コード例 #1
0
ファイル: OptimizingVisitor.java プロジェクト: sba1/teavm
 @Override
 public void visit(SubscriptExpr expr) {
   expr.getIndex().acceptVisitor(this);
   Expr index = resultExpr;
   expr.getArray().acceptVisitor(this);
   Expr array = resultExpr;
   expr.setArray(array);
   expr.setIndex(index);
   resultExpr = expr;
 }
コード例 #2
0
ファイル: LoopPermute.java プロジェクト: troore/scale
  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;
  }
コード例 #3
0
 @Override
 public Node forSubscriptExpr(SubscriptExpr that) {
   if (!Shell.getAssignmentPreDesugaring()) {
     return super.forSubscriptExpr(that);
   } else {
     // Rewrite a subscript expression into a method call (pretty straightforward)
     Expr obj = that.getObj();
     List<Expr> subs = that.getSubs();
     Option<Op> op = that.getOp();
     List<StaticArg> staticArgs = that.getStaticArgs();
     if (!op.isSome()) bug(that, "Subscript operator expected");
     Op knownOp = op.unwrap();
     Expr result =
         ExprFactory.makeMethodInvocation(
             that,
             obj,
             knownOp,
             staticArgs,
             ExprFactory.makeTupleExpr(NodeUtil.getSpan(knownOp), subs));
     return (Expr) recur(result);
   }
 }
コード例 #4
0
 @Override
 public Node forAssignment(Assignment that) {
   // System.out.println("PreDesugar entry");
   // Here there are three sorts of rewrite to consider:
   // (a) If this is a compound assignment, rewrite to use ordinary assignment.
   // (b) If the lhs is a tuple, rewrite into a set of individual assignments.
   // (c) If the lhs is a subscript expression, rewrite to a method call.
   List<Lhs> lhs = that.getLhs();
   Option<FunctionalRef> assignOp = that.getAssignOp();
   Expr rhs = that.getRhs();
   List<CompoundAssignmentInfo> assignmentInfos = that.getAssignmentInfos();
   if (!Shell.getAssignmentPreDesugaring()) {
     // System.out.println("Did not PreDesugar");
     return super.forAssignment(that);
   } else if (assignOp.isSome() || lhs.size() > 1) {
     // System.out.println("Compound/tuple PreDesugar");
     // Compound and/or tuple assignment
     // The basic idea is to transform `(a, b.field, c[sub1,sub2]) := e` into
     // `do (ta, tb, tc, tsub1, tsub2, (t1, t2, t3)) = (a, b, c, sub1, sub2, e)
     //     a := t1; tb.field := t2; tc[tsub1, tsub2] := t3 end`
     // (TODO) Unfortunately, currently we don't handle nested binding tuples.
     // For now, we'll just transform it into
     // `do (ta, tb, tc, tsub1, tsub2) = (a, b, c, sub1, sub2)
     //     (t1, t2, t3) = e
     //     a := t1; tb.field := t2; tc[tsub1, tsub2] := t3 end`
     // which merely loses a bit of potential parallelism.
     // We omit the first tuple binding if the tuple is empty.
     // If it is a compound assignment `(a, b.field, c[sub1,sub2]) OP= e`, it becomes
     // `do (ta, tb, tc, tsub1, tsub2) = (a, b, c, sub1, sub2)
     //     (t1, t2, t3) = (ta, tb, tc[tsub1, tsub2]) OP e
     //     a := t1; tb.field := t2; tc[tsub1, tsub2] := t3 end`
     List<LValue> exprLValues = Useful.list();
     List<LValue> otherLValues = Useful.list();
     List<Expr> otherExprs = Useful.list();
     List<Expr> assignments = Useful.list();
     boolean isCompound = assignOp.isSome();
     List<Expr> accesses = Useful.list();
     Span thatSpan = NodeUtil.getSpan(that);
     for (Lhs lh : lhs) {
       Span lhSpan = NodeUtil.getSpan((Expr) lh);
       Id tempId = DesugarerUtil.gensymId(lhSpan, "e");
       VarRef tempVar = ExprFactory.makeVarRef(lhSpan, tempId);
       exprLValues = Useful.snoc(exprLValues, NodeFactory.makeLValue(lhSpan, tempId));
       if (lh instanceof SubscriptExpr) {
         SubscriptExpr lhsub = (SubscriptExpr) lh;
         Expr obj = lhsub.getObj();
         Span objSpan = NodeUtil.getSpan(obj);
         List<Expr> subs = lhsub.getSubs();
         Id baseTempId = DesugarerUtil.gensymId(objSpan, "b");
         VarRef baseTempVar = ExprFactory.makeVarRef(objSpan, baseTempId);
         otherLValues = Useful.snoc(otherLValues, NodeFactory.makeLValue(objSpan, baseTempId));
         otherExprs = Useful.snoc(otherExprs, obj);
         List<Expr> subTempVars = Useful.list();
         for (Expr sub : lhsub.getSubs()) {
           Span subSpan = NodeUtil.getSpan(sub);
           Id subTempId = DesugarerUtil.gensymId(subSpan, "s");
           subTempVars = Useful.snoc(subTempVars, ExprFactory.makeVarRef(subSpan, subTempId));
           otherLValues = Useful.snoc(otherLValues, NodeFactory.makeLValue(subSpan, subTempId));
         }
         otherExprs = Useful.concat(otherExprs, subs);
         SubscriptExpr newLhs =
             ExprFactory.makeSubscriptExpr(
                 NodeUtil.getSpan(lhsub),
                 baseTempVar,
                 subTempVars,
                 lhsub.getOp(),
                 lhsub.getStaticArgs());
         if (isCompound) accesses = Useful.snoc(accesses, newLhs);
         assignments =
             Useful.snoc(assignments, ExprFactory.makeAssignment(thatSpan, newLhs, tempVar));
       } else if (lh instanceof FieldRef) {
         FieldRef lhref = (FieldRef) lh;
         Expr obj = lhref.getObj();
         Span objSpan = NodeUtil.getSpan(obj);
         Id objTempId = DesugarerUtil.gensymId(objSpan, "o");
         VarRef objTempVar = ExprFactory.makeVarRef(objSpan, objTempId);
         otherLValues = Useful.snoc(otherLValues, NodeFactory.makeLValue(objSpan, objTempId));
         otherExprs = Useful.snoc(otherExprs, obj);
         FieldRef newLhs =
             ExprFactory.makeFieldRef(NodeUtil.getSpan(lhref), objTempVar, lhref.getField());
         if (isCompound) accesses = Useful.snoc(accesses, newLhs);
         assignments =
             Useful.snoc(assignments, ExprFactory.makeAssignment(thatSpan, newLhs, tempVar));
       } else if (lh instanceof VarRef) {
         VarRef lhvar = (VarRef) lh;
         Span varSpan = NodeUtil.getSpan(lhvar);
         Id varTempId = DesugarerUtil.gensymId(varSpan, "v");
         VarRef varTempVar = ExprFactory.makeVarRef(varSpan, varTempId);
         otherLValues = Useful.snoc(otherLValues, NodeFactory.makeLValue(varSpan, varTempId));
         otherExprs = Useful.snoc(otherExprs, lhvar);
         if (isCompound) accesses = Useful.snoc(accesses, varTempVar);
         assignments =
             Useful.snoc(assignments, ExprFactory.makeAssignment(thatSpan, lhvar, tempVar));
       } else {
         bug(that, "Malformed assignment LHS");
       }
     }
     Expr result = ExprFactory.makeBlock(thatSpan, assignments);
     if (otherExprs.size() > 0) {
       Expr otherRhs = ExprFactory.makeMaybeTupleExpr(thatSpan, otherExprs);
       result = ExprFactory.makeLocalVarDecl(thatSpan, otherLValues, otherRhs, result);
     }
     Expr newRhs =
         isCompound
             ? ExprFactory.makeOpExpr(
                 NodeUtil.spanTwo(assignOp.unwrap(), rhs),
                 assignOp.unwrap(),
                 ExprFactory.makeMaybeTupleExpr(thatSpan, accesses),
                 rhs)
             : rhs;
     result = ExprFactory.makeLocalVarDecl(thatSpan, exprLValues, newRhs, result);
     return (Expr) recur(result);
   } else if (lhs.get(0) instanceof SubscriptExpr) {
     // System.out.println("PreDesugar single subscript expr");
     // Subscripted assignment
     SubscriptExpr lhExpr = (SubscriptExpr) lhs.get(0);
     Expr obj = lhExpr.getObj();
     List<Expr> subs = lhExpr.getSubs();
     Option<Op> op = lhExpr.getOp();
     List<StaticArg> staticArgs = lhExpr.getStaticArgs();
     if (!op.isSome()) bug(lhExpr, "Subscript operator expected");
     Op knownOp = op.unwrap();
     Expr result =
         ExprFactory.makeMethodInvocation(
             that,
             obj,
             NodeFactory.makeOp(knownOp, knownOp.getText() + ":="),
             staticArgs,
             ExprFactory.makeTupleExpr(NodeUtil.spanTwo(knownOp, rhs), Useful.cons(rhs, subs)));
     return (Expr) recur(result);
   } else {
     // System.out.println("PreDesugar single expr of class " + lhs.get(0).getClass().getName());
     return super.forAssignment(that);
   }
 }
コード例 #5
0
ファイル: LoopPermute.java プロジェクト: troore/scale
  /**
   * 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);
      }
    }
  }