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)
{
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)
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)
......
......@@ -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);
......
......@@ -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
......@@ -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);
}
......
......@@ -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);
}
/**
......
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