示例#1
0
 /**
  * Similar to {@link #deverbosifyInputsInPlace(com.oracle.graal.nodes.ValueNode)}, except that not
  * the parent but a fresh clone is updated upon any of its children changing.
  *
  * @return the original parent if no updated took place, a copy-on-write version of it otherwise.
  */
 private MethodCallTargetNode deverbosifyInputsCopyOnWrite(MethodCallTargetNode parent) {
   final CallTargetNode.InvokeKind ik = parent.invokeKind();
   final boolean shouldTryDevirt =
       (ik == CallTargetNode.InvokeKind.Interface || ik == CallTargetNode.InvokeKind.Virtual);
   boolean shouldDowncastReceiver = shouldTryDevirt;
   MethodCallTargetNode changed = null;
   for (ValueNode i : FlowUtil.distinctValueAndConditionInputs(parent)) {
     ValueNode j = (ValueNode) reasoner.deverbosify(i);
     if (shouldDowncastReceiver) {
       shouldDowncastReceiver = false;
       j = reasoner.downcast(j);
     }
     if (i != j) {
       assert j != parent;
       if (changed == null) {
         changed = (MethodCallTargetNode) parent.copyWithInputs();
         reasoner.added.add(changed);
         // copyWithInputs() implies graph.unique(changed)
         assert changed.isAlive();
         assert FlowUtil.lacksUsages(changed);
       }
       FlowUtil.replaceInPlace(changed, i, j);
     }
   }
   if (changed == null) {
     return parent;
   }
   FlowUtil.inferStampAndCheck(changed);
   /*
    * No need to rememberSubstitution() because not called from deverbosify(). In detail, it's
    * only deverbosify() that skips visited nodes (thus we'd better have recorded any
    * substitutions we want for them). Not this case.
    */
   return changed;
 }
示例#2
0
 /**
  * Reduce input nodes based on the state at the program point for the argument (ie, based on
  * "valid facts" only, without relying on any floating-guard-assumption).
  *
  * <p>For each (direct or indirect) child, a copy-on-write version is made in case any of its
  * children changed, with the copy accommodating the updated children. If the parent was shared,
  * copy-on-write prevents the updates from becoming visible to anyone but the invoker of this
  * method.
  *
  * <p><b> Please note the parent node is mutated upon any descendant changing. No copy-on-write is
  * performed for the parent node itself. </b>
  *
  * <p>In more detail, for each direct {@link com.oracle.graal.nodes.ValueNode} input of the node
  * at hand,
  *
  * <ol>
  *   <li>Obtain a lazy-copied version (via spanning tree) of the DAG rooted at the input-usage in
  *       question. Lazy-copying is done by walking a spanning tree of the original DAG, stopping
  *       at non-FloatingNodes but transitively walking FloatingNodes and their inputs. Upon
  *       arriving at a (floating) node N, the state's facts are checked to determine whether a
  *       constant C can be used instead in the resulting lazy-copied DAG. A NodeBitMap is used to
  *       realize the spanning tree.
  *   <li>Provided one or more N-to-C node replacements took place, the resulting lazy-copied DAG
  *       has a parent different from the original (ie different object identity) which indicates
  *       the (copied, updated) DAG should replace the original via replaceFirstInput(), and
  *       inferStamp() should be invoked to reflect the updated inputs.
  * </ol>
  *
  * @return whether any reduction was performed on the inputs of the arguments.
  */
 public boolean deverbosifyInputsInPlace(ValueNode parent) {
   boolean changed = false;
   for (ValueNode i : FlowUtil.distinctValueAndConditionInputs(parent)) {
     assert !(i instanceof GuardNode) : "This phase not intended to run during MidTier";
     ValueNode j = (ValueNode) reasoner.deverbosify(i);
     if (i != j) {
       changed = true;
       FlowUtil.replaceInPlace(parent, i, j);
     }
   }
   if (changed) {
     FlowUtil.inferStampAndCheck(parent);
   }
   return changed;
 }