/** 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(); } }
/** The main routine for block splitting. */ public final void split(Hyperblock hbStart) { Stack<Node> wl = WorkArea.<Node>getStack("split"); DataflowAnalysis df = new DataflowAnalysis(hbStart, regs); int trips = 0; // Add all the hyperblocks to the working set. hbStart.nextVisit(); hbStart.setVisited(); wl.push(hbStart); while (!wl.isEmpty()) { Hyperblock hb = (Hyperblock) wl.pop(); hb.pushOutEdges(wl); workingSet.add(hb); } // Split the hyperblocks. while (!workingSet.isEmpty()) { df.computeLiveness3(); wl.addAll(workingSet); while (!wl.isEmpty()) { Hyperblock hb = (Hyperblock) wl.pop(); hb.enterSSA(); hb.analyzeLeaveSSA(); if (!hb.isLegalBlock(true)) { splitHyperblock(hb); } else { workingSet.remove(hb); } } if ((++trips % WARN_SPLIT_ATTEMPTS) == 0) { System.err.println( "** Warning: the block splitter has run " + trips + " times for " + gen.getCurrentRoutine().getName() + "()."); } } WorkArea.<Node>returnStack(wl); }
private int[][] getDDVec(Table<Declaration, SubscriptExpr> arrayRefs, int loopDepth) { if (arrayRefs == null) return new int[0][0]; int numEdges = 0; Stack<DDEdge> wl = WorkArea.<DDEdge>getStack("g<SubscriptExpr>etDDVec"); Enumeration<DDEdge> k = graph.getEdges(); while (k.hasMoreElements()) { // Check out every array variable in the loop nest. DDEdge edge = k.nextElement(); if (edge.isSpatial()) continue; if (edge.isLoopIndependentDependency()) continue; if (edge.representsAllInput()) continue; wl.push(edge); numEdges++; } int[][] DDVector = new int[numEdges][loopDepth]; int i = 0; while (!wl.empty()) { DDEdge edge = wl.pop(); if (trace) System.out.println(" edge " + edge); // Find dependence distance. for (int level = 1; level <= loopDepth; level++) DDVector[i][level - 1] = edge.getDistance(level); if (trace) { System.out.print(i); System.out.print(" "); System.out.println(edge); } i++; } WorkArea.<DDEdge>returnStack(wl); return DDVector; }
/** Reverse if-convert the given predicate block from the hyperblock. */ private void reverseIfConvert(Hyperblock hb, PredicateBlock start) { Stack<Node> wl = WorkArea.<Node>getStack("reverseIfConvert"); Stack<PredicateBlock> reverse = WorkArea.<PredicateBlock>getStack("reverseIfConvert"); Vector<PredicateBlock> blocks = new Vector<PredicateBlock>(); Vector<Hyperblock> hbs = new Vector<Hyperblock>(); // Find the blocks which need to be reverse if-converted. start.nextVisit(); start.setVisited(); wl.add(start); while (!wl.isEmpty()) { PredicateBlock block = (PredicateBlock) wl.pop(); block.pushOutEdges(wl); for (int i = 0; i < block.numInEdges(); i++) { PredicateBlock pred = (PredicateBlock) block.getInEdge(i); if (!pred.visited()) { blocks.add(block); break; } else if (blocks.contains(pred) && block.numInEdges() > 1) { blocks.add(block); break; } } } // Order the blocks to reverse if-convert based on their depth from the root. PredicateBlock head = hb.getFirstBlock(); Vector<PredicateBlock> wl2 = new Vector<PredicateBlock>(); head.nextVisit(); head.setVisited(); wl2.add(head); while (!wl2.isEmpty()) { int l = wl2.size(); for (int i = 0; i < l; i++) { PredicateBlock block = wl2.get(i); if (blocks.contains(block)) { blocks.remove(block); reverse.push(block); } } wl2 = hb.getNextPFGLevel(wl2); } // Remove the special "dummy" last block from the PFG. PredicateBlock last = hb.getLastBlock(); assert (last.numOutEdges() == 0 && !last.isPredicated()); if (last.getFirstInstruction() == null) { for (int i = last.numInEdges() - 1; i > -1; i--) { PredicateBlock pred = (PredicateBlock) last.getInEdge(i); pred.deleteOutEdge(last); last.deleteInEdge(pred); } reverse.remove(last); } // Reverse if-convert. while (!reverse.isEmpty()) { PredicateBlock block = reverse.pop(); Hyperblock hbn = reverseIfConvertBlock(block); hbs.add(hbn); workingSet.add(hbn); } // Update the PFG. hb.updateLastBlock(); hb.invalidateDomination(); // The dominators are now invalid. // Insert the new hyperblocks in the HFG. HashMap<Instruction, Hyperblock> entries = computeEntries(hb, hbs); hbs.add(hb); Hyperblock.computeHyperblockFlowGraph(hbs, entries); // Update the return block. Since 'hbs' is an ordered list, the // first element in the list is the hyperblock with the return // because this was the original tail of the PFG which was reverse // if-converted. if (hb == gen.getReturnBlock()) { gen.setReturnBlock(hbs.firstElement()); } WorkArea.<Node>returnStack(wl); WorkArea.<PredicateBlock>returnStack(reverse); }
/** * 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; }