X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbepeephole.c;h=3194b4be9bd93325025a1654e5b351be67c544a5;hb=9003bb80f110a064291884dc408221d528686543;hp=d2377900044b8358da5b40122b1299fb5b120ba8;hpb=afaa73cdbc3679a791e1536a35fdd2971391cf0c;p=libfirm diff --git a/ir/be/bepeephole.c b/ir/be/bepeephole.c index d23779000..3194b4be9 100644 --- a/ir/be/bepeephole.c +++ b/ir/be/bepeephole.c @@ -261,6 +261,58 @@ static void kill_barriers(ir_graph *irg) { skip_barrier(start_blk, irg); } +/* + * Tries to optimize a beIncSp node with it's previous IncSP node. + * Must be run from a be_peephole_opt() context. + */ +void be_peephole_IncSP_IncSP(ir_node *node) +{ + int pred_offs; + int curr_offs; + int offs; + ir_node *pred = be_get_IncSP_pred(node); + ir_node *predpred; + + if (!be_is_IncSP(pred)) + return; + + if (get_irn_n_edges(pred) > 1) + return; + + pred_offs = be_get_IncSP_offset(pred); + curr_offs = be_get_IncSP_offset(node); + + if (pred_offs == BE_STACK_FRAME_SIZE_EXPAND) { + if (curr_offs != BE_STACK_FRAME_SIZE_SHRINK) { + return; + } + offs = 0; + } else if (pred_offs == BE_STACK_FRAME_SIZE_SHRINK) { + if (curr_offs != BE_STACK_FRAME_SIZE_EXPAND) { + return; + } + offs = 0; + } else if (curr_offs == BE_STACK_FRAME_SIZE_EXPAND || + curr_offs == BE_STACK_FRAME_SIZE_SHRINK) { + return; + } else { + offs = curr_offs + pred_offs; + } + + /* add pred offset to ours and remove pred IncSP */ + be_set_IncSP_offset(node, offs); + + predpred = be_get_IncSP_pred(pred); + be_peephole_before_exchange(pred, predpred); + + /* rewire dependency edges */ + edges_reroute_kind(pred, predpred, EDGE_KIND_DEP, current_ir_graph); + be_set_IncSP_pred(node, predpred); + sched_remove(pred); + be_kill_node(pred); + + be_peephole_after_exchange(predpred); +} void be_peephole_opt(be_irg_t *birg) {