diff options
| author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-11-24 11:41:31 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 21:04:43 -0700 |
| commit | e4fb90fb0c66b034ba45671a32616c208ccd478a (patch) | |
| tree | 8db644a14d6a6061b2d1bbf2f04cb53ef48c11ff /flow.c | |
| parent | ffd3283cdce661b220c0393020a8197ac1a9d310 (diff) | |
| download | sparse-dev-e4fb90fb0c66b034ba45671a32616c208ccd478a.tar.gz | |
Teach basic block packing about deleted phi-nodes and no-ops.
If a basic block is a source of phi-nodes, but they have all
been cleared, we can just ignore them. Similarly, if a basic
block is only a series of no-ops followed by a branch, we can
still do the branch rewrite.
Diffstat (limited to 'flow.c')
| -rw-r--r-- | flow.c | 31 |
1 files changed, 24 insertions, 7 deletions
@@ -621,6 +621,8 @@ static int rewrite_parent_branch(struct basic_block *bb, struct basic_block *old case OP_BR: rewrite_branch(bb, &insn->bb_true, old, new); rewrite_branch(bb, &insn->bb_false, old, new); + if (insn->bb_true == insn->bb_false) + insn->bb_false = NULL; return 1; case OP_SWITCH: { struct multijmp *jmp; @@ -726,20 +728,35 @@ void pack_basic_blocks(struct entrypoint *ep) /* * If this block has a phi-node associated with it, */ - if (bb->phinodes) - continue; + if (bb->phinodes) { + struct phi *phi; + FOR_EACH_PTR(bb->phinodes, phi) { + if (phi->source) + goto no_merge; + } END_FOR_EACH_PTR(phi); + } /* * Just a branch? */ - first = first_instruction(bb->insns); - if (first && first->opcode == OP_BR) { - if (rewrite_branch_bb(bb, first)) { - kill_bb(bb); + FOR_EACH_PTR(bb->insns, first) { + if (!first->bb) continue; + switch (first->opcode) { + case OP_NOP: case OP_LNOP: case OP_SNOP: + continue; + case OP_BR: + if (rewrite_branch_bb(bb, first)) { + kill_bb(bb); + goto no_merge; + } + /* fallthrough */ + default: + goto out; } - } + } END_FOR_EACH_PTR(first); +out: if (ep->entry == bb) continue; |
