src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/PiNode.java
changeset 54084 84f10bbf993f
parent 52956 4b0b796dd581
child 58299 6df94ce3ab2f
equal deleted inserted replaced
54083:d9bcf74fc56a 54084:84f10bbf993f
    30 import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
    30 import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
    31 import org.graalvm.compiler.core.common.type.ObjectStamp;
    31 import org.graalvm.compiler.core.common.type.ObjectStamp;
    32 import org.graalvm.compiler.core.common.type.Stamp;
    32 import org.graalvm.compiler.core.common.type.Stamp;
    33 import org.graalvm.compiler.core.common.type.StampFactory;
    33 import org.graalvm.compiler.core.common.type.StampFactory;
    34 import org.graalvm.compiler.core.common.type.TypeReference;
    34 import org.graalvm.compiler.core.common.type.TypeReference;
       
    35 import org.graalvm.compiler.debug.DebugContext;
    35 import org.graalvm.compiler.graph.IterableNodeType;
    36 import org.graalvm.compiler.graph.IterableNodeType;
    36 import org.graalvm.compiler.graph.Node;
    37 import org.graalvm.compiler.graph.Node;
    37 import org.graalvm.compiler.graph.NodeClass;
    38 import org.graalvm.compiler.graph.NodeClass;
    38 import org.graalvm.compiler.graph.spi.Canonicalizable;
    39 import org.graalvm.compiler.graph.spi.Canonicalizable;
    39 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
    40 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
    98         this(object, StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType),
    99         this(object, StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType),
    99                         nonNull || StampTool.isPointerNonNull(object.stamp(NodeView.DEFAULT))));
   100                         nonNull || StampTool.isPointerNonNull(object.stamp(NodeView.DEFAULT))));
   100     }
   101     }
   101 
   102 
   102     public static ValueNode create(ValueNode object, Stamp stamp) {
   103     public static ValueNode create(ValueNode object, Stamp stamp) {
   103         ValueNode value = canonical(object, stamp, null);
   104         ValueNode value = canonical(object, stamp, null, null);
   104         if (value != null) {
   105         if (value != null) {
   105             return value;
   106             return value;
   106         }
   107         }
   107         return new PiNode(object, stamp);
   108         return new PiNode(object, stamp);
   108     }
   109     }
   109 
   110 
   110     public static ValueNode create(ValueNode object, Stamp stamp, ValueNode guard) {
   111     public static ValueNode create(ValueNode object, Stamp stamp, ValueNode guard) {
   111         ValueNode value = canonical(object, stamp, (GuardingNode) guard);
   112         ValueNode value = canonical(object, stamp, (GuardingNode) guard, null);
   112         if (value != null) {
   113         if (value != null) {
   113             return value;
   114             return value;
   114         }
   115         }
   115         return new PiNode(object, stamp, guard);
   116         return new PiNode(object, stamp, guard);
   116     }
   117     }
   117 
   118 
   118     public static ValueNode create(ValueNode object, ValueNode guard) {
   119     public static ValueNode create(ValueNode object, ValueNode guard) {
   119         Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT));
   120         Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT));
   120         ValueNode value = canonical(object, stamp, (GuardingNode) guard);
   121         ValueNode value = canonical(object, stamp, (GuardingNode) guard, null);
   121         if (value != null) {
   122         if (value != null) {
   122             return value;
   123             return value;
   123         }
   124         }
   124         return new PiNode(object, stamp, guard);
   125         return new PiNode(object, stamp, guard);
   125     }
   126     }
   126 
   127 
   127     @SuppressWarnings("unused")
   128     @SuppressWarnings("unused")
   128     public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ValueNode guard) {
   129     public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ValueNode guard) {
   129         Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT));
   130         Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT));
   130         ValueNode value = canonical(object, stamp, (GuardingNode) guard);
   131         ValueNode value = canonical(object, stamp, (GuardingNode) guard, null);
   131         if (value == null) {
   132         if (value == null) {
   132             value = new PiNode(object, stamp, guard);
   133             value = new PiNode(object, stamp, guard);
   133         }
   134         }
   134         b.push(JavaKind.Object, b.append(value));
   135         b.push(JavaKind.Object, b.append(value));
   135         return true;
   136         return true;
   137 
   138 
   138     @SuppressWarnings("unused")
   139     @SuppressWarnings("unused")
   139     public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
   140     public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
   140         Stamp stamp = StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType),
   141         Stamp stamp = StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType),
   141                         nonNull || StampTool.isPointerNonNull(object.stamp(NodeView.DEFAULT)));
   142                         nonNull || StampTool.isPointerNonNull(object.stamp(NodeView.DEFAULT)));
   142         ValueNode value = canonical(object, stamp, null);
   143         ValueNode value = canonical(object, stamp, null, null);
   143         if (value == null) {
   144         if (value == null) {
   144             value = new PiNode(object, stamp);
   145             value = new PiNode(object, stamp);
   145         }
   146         }
   146         b.push(JavaKind.Object, b.append(value));
   147         b.push(JavaKind.Object, b.append(value));
   147         return true;
   148         return true;
   175     @Override
   176     @Override
   176     public void virtualize(VirtualizerTool tool) {
   177     public void virtualize(VirtualizerTool tool) {
   177         ValueNode alias = tool.getAlias(object());
   178         ValueNode alias = tool.getAlias(object());
   178         if (alias instanceof VirtualObjectNode) {
   179         if (alias instanceof VirtualObjectNode) {
   179             VirtualObjectNode virtual = (VirtualObjectNode) alias;
   180             VirtualObjectNode virtual = (VirtualObjectNode) alias;
   180             if (StampTool.typeOrNull(this) != null && StampTool.typeOrNull(this).isAssignableFrom(virtual.type())) {
   181             ResolvedJavaType type = StampTool.typeOrNull(this, tool.getMetaAccess());
       
   182             if (type != null && type.isAssignableFrom(virtual.type())) {
   181                 tool.replaceWithVirtual(virtual);
   183                 tool.replaceWithVirtual(virtual);
       
   184             } else {
       
   185                 tool.getDebug().log(DebugContext.INFO_LEVEL, "could not virtualize Pi because of type mismatch: %s %s vs %s", this, type, virtual.type());
   182             }
   186             }
   183         }
   187         }
   184     }
   188     }
   185 
   189 
   186     public static ValueNode canonical(ValueNode object, Stamp stamp, GuardingNode guard) {
   190     public static ValueNode canonical(ValueNode object, Stamp stamp, GuardingNode guard, PiNode self) {
   187         // Use most up to date stamp.
   191         // Use most up to date stamp.
   188         Stamp computedStamp = stamp.improveWith(object.stamp(NodeView.DEFAULT));
   192         Stamp computedStamp = stamp.improveWith(object.stamp(NodeView.DEFAULT));
   189 
   193 
   190         // The pi node does not give any additional information => skip it.
   194         // The pi node does not give any additional information => skip it.
   191         if (computedStamp.equals(object.stamp(NodeView.DEFAULT))) {
   195         if (computedStamp.equals(object.stamp(NodeView.DEFAULT))) {
   199                 readNode.setStamp(readNode.stamp(NodeView.DEFAULT).improveWith(stamp));
   203                 readNode.setStamp(readNode.stamp(NodeView.DEFAULT).improveWith(stamp));
   200                 return readNode;
   204                 return readNode;
   201             }
   205             }
   202         } else {
   206         } else {
   203             for (Node n : guard.asNode().usages()) {
   207             for (Node n : guard.asNode().usages()) {
   204                 if (n instanceof PiNode) {
   208                 if (n instanceof PiNode && n != self) {
   205                     PiNode otherPi = (PiNode) n;
   209                     PiNode otherPi = (PiNode) n;
       
   210                     assert otherPi.guard == guard;
   206                     if (object == otherPi.object() && computedStamp.equals(otherPi.stamp(NodeView.DEFAULT))) {
   211                     if (object == otherPi.object() && computedStamp.equals(otherPi.stamp(NodeView.DEFAULT))) {
   207                         /*
   212                         /*
   208                          * Two PiNodes with the same guard and same result, so return the one with
   213                          * Two PiNodes with the same guard and same result, so return the one with
   209                          * the more precise piStamp.
   214                          * the more precise piStamp.
   210                          */
   215                          */
   219         return null;
   224         return null;
   220     }
   225     }
   221 
   226 
   222     @Override
   227     @Override
   223     public Node canonical(CanonicalizerTool tool) {
   228     public Node canonical(CanonicalizerTool tool) {
   224         Node value = canonical(object(), stamp(NodeView.DEFAULT), getGuard());
   229         Node value = canonical(object(), piStamp(), getGuard(), this);
   225         if (value != null) {
   230         if (value != null) {
   226             return value;
   231             return value;
   227         }
   232         }
   228         return this;
   233         return this;
   229     }
   234     }