Commit e07d8cc4 authored by Matthias Braun's avatar Matthias Braun
Browse files

beflags: transform modifies_flags property into a callback, use default...

beflags: transform modifies_flags property into a callback, use default rematerialisation callback in backends where necessary

[r27821]
parent 5a5b0a88
...@@ -154,7 +154,8 @@ static void amd64_before_ra(void *self) ...@@ -154,7 +154,8 @@ static void amd64_before_ra(void *self)
{ {
amd64_code_gen_t *cg = self; amd64_code_gen_t *cg = self;
be_sched_fix_flags(cg->irg, &amd64_reg_classes[CLASS_amd64_flags], 0); be_sched_fix_flags(cg->irg, &amd64_reg_classes[CLASS_amd64_flags],
NULL, NULL);
} }
......
...@@ -165,28 +165,12 @@ static void arm_finish_irg(void *self) ...@@ -165,28 +165,12 @@ static void arm_finish_irg(void *self)
arm_peephole_optimization(cg); arm_peephole_optimization(cg);
} }
static ir_node *arm_flags_remat(ir_node *node, ir_node *after)
{
ir_node *block;
ir_node *copy;
if (is_Block(after)) {
block = after;
} else {
block = get_nodes_block(after);
}
copy = exact_copy(node);
set_nodes_block(copy, block);
sched_add_after(after, copy);
return copy;
}
static void arm_before_ra(void *self) static void arm_before_ra(void *self)
{ {
arm_code_gen_t *cg = self; arm_code_gen_t *cg = self;
be_sched_fix_flags(cg->irg, &arm_reg_classes[CLASS_arm_flags], be_sched_fix_flags(cg->irg, &arm_reg_classes[CLASS_arm_flags],
&arm_flags_remat); NULL, NULL);
} }
static void transform_Reload(ir_node *node) static void transform_Reload(ir_node *node)
......
...@@ -54,9 +54,10 @@ ...@@ -54,9 +54,10 @@
#include "benode.h" #include "benode.h"
#include "belive.h" #include "belive.h"
static const arch_register_class_t *flag_class = NULL; static const arch_register_class_t *flag_class;
static const arch_register_t *flags_reg = NULL; static const arch_register_t *flags_reg;
static func_rematerialize remat = NULL; static func_rematerialize remat;
static check_modifies_flags check_modify;
static int changed; static int changed;
static ir_node *default_remat(ir_node *node, ir_node *after) static ir_node *default_remat(ir_node *node, ir_node *after)
...@@ -74,6 +75,11 @@ static ir_node *default_remat(ir_node *node, ir_node *after) ...@@ -74,6 +75,11 @@ static ir_node *default_remat(ir_node *node, ir_node *after)
return copy; return copy;
} }
static bool default_check_modifies(const ir_node *node)
{
return arch_irn_is(node, modify_flags);
}
/** /**
* tests whether we can legally move node node after node after * tests whether we can legally move node node after node after
* (only works for nodes in same block) * (only works for nodes in same block)
...@@ -184,11 +190,6 @@ static void rematerialize_or_move(ir_node *flags_needed, ir_node *node, ...@@ -184,11 +190,6 @@ static void rematerialize_or_move(ir_node *flags_needed, ir_node *node,
} }
} }
static bool is_modify_flags(ir_node *node)
{
return arch_irn_is(node, modify_flags);
}
/** /**
* walks up the schedule and makes sure there are no flag-destroying nodes * walks up the schedule and makes sure there are no flag-destroying nodes
* between a flag-consumer -> flag-producer chain. Fixes problematic situations * between a flag-consumer -> flag-producer chain. Fixes problematic situations
...@@ -223,7 +224,7 @@ static void fix_flags_walker(ir_node *block, void *env) ...@@ -223,7 +224,7 @@ static void fix_flags_walker(ir_node *block, void *env)
if (be_is_Keep(test)) if (be_is_Keep(test))
test = sched_prev(test); test = sched_prev(test);
if (flags_needed != NULL && is_modify_flags(test)) { if (flags_needed != NULL && check_modify(test)) {
/* rematerialize */ /* rematerialize */
rematerialize_or_move(flags_needed, node, flag_consumers, pn); rematerialize_or_move(flags_needed, node, flag_consumers, pn);
flags_needed = NULL; flags_needed = NULL;
...@@ -282,14 +283,18 @@ static void fix_flags_walker(ir_node *block, void *env) ...@@ -282,14 +283,18 @@ static void fix_flags_walker(ir_node *block, void *env)
} }
void be_sched_fix_flags(ir_graph *irg, const arch_register_class_t *flag_cls, void be_sched_fix_flags(ir_graph *irg, const arch_register_class_t *flag_cls,
func_rematerialize remat_func) func_rematerialize remat_func,
check_modifies_flags check_modifies_flags_func)
{ {
flag_class = flag_cls; flag_class = flag_cls;
flags_reg = & flag_class->regs[0]; flags_reg = & flag_class->regs[0];
remat = remat_func; remat = remat_func;
changed = 0; check_modify = check_modifies_flags_func;
changed = 0;
if (remat == NULL) if (remat == NULL)
remat = &default_remat; remat = &default_remat;
if (check_modify == NULL)
check_modify = &default_check_modifies;
ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK); ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
irg_block_walk_graph(irg, fix_flags_walker, NULL, NULL); irg_block_walk_graph(irg, fix_flags_walker, NULL, NULL);
......
...@@ -29,14 +29,25 @@ ...@@ -29,14 +29,25 @@
#include "bearch.h" #include "bearch.h"
#include "beirg.h" #include "beirg.h"
/**
* Callback which rematerializes (=duplicates) a machine node.
*/
typedef ir_node * (*func_rematerialize) (ir_node *node, ir_node *after); typedef ir_node * (*func_rematerialize) (ir_node *node, ir_node *after);
/**
* Callback function that checks wether a node modifies the flags
*/
typedef bool (*check_modifies_flags) (const ir_node *node);
/** /**
* Walks the schedule and ensures that flags aren't destroyed between producer * Walks the schedule and ensures that flags aren't destroyed between producer
* and consumer of flags. It does so by moving down/rematerialising of the * and consumer of flags. It does so by moving down/rematerialising of the
* nodes. This does not work across blocks. * nodes. This does not work across blocks.
* The callback functions may be NULL if you want to use default
* implementations.
*/ */
void be_sched_fix_flags(ir_graph *irg, const arch_register_class_t *flag_cls, void be_sched_fix_flags(ir_graph *irg, const arch_register_class_t *flag_cls,
func_rematerialize remat_func); func_rematerialize remat_func,
check_modifies_flags check_modifies_flags_func);
#endif #endif
...@@ -998,7 +998,7 @@ static void ia32_before_ra(void *self) ...@@ -998,7 +998,7 @@ static void ia32_before_ra(void *self)
/* fixup flags */ /* fixup flags */
be_sched_fix_flags(cg->irg, &ia32_reg_classes[CLASS_ia32_flags], be_sched_fix_flags(cg->irg, &ia32_reg_classes[CLASS_ia32_flags],
&flags_remat); &flags_remat, NULL);
be_add_missing_keeps(cg->irg); be_add_missing_keeps(cg->irg);
} }
......
...@@ -151,29 +151,12 @@ static void sparc_prepare_graph(void *self) ...@@ -151,29 +151,12 @@ static void sparc_prepare_graph(void *self)
dump_ir_graph(cg->irg, "transformed"); dump_ir_graph(cg->irg, "transformed");
} }
static ir_node *sparc_flags_remat(ir_node *node, ir_node *after)
{
ir_node *block;
ir_node *copy;
if (is_Block(after)) {
block = after;
} else {
block = get_nodes_block(after);
}
copy = exact_copy(node);
set_nodes_block(copy, block);
sched_add_after(after, copy);
return copy;
}
static void sparc_before_ra(void *self) static void sparc_before_ra(void *self)
{ {
sparc_code_gen_t *cg = self; sparc_code_gen_t *cg = self;
/* fixup flags register */ /* fixup flags register */
be_sched_fix_flags(cg->irg, &sparc_reg_classes[CLASS_sparc_flags], &sparc_flags_remat); be_sched_fix_flags(cg->irg, &sparc_reg_classes[CLASS_sparc_flags], NULL,
NULL);
} }
/** /**
......
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