コード例 #1
0
 /**
  * Update the value graph to account for a given NEWARRAY instruction.
  *
  * <p><b>PRECONDITION:</b> <code> NewArray.conforms(s); </code> For a newarray instruction, we
  * always create a new vertex.
  *
  * @param s the instruction in question
  */
 private void processNewArray(Instruction s) {
   RegisterOperand result = NewArray.getResult(s);
   ValueGraphVertex v = findOrCreateVertex(result.getRegister());
   // set the label for a NEW instruction to be the instruction itself
   // so that no two NEW results get the same value number
   v.setLabel(s, 0);
 }
コード例 #2
0
  void mergeClasses(ValueGraphVertex v1, ValueGraphVertex v2) {
    if (DEBUG) {
      System.out.println("@@@@ mergeClasses called with v1 = " + v1 + " ; v2 = " + v2);
    }

    int val1 = v1.getValueNumber();
    int val2 = v2.getValueNumber();
    if (val1 == val2) return;

    GVCongruenceClass class1 = B.get(val1);

    while (true) {
      GVCongruenceClass class2 = B.get(val2);
      Iterator<ValueGraphVertex> i = class2.iterator();
      if (!i.hasNext()) break;
      ValueGraphVertex v = i.next();
      if (DEBUG) {
        System.out.println("@@@@ moving vertex " + v + " from class " + val2 + " to class " + val1);
      }
      class1.addVertex(v);
      class2.removeVertex(v);
      v.setValueNumber(val1);
    }

    // Null out entry for val2
    B.set(val2, null);
  }
コード例 #3
0
 /**
  * Return the (integer) value number for a given variable
  *
  * @param name name of the variable to look up
  * @return its value number
  */
 int getValueNumber(Object name) {
   ValueGraphVertex v = valueGraph.getVertex(name);
   if (v == null) {
     return UNKNOWN;
   }
   return v.getValueNumber();
 }
コード例 #4
0
 /**
  * Update the value graph to account for a given PI instruction.
  *
  * <p><b>PRECONDITION:</b> <code> s.operator == PI </code>
  *
  * @param s the instruction in question
  */
 private void processPi(Instruction s) {
   Register result = GuardedUnary.getResult(s).getRegister();
   ValueGraphVertex v = findOrCreateVertex(result);
   Operand val = GuardedUnary.getVal(s);
   // bypass Move instructions that define the right-hand side
   val = bypassMoves(val);
   v.copyVertex(findOrCreateVertex(val));
 }
コード例 #5
0
 /**
  * Update the value graph to account for an IR_PROLOGUE instruction
  *
  * <p><b>PRECONDITION:</b> <code> Prologue.conforms(s); </code>
  *
  * @param s the instruction in question
  */
 private void processPrologue(Instruction s) {
   int numArgs = 0;
   for (Enumeration<Operand> e = s.getDefs(); e.hasMoreElements(); numArgs++) {
     Register formal = ((RegisterOperand) e.nextElement()).getRegister();
     ValueGraphVertex v = findOrCreateVertex(formal);
     v.setLabel(new ValueGraphParamLabel(numArgs), 0);
   }
 }
コード例 #6
0
 /** Print the value numbers for each node in the value graph. */
 void printValueNumbers() {
   for (Enumeration<GraphNode> e = valueGraph.enumerateVertices(); e.hasMoreElements(); ) {
     ValueGraphVertex v = (ValueGraphVertex) e.nextElement();
     int valueNumber = v.getValueNumber();
     GVCongruenceClass c = B.get(valueNumber);
     System.out.println(v.getName() + " " + valueNumber + " " + c.getLabel());
   }
 }
コード例 #7
0
 /**
  * Update the value graph to account for a given IfCmp instruction.
  *
  * <p><b>PRECONDITION:</b> <code> IfCmp.conforms(s); </code>
  *
  * @param s the instruction in question
  */
 private void processIfCmp(Instruction s) {
   ValueGraphVertex v = new ValueGraphVertex(s);
   graph.addGraphNode(v);
   nameMap.put(s, v);
   v.setLabel(s.operator(), 3);
   link(v, findOrCreateVertex(bypassMoves(IfCmp.getVal1(s))), 0);
   link(v, findOrCreateVertex(bypassMoves(IfCmp.getVal2(s))), 1);
   link(v, findOrCreateVertex(IfCmp.getCond(s)), 2);
 }
コード例 #8
0
 /**
  * Find or create an ValueGraphVertex corresponding to a given register
  *
  * @param r the register
  * @return a value graph vertex corresponding to this variable
  */
 private ValueGraphVertex findOrCreateVertex(Register r) {
   ValueGraphVertex v = getVertex(r);
   if (v == null) {
     v = new ValueGraphVertex(r);
     v.setLabel(r, 0);
     graph.addGraphNode(v);
     nameMap.put(r, v);
   }
   return v;
 }
コード例 #9
0
 /**
  * Find or create an ValueGraphVertex corresponding to a given type operand
  *
  * @param op the operand in question
  * @return a value graph vertex corresponding to this type
  */
 private ValueGraphVertex findOrCreateVertex(TypeOperand op) {
   Object name = op.getTypeRef();
   ValueGraphVertex v = getVertex(name);
   if (v == null) {
     v = new ValueGraphVertex(op);
     v.setLabel(op, 0);
     graph.addGraphNode(v);
     nameMap.put(name, v);
   }
   return v;
 }
コード例 #10
0
 /**
  * Find or create an ValueGraphVertex corresponding to a given method operand
  *
  * @param op the operand in question
  * @return a value graph vertex corresponding to this type
  */
 private ValueGraphVertex findOrCreateVertex(ConditionOperand op) {
   Object name = op.value; // kludge.
   ValueGraphVertex v = getVertex(name);
   if (v == null) {
     v = new ValueGraphVertex(op);
     v.setLabel(op, 0);
     graph.addGraphNode(v);
     nameMap.put(name, v);
   }
   return v;
 }
コード例 #11
0
 /**
  * Update the value graph to account for a given NullCheck instruction.
  *
  * <p><b>PRECONDITION:</b> <code> ZeroCheck.conforms(s); </code>
  *
  * @param s the instruction in question
  */
 private void processZeroCheck(Instruction s) {
   // label the vertex corresponding to the result with the operator
   RegisterOperand result = ZeroCheck.getGuardResult(s);
   ValueGraphVertex v = findOrCreateVertex(result.getRegister());
   v.setLabel(s.operator(), 1);
   // link node v to the operand it uses
   Operand val = ZeroCheck.getValue(s);
   // bypass Move instructions
   val = bypassMoves(val);
   link(v, findOrCreateVertex(val), 0);
 }
コード例 #12
0
 /**
  * Assuming congruence class c has changed: find all other classes that might be affected, and add
  * them to the worklist
  *
  * @param c the congruence class that has changed
  */
 private void addDependentClassesToWorklist(GVCongruenceClass c) {
   // for each element of this congruence class:
   for (ValueGraphVertex v : c) {
     // for each vertex which points to v in the value graph
     for (Enumeration<GraphNode> e = v.inNodes(); e.hasMoreElements(); ) {
       ValueGraphVertex in = (ValueGraphVertex) e.nextElement();
       int vn = in.getValueNumber();
       GVCongruenceClass x = B.get(vn);
       workList.push(x);
     }
   }
 }
コード例 #13
0
 /**
  * Initialize the congruence classes, assuming that all nodes with the same label are congruent.
  */
 private void initialize() {
   // store a map from label -> congruenceClass
   HashMap<Object, GVCongruenceClass> labelMap = new HashMap<Object, GVCongruenceClass>(10);
   for (Enumeration<GraphNode> e = valueGraph.enumerateVertices(); e.hasMoreElements(); ) {
     ValueGraphVertex v = (ValueGraphVertex) e.nextElement();
     Object label = v.getLabel();
     GVCongruenceClass c = findOrCreateCongruenceClass(label, labelMap);
     // add this node to the congruence class
     c.addVertex(v);
     // set the value number for the node
     v.setValueNumber(c.getValueNumber());
   }
 }
コード例 #14
0
 /**
  * Partition a congruence class.
  *
  * @param partition the class to partition
  */
 private void partitionClass(GVCongruenceClass partition) {
   // store a reference to the first node in c, which will serve
   // as a representative for this class
   Iterator<ValueGraphVertex> i = partition.iterator();
   ValueGraphVertex first = i.next();
   ArrayList<GVCongruenceClass> newClasses = new ArrayList<GVCongruenceClass>();
   // now check each other node in c, to see if it matches the
   // representative
   ArrayList<ValueGraphVertex> toRemove = new ArrayList<ValueGraphVertex>();
   while (i.hasNext()) {
     ValueGraphVertex v = i.next();
     if (!checkCongruence(first, v)) {
       // NOT CONGRUENT!!  split the partition.  first check if
       // v fits in any other newly created congruence classes
       int index = findCongruenceMatch(newClasses, v);
       if (index > -1) {
         // MATCH FOUND!! place v in newClasses[index]
         GVCongruenceClass match = B.get(index);
         match.addVertex(v);
         v.setValueNumber(match.getValueNumber());
       } else {
         // NO MATCH FOUND!! create a new congruence class
         // find the appropriate label for the new congruence class
         // and create a new congruence class with this label
         GVCongruenceClass c = createCongruenceClass(v);
         newClasses.add(c);
         c.addVertex(v);
         v.setValueNumber(c.getValueNumber());
       }
       // mark v as to be removed from partition
       // (Can't remove it yet while iterating over the set);
       toRemove.add(v);
     }
   }
   // remove necessary vertices
   for (ValueGraphVertex v : toRemove) {
     partition.removeVertex(v);
   }
   // if needed place the original partition back on the work list
   if ((!newClasses.isEmpty()) && (partition.size() > 1)) {
     workList.push(partition);
   }
   // place any new congruence classes with size > 1 on the worklist
   // also place any classes which might indirectly be affected
   for (GVCongruenceClass c : newClasses) {
     if (c.size() > 1) {
       workList.push(c);
     }
     addDependentClassesToWorklist(c);
   }
 }
コード例 #15
0
 /**
  * Update the value graph to account for a given InlineGuard instruction.
  *
  * <p><b>PRECONDITION:</b> <code> InlineGuard.conforms(s); </code>
  *
  * @param s the instruction in question
  */
 private void processInlineGuard(Instruction s) {
   ValueGraphVertex v = new ValueGraphVertex(s);
   graph.addGraphNode(v);
   nameMap.put(s, v);
   if (s.operator() == IG_PATCH_POINT) {
     // the 'goal' is irrelevant for patch_point guards.
     v.setLabel(s.operator(), 1);
     link(v, findOrCreateVertex(bypassMoves(InlineGuard.getValue(s))), 0);
   } else {
     v.setLabel(s.operator(), 2);
     link(v, findOrCreateVertex(bypassMoves(InlineGuard.getValue(s))), 0);
     link(v, findOrCreateVertex(InlineGuard.getGoal(s)), 1);
   }
 }
コード例 #16
0
 /**
  * Update the value graph to account for a given GuardedBinary instruction.
  *
  * <p><b>PRECONDITION:</b> <code> GuardedBinary.conforms(s); </code> Careful: we define two
  * Guarded Binaries to be equivalent regardless of whether the guards are equivalent!
  *
  * @param s the instruction in question
  */
 private void processGuardedBinary(Instruction s) {
   // label the vertex corresponding to the result with the operator
   RegisterOperand result = GuardedBinary.getResult(s);
   ValueGraphVertex v = findOrCreateVertex(result.getRegister());
   v.setLabel(s.operator(), 2);
   // link node v to the two operands it uses
   // first link the first val
   Operand val = GuardedBinary.getVal1(s);
   val = bypassMoves(val);
   link(v, findOrCreateVertex(val), 0);
   Operand val2 = GuardedBinary.getVal2(s);
   val2 = bypassMoves(val2);
   link(v, findOrCreateVertex(val2), 1);
 }
コード例 #17
0
  /**
   * Update the value graph to account for a given MOVE instruction.
   *
   * <p><b>PRECONDITION:</b> <code> Move.conforms(s); </code>
   *
   * @param s the instruction in question
   */
  private void processMove(Instruction s) {
    // ignore instructions that define physical registers
    for (Enumeration<Operand> e = s.getDefs(); e.hasMoreElements(); ) {
      Operand current = e.nextElement();
      if (current instanceof RegisterOperand
          && ((RegisterOperand) current).getRegister().isPhysical()) return;
    }

    Register result = Move.getResult(s).getRegister();
    ValueGraphVertex v = findOrCreateVertex(result);
    Operand val = Move.getVal(s);
    // bypass Move instructions that define the right-hand side
    val = bypassMoves(val);
    v.copyVertex(findOrCreateVertex(val));
  }
コード例 #18
0
 /**
  * Update the value graph to account for a given Phi instruction.
  *
  * <p><b>PRECONDITION:</b> <code> Phi.conforms(s); </code>
  *
  * @param s the instruction in question
  */
 private void processPhi(Instruction s) {
   // the label for a PHI instruction is the basic block
   // in which it appears
   Register result = Phi.getResult(s).asRegister().getRegister();
   ValueGraphVertex v = findOrCreateVertex(result);
   BasicBlock bb = s.getBasicBlock();
   v.setLabel(bb, bb.getNumberOfIn());
   // link node v to all operands it uses
   for (int i = 0; i < Phi.getNumberOfValues(s); i++) {
     Operand val = Phi.getValue(s, i);
     val = bypassMoves(val);
     ValueGraphVertex target = findOrCreateVertex(val);
     link(v, target, i);
   }
 }
コード例 #19
0
 /**
  * Find or create an ValueGraphVertex corresponding to a given method operand
  *
  * @param op the operand in question
  * @return a value graph vertex corresponding to this type
  */
 private ValueGraphVertex findOrCreateVertex(MethodOperand op) {
   Object name;
   if (op.hasTarget()) {
     name = op.getTarget();
   } else {
     name = op.getMemberRef();
   }
   ValueGraphVertex v = getVertex(name);
   if (v == null) {
     v = new ValueGraphVertex(op);
     v.setLabel(op, 0);
     graph.addGraphNode(v);
     nameMap.put(name, v);
   }
   return v;
 }
コード例 #20
0
 /**
  * Transform to eliminate redundant branches passed on GVNs and dominator information.
  *
  * @param ir The IR on which to apply the phase
  */
 public void perform(IR ir) {
   // (1) Remove redundant conditional branches and locally fix the PHIs
   GlobalValueNumberState gvns = ir.HIRInfo.valueNumbers;
   DominatorTree dt = ir.HIRInfo.dominatorTree;
   for (BasicBlockEnumeration bbs = ir.getBasicBlocks(); bbs.hasMoreElements(); ) {
     BasicBlock candBB = bbs.next();
     Instruction candTest = candBB.firstBranchInstruction();
     if (candTest == null) continue;
     if (!(IfCmp.conforms(candTest) || InlineGuard.conforms(candTest))) continue;
     GVCongruenceClass cc = gvns.congruenceClass(candTest);
     if (cc.size() > 1) {
       for (ValueGraphVertex vertex : cc) {
         Instruction poss = (Instruction) vertex.getName();
         if (poss != candTest) {
           BasicBlock notTaken = getNotTakenBlock(poss);
           BasicBlock taken = poss.getBranchTarget();
           if (taken == notTaken) continue; // both go to same block, so we don't know anything!
           if (notTaken.hasOneIn() && dt.dominates(notTaken, candBB)) {
             if (DEBUG)
               VM.sysWrite(candTest + " is dominated by not-taken branch of " + poss + "\n");
             removeCondBranch(candBB, candTest, ir, poss);
             cc.removeVertex(gvns.valueGraph.getVertex(candTest));
             break;
           }
           if (taken.hasOneIn() && dt.dominates(taken, candBB)) {
             if (DEBUG)
               VM.sysWrite(candTest + " is dominated by taken branch of " + poss + "\n");
             takeCondBranch(candBB, candTest, ir);
             cc.removeVertex(gvns.valueGraph.getVertex(candTest));
             break;
           }
         }
       }
     }
   }
   // (2) perform a Depth-first search of the control flow graph,
   //     and remove any nodes we have made unreachable
   removeUnreachableCode(ir);
 }
コード例 #21
0
 /**
  * Find or create an ValueGraphVertex corresponding to a given constant operand
  *
  * @param op the constant operand
  * @return a value graph vertex corresponding to this variable
  */
 private ValueGraphVertex findOrCreateVertex(ConstantOperand op) {
   Object name;
   if (op.isAddressConstant()) {
     name =
         (VM.BuildFor32Addr)
             ? op.asAddressConstant().value.toInt()
             : op.asAddressConstant().value.toLong();
   } else if (op.isIntConstant()) {
     name = op.asIntConstant().value;
   } else if (op.isFloatConstant()) {
     name = op.asFloatConstant().value;
   } else if (op.isLongConstant()) {
     name = op.asLongConstant().value;
   } else if (op.isDoubleConstant()) {
     name = op.asDoubleConstant().value;
   } else if (op instanceof ObjectConstantOperand) {
     name = op.asObjectConstant().value;
   } else if (op instanceof TIBConstantOperand) {
     name = op.asTIBConstant().value;
   } else if (op.isNullConstant()) {
     name = op;
   } else if (op instanceof TrueGuardOperand) {
     name = op;
   } else if (op instanceof UnreachableOperand) {
     name = op;
   } else {
     throw new OptimizingCompilerException(
         "ValueGraph.findOrCreateVertex: unexpected constant operand: " + op);
   }
   ValueGraphVertex v = getVertex(name);
   if (v == null) {
     v = new ValueGraphVertex(op);
     v.setLabel(op, 0);
     graph.addGraphNode(v);
     nameMap.put(name, v);
   }
   return v;
 }
コード例 #22
0
 /**
  * Does the current state of the algorithm optimistically assume that two nodes are congruent?
  * Note: this can return false even if the value numbers are currently the same.
  *
  * @param v1 first vertex
  * @param v2 second vertex
  * @return whether the notes are assumed to be congruent
  */
 private boolean checkCongruence(ValueGraphVertex v1, ValueGraphVertex v2) {
   if (v1 == v2) {
     return true;
   }
   // make sure the two nodes have the same label
   if (v1.getLabel() != v2.getLabel()) {
     return false;
   }
   // make sure that the operands match
   int arity = v1.getArity();
   for (int i = 0; i < arity; i++) {
     ValueGraphVertex target1 = v1.getTarget(i);
     ValueGraphVertex target2 = v2.getTarget(i);
     // if either target is null, then that particular control
     // flow path is never realized, so assume TOP
     if ((target1 == null) || (target2 == null)) {
       continue;
     }
     if (target1.getValueNumber() != target2.getValueNumber()) {
       return false;
     }
   }
   return true;
 }
コード例 #23
0
 /**
  * Definitely-different relation. Returns true for the following cases:
  *
  * <ul>
  *   <li>name1 and name2 are both constants, but don't match
  *   <li>name1 and name2 both result from NEW statements, but don't match
  *   <li>one of name1 and name2 is a parameter, and the other results from a new statement
  * </ul>
  *
  * <p>TODO: add more smarts
  *
  * @param name1 name of first object to compare
  * @param name2 name of second object to compare
  * @return true iff the value numbers for two variables are definitely different
  */
 boolean DD(Object name1, Object name2) {
   ValueGraphVertex v1 = valueGraph.getVertex(name1);
   ValueGraphVertex v2 = valueGraph.getVertex(name2);
   return DD(v1.getValueNumber(), v2.getValueNumber());
 }
コード例 #24
0
 /**
  * Link two vertices in the value graph
  *
  * @param src the def
  * @param target the use
  * @param pos the position of target in the set of uses
  */
 private void link(ValueGraphVertex src, ValueGraphVertex target, int pos) {
   ValueGraphEdge e = new ValueGraphEdge(src, target);
   src.addTarget(target, pos);
   graph.addGraphEdge(e);
 }
コード例 #25
0
 /**
  * Due to PI nodes and Moves, the initial label for a register may be another register. Fix up the
  * value graph for cases where the initial register label was not removed.
  */
 private void computeClosure() {
   for (Enumeration<GraphNode> e = enumerateVertices(); e.hasMoreElements(); ) {
     ValueGraphVertex v = (ValueGraphVertex) e.nextElement();
     if (v.getName() instanceof Register) {
       if (v.getLabel() instanceof Register) {
         if (v.getName() != v.getLabel()) {
           ValueGraphVertex v2 = getVertex(v.getLabel());
           if (VM.VerifyAssertions) {
             if (v2.getName() instanceof Register
                 && v2.getLabel() instanceof Register
                 && v2.getLabel() != v2.getName()) {
               VM._assert(VM.NOT_REACHED);
             }
           }
           v.copyVertex(v2);
         }
       }
     }
   }
 }
コード例 #26
0
 /**
  * Definitely-same relation.
  *
  * @param name1 first variable
  * @param name2 second variable
  * @return true iff the value numbers for two variables are equal
  */
 boolean DS(Object name1, Object name2) {
   ValueGraphVertex v1 = valueGraph.getVertex(name1);
   ValueGraphVertex v2 = valueGraph.getVertex(name2);
   return v1.getValueNumber() == v2.getValueNumber();
 }
コード例 #27
0
 GVCongruenceClass congruenceClass(Object name) {
   ValueGraphVertex v = valueGraph.getVertex(name);
   return B.get(v.getValueNumber());
 }