From e07d8cc4c40976bebaf73f77f3bfba7461dd491e Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Tue, 27 Jul 2010 17:57:55 +0000 Subject: [PATCH] beflags: transform modifies_flags property into a callback, use default rematerialisation callback in backends where necessary [r27821] --- ir/be/amd64/bearch_amd64.c | 3 ++- ir/be/arm/bearch_arm.c | 18 +----------------- ir/be/beflags.c | 33 +++++++++++++++++++-------------- ir/be/beflags.h | 13 ++++++++++++- ir/be/ia32/bearch_ia32.c | 2 +- ir/be/sparc/bearch_sparc.c | 21 ++------------------- 6 files changed, 37 insertions(+), 53 deletions(-) diff --git a/ir/be/amd64/bearch_amd64.c b/ir/be/amd64/bearch_amd64.c index 73dd0cdde..f7a979cb9 100644 --- a/ir/be/amd64/bearch_amd64.c +++ b/ir/be/amd64/bearch_amd64.c @@ -154,7 +154,8 @@ static void amd64_before_ra(void *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); } diff --git a/ir/be/arm/bearch_arm.c b/ir/be/arm/bearch_arm.c index c844dc102..4c7b239f2 100644 --- a/ir/be/arm/bearch_arm.c +++ b/ir/be/arm/bearch_arm.c @@ -165,28 +165,12 @@ static void arm_finish_irg(void *self) 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) { arm_code_gen_t *cg = self; be_sched_fix_flags(cg->irg, &arm_reg_classes[CLASS_arm_flags], - &arm_flags_remat); + NULL, NULL); } static void transform_Reload(ir_node *node) diff --git a/ir/be/beflags.c b/ir/be/beflags.c index 1e6e330a9..63e71f9b8 100644 --- a/ir/be/beflags.c +++ b/ir/be/beflags.c @@ -54,9 +54,10 @@ #include "benode.h" #include "belive.h" -static const arch_register_class_t *flag_class = NULL; -static const arch_register_t *flags_reg = NULL; -static func_rematerialize remat = NULL; +static const arch_register_class_t *flag_class; +static const arch_register_t *flags_reg; +static func_rematerialize remat; +static check_modifies_flags check_modify; static int changed; 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; } +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 * (only works for nodes in same block) @@ -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 * between a flag-consumer -> flag-producer chain. Fixes problematic situations @@ -223,7 +224,7 @@ static void fix_flags_walker(ir_node *block, void *env) if (be_is_Keep(test)) test = sched_prev(test); - if (flags_needed != NULL && is_modify_flags(test)) { + if (flags_needed != NULL && check_modify(test)) { /* rematerialize */ rematerialize_or_move(flags_needed, node, flag_consumers, pn); flags_needed = NULL; @@ -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, - func_rematerialize remat_func) + func_rematerialize remat_func, + check_modifies_flags check_modifies_flags_func) { - flag_class = flag_cls; - flags_reg = & flag_class->regs[0]; - remat = remat_func; - changed = 0; + flag_class = flag_cls; + flags_reg = & flag_class->regs[0]; + remat = remat_func; + check_modify = check_modifies_flags_func; + changed = 0; if (remat == NULL) remat = &default_remat; + if (check_modify == NULL) + check_modify = &default_check_modifies; ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK); irg_block_walk_graph(irg, fix_flags_walker, NULL, NULL); diff --git a/ir/be/beflags.h b/ir/be/beflags.h index 04a12ce2d..c0ce0fc87 100644 --- a/ir/be/beflags.h +++ b/ir/be/beflags.h @@ -29,14 +29,25 @@ #include "bearch.h" #include "beirg.h" +/** + * Callback which rematerializes (=duplicates) a machine node. + */ 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 * and consumer of flags. It does so by moving down/rematerialising of the * 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, - func_rematerialize remat_func); + func_rematerialize remat_func, + check_modifies_flags check_modifies_flags_func); #endif diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 4b00da247..a54773b18 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -998,7 +998,7 @@ static void ia32_before_ra(void *self) /* fixup flags */ be_sched_fix_flags(cg->irg, &ia32_reg_classes[CLASS_ia32_flags], - &flags_remat); + &flags_remat, NULL); be_add_missing_keeps(cg->irg); } diff --git a/ir/be/sparc/bearch_sparc.c b/ir/be/sparc/bearch_sparc.c index e96fbf963..b6f568017 100644 --- a/ir/be/sparc/bearch_sparc.c +++ b/ir/be/sparc/bearch_sparc.c @@ -151,29 +151,12 @@ static void sparc_prepare_graph(void *self) 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) { sparc_code_gen_t *cg = self; /* 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); } /** -- 2.20.1