public String toString() { StringBuffer buf = new StringBuffer("{RG "); int len = refs.size(); if (len > 3) len = 3; for (int i = 0; i < len; i++) { if (i > 0) buf.append(','); buf.append(refs.elementAt(i)); } if (len < refs.size()) buf.append(", ..."); buf.append('}'); return buf.toString(); }
private Cost computeRefCostSum(LoopHeaderChord loop, Vector<RefGroup> refGroups) { Cost lc = new Cost(); int l = refGroups.size(); for (int i = 0; i < l; i++) { RefGroup rg = refGroups.elementAt(i); SubscriptExpr se = rg.getRepresentative(); Cost cost = computeRefCost(loop, se); if (cost == null) continue; lc.add(cost); } return lc; }
public void perform() { if (trace) System.out.println("** LP " + scribble.getRoutineDecl().getName()); LoopHeaderChord lt = scribble.getLoopTree(); Vector<LoopHeaderChord> innerLoops = lt.getInnerLoops(); for (int li = 0; li < innerLoops.size(); li++) { LoopHeaderChord loop = innerLoops.elementAt(li); InductionVar ivar = loop.getPrimaryInductionVar(); if (trace) System.out.println(" lp " + loop.nestedLevel() + " " + loop); if ((ivar == null) || !loop.isPerfectlyNested()) { innerLoops.addVectors(loop.getInnerLoops()); continue; } if (loop.nestedLevel() < 2) // no need to check permutation for a simple nest continue; tryPermute(loop); } }
private void tryPermute(LoopHeaderChord topLoop) { Vector<LoopHeaderChord> loopNest = topLoop.getTightlyNestedLoops(); if (loopNest == null) return; int loopDepth = loopNest.size(); LoopHeaderChord bottom = loopNest.get(loopDepth - 1); if (!unsafe && !legalLoop(bottom)) return; // Set the loop costs for the loops in a loop nest. The cost for a loop is // the cost of executing the nest with that loop in the innermost nesting. Table<Declaration, SubscriptExpr> arrayRefs = new Table<Declaration, SubscriptExpr>(); if (!topLoop.getSubscriptsRecursive(arrayRefs)) return; graph = topLoop.getDDGraph(false); if (graph == null) return; if (trace) System.out.println(" " + graph); int[] loopIndex = new int[loopDepth]; Cost[] loopCostList = new Cost[loopDepth]; Vector<RefGroup> refGroups = new Vector<RefGroup>(20); for (int i = 0; i < loopDepth; i++) { LoopHeaderChord loop = loopNest.elementAt(i); if (trace) System.out.println(" " + i + " " + loop); computeRefGroups(loop.getNestedLevel(), 2, 2, arrayRefs, refGroups); Cost lc = computeRefCostSum(loop, refGroups); if (trace) System.out.println(" " + i + " " + lc); loopCostList[i] = lc; loopIndex[i] = i; // the outtermost loop is at position 0 Cost tp = tripProduct(loopNest, loop); if (trace) System.out.println(" " + i + " " + tp); lc.multiply(tp); if (trace) System.out.println(" " + i + " " + lc); } boolean permuted = sortByCost(loopCostList, loopIndex); if (!permuted) return; if (trace) { System.out.print(" permute " + loopDepth); System.out.print(":"); for (int i = 0; i < loopIndex.length; i++) System.out.print(" " + loopIndex[i]); System.out.println(""); } int[][] ddVec = getDDVec(arrayRefs, loopDepth); if (trace) printDDInfo(ddVec, loopDepth); if (!isLegal(loopIndex, ddVec)) return; if (trace) System.out.println(" permute " + loopDepth); int[] rank = new int[loopDepth]; // We will do sorting on the rank vector, which corresponds to the interchange we need. for (int i = 0; i < loopDepth; i++) { int loopNum = loopIndex[i]; rank[loopNum] = i; } if (trace) printOrder(rank); boolean changed = true; while (changed) { changed = false; for (int i = 0; i < loopDepth - 1; i++) { int j = i + 1; int outerRank = rank[i]; int innerRank = rank[j]; if (innerRank >= outerRank) continue; LoopHeaderChord innerLoop = loopNest.elementAt(j); LoopHeaderChord outerLoop = loopNest.elementAt(i); if (!outerLoop.isDDComplete() || outerLoop.inhibitLoopPermute()) continue; if (!innerLoop.isDDComplete() || innerLoop.inhibitLoopPermute()) continue; changed = true; rank[i] = innerRank; rank[j] = outerRank; loopNest.setElementAt(innerLoop, i); loopNest.setElementAt(outerLoop, j); performLoopInterchange(innerLoop, outerLoop); } } }
/** * Compute the reference groups for this loop. Two array references are in the same group with * respect to this loop if - there is a loop-independent dependence between them, or - the * dependence distance(dependence vector entry dl) for this loop is less than some constant * *dist*, and all other dependence vector entries are 0. - the two array refer to the same array * and differ by at most *dist2* in the first subscript dimension, where d is less than or equal * to the cache line size in terms of array elements. All other subscripts must be identical. * Notes: Here we assume dist1 = dist2 = 2 */ private void computeRefGroups( int level, int dist1, int dist2, Table<Declaration, SubscriptExpr> arrayRefs, Vector<RefGroup> refGroups) { if (arrayRefs == null) return; Enumeration<Declaration> ek = arrayRefs.keys(); while (ek.hasMoreElements()) { VariableDecl vd = (VariableDecl) ek.nextElement(); String s = vd.getName(); // array name Object[] v = arrayRefs.getRowArray(vd); // vector of SubscriptExpr's int vi = v.length; for (int j = vi - 1; j >= 0; j--) { SubscriptExpr sr = (SubscriptExpr) v[j]; Vector<LoopHeaderChord> allRelatedLoops = sr.allRelatedLoops(); // ** Incorrect when something like a[(j+i][j] int arls = allRelatedLoops.size(); int firstsub = arls - 1; // ** Making an invalid assumption here // Process the list of references r' with which r has a data // dependence, and r is the source(data flows from r to r'). RefGroup rg = new RefGroup(s, sr); Object[] edges = graph.getEdges(sr); int len = edges.length; for (int i = 0; i < len; i++) { DDEdge edge = (DDEdge) edges[i]; if (edge.isSpatial()) continue; // Condition(1)-(a) in McKinley's paper if (edge.isLoopIndependentDependency()) { // add rP to the RefGroup of r: rg.add(edge); continue; } // Condition(1)-(b) in McKinley's paper computeEdgeRefs(edge, rg, level, dist1); if (arls <= 0) continue; // Condition(2) in McKinley's paper // rlevel is the level of the loop related to the first subscript. int rlevel = allRelatedLoops.elementAt(firstsub).getNestedLevel(); computeEdgeRefs(edge, rg, rlevel, dist2); } boolean isInExistingRefGroups = false; int rgl = refGroups.size(); for (int i = 0; i < rgl; i++) { RefGroup rg2 = refGroups.elementAt(i); if (!rg2.getName().equals(s)) continue; isInExistingRefGroups = rg2.contains(rg); if (isInExistingRefGroups) { rg2.add(rg); break; } } if (!isInExistingRefGroups) refGroups.addElement(rg); } } }
private void printRefGroups(Vector<RefGroup> refGroups) { for (int i = 0; i < refGroups.size(); i++) { RefGroup rg = refGroups.elementAt(i); System.out.println(rg); } }
public SubscriptExpr getRepresentative() { if (refs.size() > 0) return (SubscriptExpr) refs.elementAt(0); return null; }