Exemplo n.º 1
0
Arquivo: CP.java Projeto: wrmsr/scale
  /** 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();
    }
  }
Exemplo n.º 2
0
  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;
  }
Exemplo n.º 3
0
  /** Remove all the predicates which are not defined in the hyperblock. */
  private BitVect removePredicates(PredicateBlock start) {
    BitVect predicates = new BitVect();
    Stack<Node> wl = new Stack<Node>();

    // Determine all the predicates defined outside this hyperblock.

    start.nextVisit();
    start.setVisited();
    wl.add(start);

    while (!wl.isEmpty()) {
      PredicateBlock block = (PredicateBlock) wl.pop();
      block.pushOutEdges(wl);

      for (Instruction inst = block.getFirstInstruction(); inst != null; inst = inst.getNext()) {
        if (inst.isMarker()) {
          continue;
        }

        if (inst.isBranch()) {
          continue;
        }

        if (((TripsInstruction) inst).definesPredicate()) {
          predicates.set(inst.getDestRegister());
        }
      }
    }

    // Remove the predicates.

    start.nextVisit();
    start.setVisited();
    wl.add(start);

    while (!wl.isEmpty()) {
      PredicateBlock block = (PredicateBlock) wl.pop();
      block.pushOutEdges(wl);

      if (!block.isPredicated()) {
        continue;
      }

      int rp = block.getPredicate();
      if (predicates.get(rp)) {
        continue;
      }

      block.removePredicates();

      for (Instruction inst = block.getFirstInstruction(); inst != null; inst = inst.getNext()) {
        inst.removePredicates();
      }
    }

    return predicates;
  }
Exemplo n.º 4
0
  /** 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);
  }
Exemplo n.º 5
0
  /** 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);
  }
Exemplo n.º 6
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;
  }