Commit 133cd801 authored by Matthias Braun's avatar Matthias Braun
Browse files

bepeephole: reachability check in can_move_before

before we only tested, if we produce an output that is used as as input
of any schedule node in between. This missed the case where you have
unscheduled utility nodes like Sync in between.
parent 1475afff
......@@ -33,6 +33,7 @@
#include "irprintf.h"
#include "ircons.h"
#include "irgmod.h"
#include "heights.h"
#include "error.h"
#include "beirg.h"
......@@ -248,22 +249,19 @@ bool be_has_only_one_user(ir_node *node)
return n_users == 1;
}
bool be_can_move_before(const ir_node *node, const ir_node *before)
bool be_can_move_before(ir_heights_t *heights, const ir_node *node,
const ir_node *before)
{
int node_arity = get_irn_arity(node);
ir_node *schedpoint = sched_next(node);
while (schedpoint != before) {
int i;
int arity = get_irn_arity(schedpoint);
unsigned n_outs = arch_get_irn_n_outs(schedpoint);
/* the node must not use our computed values */
for (i = 0; i < arity; ++i) {
ir_node *in = get_irn_n(schedpoint, i);
if (skip_Proj(in) == node)
return false;
}
if (heights_reachable_in_block(heights, schedpoint, node))
return false;
/* the node must not overwrite registers of our inputs */
for (i = 0; i < node_arity; ++i) {
......
......@@ -81,7 +81,8 @@ bool be_has_only_one_user(ir_node *node);
* Note: It is allowed to use this function without being in a peephole
* optimization phase.
*/
bool be_can_move_before(const ir_node *node, const ir_node *before);
bool be_can_move_before(ir_heights_t *heights, const ir_node *node,
const ir_node *before);
/**
* Do peephole optimisations. It traverses the schedule of all blocks in
......
......@@ -401,7 +401,7 @@ static bool writes_reg(const ir_node *node, const arch_register_t *reg)
static bool can_move_into_delayslot(const ir_node *node, const ir_node *to)
{
if (!be_can_move_before(node, to))
if (!be_can_move_before(heights, node, to))
return false;
if (is_sparc_Call(to)) {
......
......@@ -47,6 +47,7 @@
#include "irgmod.h"
#include "ircons.h"
#include "irgwalk.h"
#include "heights.h"
#include "bepeephole.h"
#include "benode.h"
......@@ -55,6 +56,8 @@
#include "bestack.h"
#include "beirgmod.h"
static ir_heights_t *heights;
static void kill_unused_stacknodes(ir_node *node)
{
if (get_irn_n_edges(node) > 0)
......@@ -505,13 +508,13 @@ static void peephole_sparc_RestoreZero(ir_node *node)
if (!is_restorezeroopt_reg(reg))
continue;
if (be_is_Copy(schedpoint) && be_can_move_before(schedpoint, node)) {
if (be_is_Copy(schedpoint) && be_can_move_before(heights, schedpoint, node)) {
ir_node *op = get_irn_n(schedpoint, n_be_Copy_op);
replace_with_restore_imm(node, schedpoint, op, NULL, 0);
} else if (is_sparc_Or(schedpoint) &&
arch_get_irn_flags(schedpoint) & ((arch_irn_flags_t)sparc_arch_irn_flag_immediate_form) &&
arch_get_irn_register_in(schedpoint, 0) == &sparc_registers[REG_G0] &&
be_can_move_before(schedpoint, node)) {
be_can_move_before(heights, schedpoint, node)) {
/* it's a constant */
const sparc_attr_t *attr = get_sparc_attr_const(schedpoint);
ir_entity *entity = attr->immediate_value_entity;
......@@ -519,7 +522,7 @@ static void peephole_sparc_RestoreZero(ir_node *node)
ir_node *g0 = get_irn_n(schedpoint, 0);
replace_with_restore_imm(node, schedpoint, g0, entity, immediate);
} else if (is_sparc_Add(schedpoint) &&
be_can_move_before(schedpoint, node)) {
be_can_move_before(heights, schedpoint, node)) {
if (arch_get_irn_flags(schedpoint) & ((arch_irn_flags_t)sparc_arch_irn_flag_immediate_form)) {
ir_node *op = get_irn_n(schedpoint, 0);
const sparc_attr_t *attr = get_sparc_attr_const(schedpoint);
......@@ -534,7 +537,7 @@ static void peephole_sparc_RestoreZero(ir_node *node)
} else if (is_sparc_Sub(schedpoint) &&
arch_get_irn_flags(schedpoint) & ((arch_irn_flags_t)sparc_arch_irn_flag_immediate_form) &&
arch_get_irn_register_in(schedpoint, 0) == &sparc_registers[REG_G0] &&
be_can_move_before(schedpoint, node)) {
be_can_move_before(heights, schedpoint, node)) {
/* it's a constant */
const sparc_attr_t *attr = get_sparc_attr_const(schedpoint);
ir_entity *entity = attr->immediate_value_entity;
......@@ -642,6 +645,8 @@ void sparc_finish(ir_graph *irg)
be_abi_fix_stack_nodes(irg);
sparc_fix_stack_bias(irg);
heights = heights_new(irg);
/* perform peephole optimizations */
clear_irp_opcodes_generic_func();
register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP);
......@@ -662,5 +667,7 @@ void sparc_finish(ir_graph *irg)
register_peephole_optimisation(op_sparc_Stf, finish_sparc_Stf);
be_peephole_opt(irg);
heights_free(heights);
be_remove_dead_nodes_from_schedule(irg);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment