Beispiel #1
0
  /** 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();
    }
  }
Beispiel #2
0
  /**
   * 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;
  }
Beispiel #3
0
  private void visitExprChord(ExprChord se, boolean doSubscripts) {
    if (se.getPredicate() != null) {
      return;
    }

    Expr rvalue = se.getRValue();
    if (rvalue instanceof PhiExpr) {
      return;
    }

    if (rvalue instanceof DualExpr) {
      if (!doSubscripts && (((DualExpr) rvalue).getHigh() instanceof SubscriptExpr)) {
        return; // Don't mess up ScalarReplacement.
      }
      rvalue = ((DualExpr) rvalue).getLow();
    }

    // Check if the statement is a simple assignment to a variable.

    Expr lvalue = se.getLValue();
    if (!(lvalue instanceof LoadDeclAddressExpr)) {
      return;
    }

    if (!rvalue.getCoreType().isAtomicType()) {
      return;
    }

    LoadDeclAddressExpr lhs = (LoadDeclAddressExpr) lvalue;
    VariableDecl ldecl = (VariableDecl) lhs.getDecl();

    if (ldecl.isNotAliasCandidate()) {
      return;
    }

    if (doSubscripts) {
      while (rvalue instanceof DualExpr) {
        rvalue = rvalue.getLow();
      }
    }

    Expr rv = rvalue;

    while (rv.isCast()) {
      rv = rv.getOperand(0);
    }

    if (!(rv instanceof LoadDeclValueExpr)) {
      if (!(rv instanceof AdditionExpr) && !(rv instanceof SubtractionExpr)) {
        return;
      }

      if (!rv.optimizationCandidate()) {
        return;
      }

      BinaryExpr be = (BinaryExpr) rv;
      Expr ra = be.getRightArg();
      if (!ra.isLiteralExpr()) {
        return;
      }

      if (!ra.getCoreType().isIntegerType()) {
        return;
      }

      Expr la = be.getLeftArg();
      while (la.isCast()) {
        la = la.getOperand(0);
      }

      if (!(la instanceof LoadDeclValueExpr)) {
        return; // It's not a simple add or subtract.
      }

      // Undo some of the damage caused by ValNum & LICM.  Move simple
      // adds & subtracts to reduce register pressure.

      // It makes no sense to propagate an addition expression that
      // references a variable that should not be aliased.  For
      // example, if the variable is in memory, this could increase
      // the number of memory references and undo much of what global
      // variable replacement tries to do.

      VariableDecl org = ((VariableDecl) ((LoadDeclValueExpr) la).getDecl()).getOriginal();
      if ((org == ldecl.getOriginal()) || org.isNotAliasCandidate()) {
        return;
      }

      LoopHeaderChord lh = be.getChord().getLoopHeader();
      LoadExpr[] uda = se.getDefUseArray();
      for (int i = 0; i < uda.length; i++) {
        LoadExpr ud = uda[i];
        Chord s = ud.getChord();
        LoopHeaderChord slh = s.getLoopHeader();
        Note out = ud.getOutDataEdge();

        // Propagate the expression.

        out.changeInDataEdge(ud, rvalue.copy());
        ud.unlinkExpression();
        rChanged = true;
      }

      return;
    }

    LoadDeclValueExpr rhs = (LoadDeclValueExpr) rv;
    VariableDecl rdecl = (VariableDecl) rhs.getDecl();

    if (!rdecl.optimizationCandidate()) {
      return;
    }

    if ((rdecl == rdecl.getOriginal()) && (ldecl.getOriginal() == rdecl)) {
      return; // The original variable is special in SSA form.
    }

    ExprChord rhsud = rhs.getUseDef();
    if (!doSubscripts && (rhsud != null)) {
      // Don't mess up scalar replacement by creating new data
      // dependence edges.
      Expr rhsv = rhsud.getRValue();
      if (rhsv instanceof DualExpr) {
        return;
      }
    }

    // For now if the may use info is not null, do not propagate.

    if (rhs.getMayUse() != null) {
      return;
    }

    MayDef md = se.getMayDef();
    LoadExpr[] uses = se.getDefUseArray();
    for (int i = 0; i < uses.length; i++) {
      LoadExpr use = uses[i];

      // Copy propagation of a variable into a phi function just
      // results in extra copy operations.  For example, consider
      //      x1 = y
      //   l: x3 = phi(x1, x4)
      //
      // After copy propagation
      //      x1 = y
      //   l: x3 = phi(y, x4)
      //
      // After phi removal
      //      x1 = y
      //      x3 = y
      //   l:
      //
      // After variable coalescing
      //      x = y
      //      x = y

      if (use.getOutDataEdge() instanceof PhiExpr) {
        continue;
      }

      boolean doit = true;

      // If there is may def information associated with the
      // lhs of the expression, check to see if it can be
      // propagated.

      if (!unsafe) {
        MayUse mu = use.getMayUse();

        if (md != null) {
          if (mu == null) {
            doit = false;
          } else {
            Declaration d1 = null;
            MayDef ud = mu.findMayDef();

            if (ud != null) {
              d1 = ((LoadExpr) (ud.getLhs())).getDecl();
            }

            /*Declaration d1 = mu.getDecl();*/
            Declaration d2 = ((LoadExpr) md.getLhs()).getDecl();
            doit = (d1 == d2);
          }
        }
      }

      if (doit) { // Change the variable in the use.
        if (rv == rvalue) {
          use.setDecl(rdecl);
          use.setUseDef(rhsud);
        } else {
          Note out = use.getOutDataEdge();
          out.changeInDataEdge(use, rvalue.copy());
          use.unlinkExpression();
        }

        rChanged = true;

        propagationCount++;
      } else {
        aliasInhibitedCount++;
      }
    }
  }