aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-11-14 17:59:29 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-11-17 18:03:18 +0100
commit5a7a06698fe2cd4ccb8d3f1a8585c70e6d8f7531 (patch)
treef044bf05f0702556a3db451adffe2749d0f557cb
parent2fdaca9e7175e62f08d259f5cb3ec7c9725bba68 (diff)
downloadsparse-5a7a06698fe2cd4ccb8d3f1a8585c70e6d8f7531.tar.gz
cfg: remove phi-nodes when merging BBs
When merging BBs, it's possible that the top BB feeds one or several phi-nodes in the bottom BB. Since phi-nodes only make sense for values incoming from the parent BBs, these phi-nodes can and should be removed when merging the BBs. So, when merging BBs, remove these related phi-nodes. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--flow.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/flow.c b/flow.c
index 566f4637..f052cdb1 100644
--- a/flow.c
+++ b/flow.c
@@ -760,6 +760,26 @@ static void remove_merging_phisrc(struct basic_block *top, struct instruction *i
} END_FOR_EACH_PTR(phi);
}
+static void remove_merging_phi(struct basic_block *top, struct instruction *insn)
+{
+ pseudo_t phi;
+
+ FOR_EACH_PTR(insn->phi_list, phi) {
+ struct instruction *def;
+
+ if (phi == VOID)
+ continue;
+
+ def = phi->def;
+ if (def->bb != top)
+ continue;
+
+ convert_instruction_target(insn, def->src);
+ kill_instruction(def);
+ kill_instruction(insn);
+ } END_FOR_EACH_PTR(phi);
+}
+
///
// merge two BBs
// @top: the first BB to be merged
@@ -786,6 +806,9 @@ static int merge_bb(struct basic_block *top, struct basic_block *bot)
continue;
assert(insn->bb == bot);
switch (insn->opcode) {
+ case OP_PHI:
+ remove_merging_phi(top, insn);
+ continue;
case OP_PHISOURCE:
remove_merging_phisrc(top, insn);
break;