/** Perform the actual copy propagation. */ public void perform() { Stack<Chord> wl = WorkArea.<Chord>getStack("perform CP"); Chord start = scribble.getBegin(); boolean doSubscripts = scribble.scalarReplacementPerformed(); // If subscript addresses are propagated before scalar replacement // is performed, scalar replacement generates incorrect code. wl.push(start); Chord.nextVisit(); start.setVisited(); while (!wl.empty()) { Chord s = wl.pop(); s.pushOutCfgEdges(wl); if (s.isAssignChord()) { visitExprChord((ExprChord) s, doSubscripts); } } WorkArea.<Chord>returnStack(wl); if (rChanged) { scribble.recomputeRefs(); } }
/** * Return true if this is a legal loop. A legal loop contains no function calls and has no scalar * variable cycles. A cycle exists when the variable is referenced before it is defed. We go to * some trouble to allow loops containing cycles such as * * <pre> * s = s + a(i,j) * </pre> * * to be permuted. */ private boolean legalLoop(LoopHeaderChord loop) { Stack<Chord> wl = WorkArea.<Chord>getStack("legalLoop"); References refs = scribble.getRefs(); Chord.nextVisit(); wl.push(loop); loop.setVisited(); int n = loop.numLoopExits(); for (int i = 0; i < n; i++) loop.getLoopExit(i).setVisited(); boolean legal = true; outer: while (!wl.empty()) { Chord c = wl.pop(); if (c.getCall(true) != null) { legal = false; break; } if ((c instanceof DecisionChord) && (c != loop.getLoopTest())) { legal = false; break; } if (c.isAssignChord() && !c.isPhiExpr()) { ExprChord ec = (ExprChord) c; Expr lhs = ec.getLValue(); Expr rhs = ec.getRValue(); // The variable is both defed and used in the loop and // we don't know how it is used. For example, it could be // s = s + 1 // c(i,j) = s // or // c(i,j) = s // s = s + 1 // We want to allow // s = s + c(i,j) // because we know that s is not used to specify the // value of an array element. We want to allow // s = ... // = s // since there is no cycle. if (lhs instanceof LoadDeclAddressExpr) { LoadDeclAddressExpr ldae = (LoadDeclAddressExpr) lhs; VariableDecl vd = ldae.getDecl().returnVariableDecl(); if ((vd != null) && !loop.isLoopIndex(vd)) { boolean cycle = false; Iterator<Chord> it1 = refs.getUseChords(vd); while (it1.hasNext()) { Chord s = it1.next(); cycle |= (s == c); } Iterator<Chord> it2 = refs.getUseChords(vd); while (it2.hasNext()) { Chord s = it2.next(); if (c == s) continue; if (s.getLoopHeader() != loop) continue; if (cycle) { // There was a cycle and another use. // s = s + 1 // = s legal = false; break outer; } // Check for a use before the def. while (true) { s = s.getNextChord(); if (s == null) break; if (s == c) { legal = false; break outer; } } } } } } c.pushOutCfgEdges(wl); } WorkArea.<Chord>returnStack(wl); return legal; }