/** * @return an integer telling which predecessor of Y in CFG is X. The jth operand of a * phi-function in Y corresponds to the jth predecessor of Y from the listing of the in edges * of Y */ private int whichPred(BasicBlock X, BasicBlock Y) { int j = 0; for (BasicBlock P : cfg.getPredecessors(X)) { if (P.equals(Y)) { return j; } j++; } throw new IllegalArgumentException("X is not a predecessor of Y"); }
/** Inserts PHI functions at the beginning of basic blocks. */ private void insertPhiFunctions() { // See Figure 11 // http://www.cs.utexas.edu/~pingali/CS380C/2010/papers/ssaCytron.pdf int iterCount = 0; Map<BasicBlock, Integer> hasAlready = Maps.newHashMap(); Map<BasicBlock, Integer> work = Maps.newHashMap(); for (BasicBlock X : cfg.getLiveBasicBlocks()) { hasAlready.put(X, 0); work.put(X, 0); } Queue<BasicBlock> W = Lists.newLinkedList(); for (Variable V : cfg.variables()) { iterCount = iterCount + 1; for (BasicBlock X : Iterables.filter(cfg.getLiveBasicBlocks(), CfgPredicates.containsAssignmentTo(V))) { work.put(X, iterCount); W.add(X); } while (!W.isEmpty()) { BasicBlock X = W.poll(); for (BasicBlock Y : dtree.getFrontier(X)) { if (X != cfg.getExit()) { if (hasAlready.get(Y) < iterCount) { Y.insertPhiFunction(V, cfg.getPredecessors(Y).size()); // place (V <- phi(V,..., V)) at Y hasAlready.put(Y, iterCount); if (work.get(Y) < iterCount) { work.put(Y, iterCount); W.add(Y); } } } } } } }
private void search(BasicBlock X) { for (Statement stmt : X.getStatements()) { Expression rhs = stmt.getRHS(); if (!(rhs instanceof PhiFunction)) { for (Variable V : rhs.variables()) { int i = Top(V); rhs = rhs.replaceVariable(V, new SsaVariable(V, i)); } stmt = X.replaceStatement(stmt, stmt.withRHS(rhs)); } if (stmt instanceof Assignment) { Assignment assignment = (Assignment) stmt; if (assignment.getLHS() instanceof Variable) { Variable V = (Variable) assignment.getLHS(); int i = C.get(V); X.replaceStatement(assignment, assignment.withLHS(new SsaVariable(V, i))); S.get(V).push(i); C.put(V, i + 1); } } } for (BasicBlock Y : cfg.getSuccessors(X)) { int j = whichPred(Y, X); for (Assignment A : Lists.newArrayList(Y.phiAssignments())) { PhiFunction rhs = (PhiFunction) A.getRHS(); Variable V = rhs.getArgument(j); int i = Top(V); rhs = rhs.replaceVariable(j, i); Y.replaceStatement(A, new Assignment(A.getLHS(), rhs)); // replace the j-th operand V in RHS(F) by V_i where i = Top(S(V)) } } for (BasicBlock Y : dtree.getChildren(X)) { search(Y); } for (Assignment A : X.assignments()) { if (A.getLHS() instanceof SsaVariable) { SsaVariable lhs = (SsaVariable) A.getLHS(); S.get(lhs.getInner()).pop(); } } }