Example #1
0
  public Cost computeRefCost(LoopHeaderChord loop, SubscriptExpr se) {
    Cost tripL = loop.getTripCount();
    InductionVar ivar = loop.getPrimaryInductionVar();
    if (ivar == null) return tripL;

    // Compute
    // tripL = (ubL - lbL + stepL) / stepL

    int nsubs = se.numSubscripts(); // number of subscripts in the subscript
    LoopHeaderChord tloop = loop.getTopLoop();
    VariableDecl iv = ivar.getVar();

    for (int i = 0; i < nsubs - 1; i++) { // for c code
      // If the loop index variable of this loop appears in any of the
      // subscripts other then the last, then return tripL.
      Expr sI = se.getSubscript(i);
      AffineExpr ae = tloop.isAffine(sI);

      if (ae == null) return null;

      if (ae.hasTerm(iv)) return tripL;
    }

    int fs = nsubs - 1;
    Expr s0 = se.getSubscript(fs);
    AffineExpr ae = tloop.isAffine(s0);
    if (ae == null) return null;

    int at = ae.getTermIndexOrig(iv);
    long coeff = 0;
    if (at >= 0) coeff = ae.getCoefficient(at);

    if (coeff == 0) // Invariant Reuse.
    return new Cost(1.0, 0);

    long stepL = loop.getStepValue();
    long stride = stepL * coeff;
    if (stride < 0) stride = -stride;

    // Unit Reuse.

    Type et = se.getCoreType().getPointedTo();
    int bs = et.memorySizeAsInt(Machine.currentMachine);
    int cs = Machine.currentMachine.getCacheSize(bs);
    if (stride <= cs) { // cache line or block size
      tripL.multiply(stride);
      tripL.divide(cs);
      return tripL;
    }

    // No Reuse.

    return tripL;
  }
Example #2
0
  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);
      }
    }
  }