aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ssa.c
diff options
Diffstat (limited to 'ssa.c')
-rw-r--r--ssa.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/ssa.c b/ssa.c
index 0d21d691..34d92279 100644
--- a/ssa.c
+++ b/ssa.c
@@ -313,6 +313,41 @@ static void ssa_rename_insns(struct entrypoint *ep)
} END_FOR_EACH_PTR(bb);
}
+static void ssa_rename_phi(struct instruction *insn)
+{
+ struct basic_block *par;
+ struct symbol *var;
+
+ if (!insn->phi_var)
+ return;
+ var = insn->phi_var->sym;
+ if (!var->torename)
+ return;
+ FOR_EACH_PTR(insn->bb->parents, par) {
+ struct instruction *term = delete_last_instruction(&par->insns);
+ pseudo_t val = lookup_var(par, var);
+ pseudo_t phi = alloc_phi(par, val, var);
+ phi->ident = var->ident;
+ add_instruction(&par->insns, term);
+ use_pseudo(insn, phi, add_pseudo(&insn->phi_list, phi));
+ } END_FOR_EACH_PTR(par);
+}
+
+static void ssa_rename_phis(struct entrypoint *ep)
+{
+ struct basic_block *bb;
+
+
+ FOR_EACH_PTR(ep->bbs, bb) {
+ struct instruction *insn;
+ FOR_EACH_PTR(bb->insns, insn) {
+ if (!insn->bb || insn->opcode != OP_PHI)
+ continue;
+ ssa_rename_phi(insn);
+ } END_FOR_EACH_PTR(insn);
+ } END_FOR_EACH_PTR(bb);
+}
+
void ssa_convert(struct entrypoint *ep)
{
struct basic_block *bb;
@@ -337,4 +372,5 @@ void ssa_convert(struct entrypoint *ep)
// rename the converted accesses
ssa_rename_insns(ep);
+ ssa_rename_phis(ep);
}