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

use callbacks for proj transform functions

parent 1183e0e3
......@@ -303,6 +303,7 @@ static void TEMPLATE_register_transformers(void)
be_set_transform_function(op_Start, gen_Start);
be_set_transform_function(op_Store, gen_Store);
be_set_transform_function(op_Sub, gen_Sub);
be_set_transform_proj_function(op_Start, gen_Proj_Start);
}
/**
......
......@@ -379,37 +379,29 @@ static ir_node *gen_Proj_Load(ir_node *node)
return be_duplicate_node(node);
}
/**
* Transform a Proj node.
*/
static ir_node *gen_Proj(ir_node *node)
static ir_node *gen_Proj_Store(ir_node *node)
{
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *pred = get_Proj_pred(node);
long proj = get_Proj_proj(node);
(void) dbgi;
if (is_Store(pred)) {
if (proj == pn_Store_M) {
return be_transform_node(pred);
} else {
panic("Unsupported Proj from Store");
}
} else if (is_Load(pred)) {
return gen_Proj_Load(node);
} else if (is_Start(pred)) {
} else if (be_is_Call(pred)) {
ir_mode *mode = get_irn_mode(node);
if (mode_needs_gp_reg(mode)) {
ir_node *new_pred = be_transform_node(pred);
long pn = get_Proj_proj(node);
ir_node *new_proj = new_r_Proj(new_pred, mode_Lu, pn);
return new_proj;
}
ir_node *pred = get_Proj_pred(node);
long pn = get_Proj_proj(node);
if (pn == pn_Store_M) {
return be_transform_node(pred);
} else {
panic("Unsupported Proj from Store");
}
}
return be_duplicate_node(node);
static ir_node *gen_Proj_be_Call(ir_node *node)
{
ir_mode *mode = get_irn_mode(node);
if (mode_needs_gp_reg(mode)) {
ir_node *pred = get_Proj_pred(node);
ir_node *new_pred = be_transform_node(pred);
long pn = get_Proj_proj(node);
ir_node *new_proj = new_r_Proj(new_pred, mode_Lu, pn);
return new_proj;
} else {
return be_duplicate_node(node);
}
}
/**
......@@ -472,8 +464,12 @@ static void amd64_register_transformers(void)
be_set_transform_function(op_Phi, gen_Phi);
be_set_transform_function(op_Load, gen_Load);
be_set_transform_function(op_Store, gen_Store);
be_set_transform_function(op_Proj, gen_Proj);
be_set_transform_function(op_Minus, gen_Minus);
be_set_transform_proj_function(op_be_Call, gen_Proj_be_Call);
be_set_transform_proj_function(op_be_Start, be_duplicate_node);
be_set_transform_proj_function(op_Load, gen_Proj_Load);
be_set_transform_proj_function(op_Store, gen_Proj_Store);
}
void amd64_transform_graph(ir_graph *irg)
......
......@@ -1473,49 +1473,27 @@ static ir_node *gen_Proj_Call(ir_node *node)
panic("Unexpected Call proj %ld\n", pn);
}
/**
* Transform a Proj node.
*/
static ir_node *gen_Proj(ir_node *node)
static ir_node *gen_Proj_Store(ir_node *node)
{
ir_node *pred = get_Proj_pred(node);
long proj = get_Proj_proj(node);
switch (get_irn_opcode(pred)) {
case iro_Store:
if (proj == pn_Store_M) {
return be_transform_node(pred);
} else {
panic("Unsupported Proj from Store");
}
case iro_Load:
return gen_Proj_Load(node);
case iro_Call:
return gen_Proj_Call(node);
case iro_CopyB:
return gen_Proj_CopyB(node);
case iro_Div:
return gen_Proj_Div(node);
case iro_Start:
return gen_Proj_Start(node);
case iro_Cond:
case iro_Switch:
/* nothing to do */
return be_duplicate_node(node);
case iro_Proj: {
ir_node *pred_pred = get_Proj_pred(pred);
if (is_Call(pred_pred)) {
return gen_Proj_Proj_Call(node);
} else if (is_Start(pred_pred)) {
return gen_Proj_Proj_Start(node);
}
/* FALLTHROUGH */
ir_node *pred = get_Proj_pred(node);
long pn = get_Proj_proj(node);
if (pn == pn_Store_M) {
return be_transform_node(pred);
} else {
panic("Unsupported Proj from Store");
}
case iro_Builtin:
return gen_Proj_Builtin(node);
default:
panic("code selection didn't expect Proj after %+F\n", pred);
}
static ir_node *gen_Proj_Proj(ir_node *node)
{
ir_node *pred = get_Proj_pred(node);
ir_node *pred_pred = get_Proj_pred(pred);
if (is_Call(pred_pred)) {
return gen_Proj_Proj_Call(node);
} else if (is_Start(pred_pred)) {
return gen_Proj_Proj_Start(node);
}
panic("code selection didn't expect Proj(Proj) after %+F\n", pred_pred);
}
static ir_node *gen_Unknown(ir_node *node)
......@@ -1926,7 +1904,6 @@ static void arm_register_transformers(void)
be_set_transform_function(op_Not, gen_Not);
be_set_transform_function(op_Or, gen_Or);
be_set_transform_function(op_Phi, gen_Phi);
be_set_transform_function(op_Proj, gen_Proj);
be_set_transform_function(op_Return, gen_Return);
be_set_transform_function(op_Rotl, gen_Rotl);
be_set_transform_function(op_Sel, gen_Sel);
......@@ -1940,6 +1917,17 @@ static void arm_register_transformers(void)
be_set_transform_function(op_SymConst, gen_SymConst);
be_set_transform_function(op_Unknown, gen_Unknown);
be_set_transform_function(op_Builtin, gen_Builtin);
be_set_transform_proj_function(op_Builtin, gen_Proj_Builtin);
be_set_transform_proj_function(op_Call, gen_Proj_Call);
be_set_transform_proj_function(op_Cond, be_duplicate_node);
be_set_transform_proj_function(op_CopyB, gen_Proj_CopyB);
be_set_transform_proj_function(op_Div, gen_Proj_Div);
be_set_transform_proj_function(op_Load, gen_Proj_Load);
be_set_transform_proj_function(op_Proj, gen_Proj_Proj);
be_set_transform_proj_function(op_Start, gen_Proj_Start);
be_set_transform_proj_function(op_Store, gen_Proj_Store);
be_set_transform_proj_function(op_Switch, be_duplicate_node);
}
/**
......
......@@ -108,6 +108,11 @@ void be_set_transform_function(ir_op *op, be_transform_func func)
op->ops.generic = (op_func) func;
}
void be_set_transform_proj_function(ir_op *op, be_transform_func func)
{
op->ops.generic1 = (op_func) func;
}
/**
* Transform helper for blocks.
*/
......@@ -155,6 +160,17 @@ static ir_node *transform_end(ir_node *node)
return new_end;
}
static ir_node *transform_proj(ir_node *node)
{
ir_node *pred = get_Proj_pred(node);
ir_op *pred_op = get_irn_op(pred);
be_transform_func *proj_transform
= (be_transform_func*)pred_op->ops.generic1;
/* we should have a Proj transformer registered */
assert(proj_transform != NULL);
return proj_transform(node);
}
ir_node *be_duplicate_node(ir_node *node)
{
ir_node *block = be_transform_node(get_nodes_block(node));
......@@ -392,9 +408,9 @@ void be_transform_graph(ir_graph *irg, arch_pretrans_nodes *func)
bool be_upper_bits_clean(const ir_node *node, ir_mode *mode)
{
ir_op *op = get_irn_op(node);
if (op->ops.generic1 == NULL)
if (op->ops.generic2 == NULL)
return false;
upper_bits_clean_func func = (upper_bits_clean_func)op->ops.generic1;
upper_bits_clean_func func = (upper_bits_clean_func)op->ops.generic2;
return func(node, mode);
}
......@@ -497,7 +513,7 @@ static bool proj_upper_bits_clean(const ir_node *node, ir_mode *mode)
void be_set_upper_bits_clean_function(ir_op *op, upper_bits_clean_func func)
{
op->ops.generic1 = (op_func)func;
op->ops.generic2 = (op_func)func;
}
void be_start_transform_setup(void)
......@@ -514,6 +530,7 @@ void be_start_transform_setup(void)
be_set_transform_function(op_End, transform_end);
be_set_transform_function(op_NoMem, be_duplicate_node);
be_set_transform_function(op_Pin, be_duplicate_node);
be_set_transform_function(op_Proj, transform_proj);
be_set_transform_function(op_Start, be_duplicate_node);
be_set_transform_function(op_Sync, be_duplicate_node);
......
......@@ -56,6 +56,9 @@ void be_start_transform_setup(void);
/** register a transform function for a specific node type */
void be_set_transform_function(ir_op *op, be_transform_func func);
/** register a transform function for a Proj attached to a specific node */
void be_set_transform_proj_function(ir_op *pred_op, be_transform_func func);
/**
* Associate an old node with a transformed node. Uses link field.
*/
......
......@@ -5251,62 +5251,34 @@ static ir_node *gen_Proj_ASM(ir_node *node)
return new_r_Proj(new_pred, mode, pos);
}
/**
* Transform and potentially renumber Proj nodes.
*/
static ir_node *gen_Proj(ir_node *node)
static ir_node *gen_Proj_Start(ir_node *node)
{
ir_node *pred = get_Proj_pred(node);
switch (get_irn_opcode(pred)) {
case iro_Load:
return gen_Proj_Load(node);
case iro_Store:
return gen_Proj_Store(node);
case iro_ASM:
return gen_Proj_ASM(node);
case iro_Builtin:
return gen_Proj_Builtin(node);
case iro_Div:
return gen_Proj_Div(node);
case iro_Mod:
return gen_Proj_Mod(node);
case iro_CopyB:
return gen_Proj_CopyB(node);
case beo_SubSP:
return gen_Proj_be_SubSP(node);
case beo_AddSP:
return gen_Proj_be_AddSP(node);
case beo_Call:
return gen_Proj_be_Call(node);
case iro_Start: {
long proj = get_Proj_proj(node);
switch (proj) {
case pn_Start_X_initial_exec: {
ir_node *block = get_nodes_block(pred);
ir_node *new_block = be_transform_node(block);
dbg_info *dbgi = get_irn_dbg_info(node);
/* we exchange the ProjX with a jump */
ir_node *jump = new_rd_Jmp(dbgi, new_block);
return jump;
}
}
break;
long proj = get_Proj_proj(node);
switch (proj) {
case pn_Start_X_initial_exec: {
ir_node *block = get_nodes_block(pred);
ir_node *new_block = be_transform_node(block);
dbg_info *dbgi = get_irn_dbg_info(node);
/* we exchange the ProjX with a jump */
ir_node *jump = new_rd_Jmp(dbgi, new_block);
return jump;
}
}
return be_duplicate_node(node);
}
default:
if (is_ia32_l_FloattoLL(pred)) {
return gen_Proj_l_FloattoLL(node);
} else {
ir_mode *mode = get_irn_mode(node);
if (ia32_mode_needs_gp_reg(mode)) {
ir_node *new_pred = be_transform_node(pred);
ir_node *new_proj = new_r_Proj(new_pred, mode_Iu,
get_Proj_proj(node));
new_proj->node_nr = node->node_nr;
return new_proj;
}
}
static ir_node *gen_Proj_default(ir_node *node)
{
ir_node *pred = get_Proj_pred(node);
ir_mode *mode = get_irn_mode(node);
if (ia32_mode_needs_gp_reg(mode)) {
ir_node *new_pred = be_transform_node(pred);
ir_node *new_proj = new_r_Proj(new_pred, mode_Iu,
get_Proj_proj(node));
new_proj->node_nr = node->node_nr;
return new_proj;
}
return be_duplicate_node(node);
}
......@@ -5319,6 +5291,11 @@ static void register_transformers(void)
/* first clear the generic function pointer for all ops */
be_start_transform_setup();
for (unsigned opc = iro_first; opc <= iro_last; ++opc) {
ir_op *op = ir_get_opcode(opc);
be_set_transform_proj_function(op, gen_Proj_default);
}
be_set_transform_function(op_Add, gen_Add);
be_set_transform_function(op_And, gen_And);
be_set_transform_function(op_ASM, ia32_gen_ASM);
......@@ -5363,7 +5340,6 @@ static void register_transformers(void)
be_set_transform_function(op_Not, gen_Not);
be_set_transform_function(op_Or, gen_Or);
be_set_transform_function(op_Phi, gen_Phi);
be_set_transform_function(op_Proj, gen_Proj);
be_set_transform_function(op_Rotl, gen_Rotl);
be_set_transform_function(op_Shl, gen_Shl);
be_set_transform_function(op_Shr, gen_Shr);
......@@ -5373,6 +5349,27 @@ static void register_transformers(void)
be_set_transform_function(op_Switch, gen_Switch);
be_set_transform_function(op_SymConst, gen_SymConst);
be_set_transform_function(op_Unknown, ia32_gen_Unknown);
be_set_transform_proj_function(op_ASM, gen_Proj_ASM);
be_set_transform_proj_function(op_be_AddSP, gen_Proj_be_AddSP);
be_set_transform_proj_function(op_be_Call, gen_Proj_be_Call);
be_set_transform_proj_function(op_be_Start, be_duplicate_node);
be_set_transform_proj_function(op_be_SubSP, gen_Proj_be_SubSP);
be_set_transform_proj_function(op_Builtin, gen_Proj_Builtin);
be_set_transform_proj_function(op_CopyB, gen_Proj_CopyB);
be_set_transform_proj_function(op_Div, gen_Proj_Div);
be_set_transform_proj_function(op_ia32_l_Adc, gen_Proj_default);
be_set_transform_proj_function(op_ia32_l_Add, gen_Proj_default);
be_set_transform_proj_function(op_ia32_l_FloattoLL, gen_Proj_l_FloattoLL);
be_set_transform_proj_function(op_ia32_l_IMul, gen_Proj_default);
be_set_transform_proj_function(op_ia32_l_LLtoFloat, gen_Proj_default);
be_set_transform_proj_function(op_ia32_l_Mul, gen_Proj_default);
be_set_transform_proj_function(op_ia32_l_Sbb, gen_Proj_default);
be_set_transform_proj_function(op_ia32_l_Sub, gen_Proj_default);
be_set_transform_proj_function(op_ia32_Minus64Bit, gen_Proj_default);
be_set_transform_proj_function(op_Load, gen_Proj_Load);
be_set_transform_proj_function(op_Mod, gen_Proj_Mod);
be_set_transform_proj_function(op_Start, gen_Proj_Start);
be_set_transform_proj_function(op_Store, gen_Proj_Store);
be_set_upper_bits_clean_function(op_Mux, ia32_mux_upper_bits_clean);
}
......
......@@ -2731,50 +2731,16 @@ static ir_node *gen_Proj_Proj_Call(ir_node *node)
return new_r_Proj(new_call, mode, new_pn);
}
/**
* Transform a Proj node.
*/
static ir_node *gen_Proj(ir_node *node)
{
ir_node *pred = get_Proj_pred(node);
switch (get_irn_opcode(pred)) {
case iro_ASM:
return gen_Proj_ASM(node);
case iro_Alloc:
return gen_Proj_Alloc(node);
case iro_Builtin:
return gen_Proj_Builtin(node);
case iro_Store:
return gen_Proj_Store(node);
case iro_Load:
return gen_Proj_Load(node);
case iro_Call:
return gen_Proj_Call(node);
case iro_Switch:
case iro_Cond:
return be_duplicate_node(node);
case iro_Div:
return gen_Proj_Div(node);
case iro_Start:
return gen_Proj_Start(node);
case iro_Proj: {
ir_node *pred_pred = get_Proj_pred(pred);
if (is_Call(pred_pred)) {
return gen_Proj_Proj_Call(node);
} else if (is_Start(pred_pred)) {
return gen_Proj_Proj_Start(node);
}
/* FALLTHROUGH */
}
default:
if (is_sparc_AddCC_t(pred)) {
return gen_Proj_AddCC_t(node);
} else if (is_sparc_SubCC_t(pred)) {
return gen_Proj_SubCC_t(node);
}
panic("code selection didn't expect Proj after %+F\n", pred);
static ir_node *gen_Proj_Proj(ir_node *node)
{
ir_node *pred = get_Proj_pred(node);
ir_node *pred_pred = get_Proj_pred(pred);
if (is_Call(pred_pred)) {
return gen_Proj_Proj_Call(node);
} else if (is_Start(pred_pred)) {
return gen_Proj_Proj_Start(node);
}
panic("code selection didn't expect Proj(Proj) after %+F\n", pred_pred);
}
/**
......@@ -2817,7 +2783,6 @@ static void sparc_register_transformers(void)
be_set_transform_function(op_Not, gen_Not);
be_set_transform_function(op_Or, gen_Or);
be_set_transform_function(op_Phi, gen_Phi);
be_set_transform_function(op_Proj, gen_Proj);
be_set_transform_function(op_Return, gen_Return);
be_set_transform_function(op_Sel, gen_Sel);
be_set_transform_function(op_Shl, gen_Shl);
......@@ -2835,6 +2800,20 @@ static void sparc_register_transformers(void)
be_set_transform_function(op_sparc_Save, be_duplicate_node);
be_set_transform_function(op_sparc_SubX_t, gen_SubX_t);
be_set_transform_function(op_sparc_SubCC_t,gen_SubCC_t);
be_set_transform_proj_function(op_Alloc, gen_Proj_Alloc);
be_set_transform_proj_function(op_ASM, gen_Proj_ASM);
be_set_transform_proj_function(op_Builtin, gen_Proj_Builtin);
be_set_transform_proj_function(op_Call, gen_Proj_Call);
be_set_transform_proj_function(op_Cond, be_duplicate_node);
be_set_transform_proj_function(op_Div, gen_Proj_Div);
be_set_transform_proj_function(op_Load, gen_Proj_Load);
be_set_transform_proj_function(op_Proj, gen_Proj_Proj);
be_set_transform_proj_function(op_sparc_AddCC_t, gen_Proj_AddCC_t);
be_set_transform_proj_function(op_sparc_SubCC_t, gen_Proj_SubCC_t);
be_set_transform_proj_function(op_Start, gen_Proj_Start);
be_set_transform_proj_function(op_Store, gen_Proj_Store);
be_set_transform_proj_function(op_Switch, be_duplicate_node);
}
/**
......
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