X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firopt.c;h=f6b38c8722bd77d5e0101a7eba26848a7035f50b;hb=4f92e524762e0febc361676111b3b5b79addd03a;hp=a201855ac27a5befb5b067a4754009b0839d8e4c;hpb=cd07ee0e8a9a4294f3de5f02b899c88661af8e34;p=libfirm diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index a201855ac..f6b38c872 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -5686,6 +5686,66 @@ static ir_node *transform_node_Sync(ir_node *n) return n; } /* transform_node_Sync */ +static ir_node *transform_node_Load(ir_node *n) +{ + /* if our memory predecessor is a load from the same address, then reuse the + * previous result */ + ir_node *mem = get_Load_mem(n); + ir_node *mem_pred; + + if (!is_Proj(mem)) + return n; + /* don't touch volatile loads */ + if (get_Load_volatility(n) == volatility_is_volatile) + return n; + mem_pred = get_Proj_pred(mem); + if (is_Load(mem_pred)) { + ir_node *pred_load = mem_pred; + + /* conservatively compare the 2 loads. TODO: This could be less strict + * with fixup code in some situations (like smaller/bigger modes) */ + if (get_Load_ptr(pred_load) != get_Load_ptr(n)) + return n; + if (get_Load_mode(pred_load) != get_Load_mode(n)) + return n; + /* all combinations of aligned/unaligned pred/n should be fine so we do + * not compare the unaligned attribute */ + { + ir_node *block = get_nodes_block(n); + ir_node *jmp = new_r_Jmp(block); + ir_graph *irg = get_irn_irg(n); + ir_node *bad = new_r_Bad(irg); + ir_mode *mode = get_Load_mode(n); + ir_node *res = new_r_Proj(pred_load, mode, pn_Load_res); + ir_node *in[pn_Load_max] = { mem, jmp, bad, res }; + ir_node *tuple = new_r_Tuple(block, ARRAY_SIZE(in), in); + return tuple; + } + } else if (is_Store(mem_pred)) { + ir_node *pred_store = mem_pred; + ir_node *value = get_Store_value(pred_store); + + if (get_Store_ptr(pred_store) != get_Load_ptr(n)) + return n; + if (get_irn_mode(value) != get_Load_mode(n)) + return n; + /* all combinations of aligned/unaligned pred/n should be fine so we do + * not compare the unaligned attribute */ + { + ir_node *block = get_nodes_block(n); + ir_node *jmp = new_r_Jmp(block); + ir_graph *irg = get_irn_irg(n); + ir_node *bad = new_r_Bad(irg); + ir_node *res = value; + ir_node *in[pn_Load_max] = { mem, jmp, bad, res }; + ir_node *tuple = new_r_Tuple(block, ARRAY_SIZE(in), in); + return tuple; + } + } + + return n; +} + /** * optimize a trampoline Call into a direct Call */ @@ -5829,10 +5889,10 @@ static ir_op_ops *firm_set_default_transform_node(ir_opcode code, ir_op_ops *ops CASE(Sync); CASE_PROJ(Bound); CASE_PROJ(CopyB); - CASE_PROJ(Load); CASE_PROJ(Store); CASE_PROJ_EX(Cond); CASE_PROJ_EX(Div); + CASE_PROJ_EX(Load); CASE_PROJ_EX(Mod); default: /* leave NULL */; @@ -6626,7 +6686,7 @@ static unsigned hash_SymConst(const ir_node *node) * @return * The operations. */ -static ir_op_ops *firm_set_default_hash(ir_opcode code, ir_op_ops *ops) +static ir_op_ops *firm_set_default_hash(unsigned code, ir_op_ops *ops) { #define CASE(a) \ case iro_##a: \ @@ -6652,7 +6712,7 @@ static ir_op_ops *firm_set_default_hash(ir_opcode code, ir_op_ops *ops) /* * Sets the default operation for an ir_ops. */ -ir_op_ops *firm_set_default_operations(ir_opcode code, ir_op_ops *ops) +ir_op_ops *firm_set_default_operations(unsigned code, ir_op_ops *ops) { ops = firm_set_default_hash(code, ops); ops = firm_set_default_computed_value(code, ops);