Search in sources :

Example 6 with ObjectStamp

use of org.graalvm.compiler.core.common.type.ObjectStamp in project graal by oracle.

the class InferStamps method inferStamps.

/**
 * Infer the stamps for all Object nodes in the graph, to make the stamps as precise as
 * possible. For example, this propagates the word-type through phi functions. To handle phi
 * functions at loop headers, the stamp inference is called until a fix point is reached.
 * <p>
 * This method can be used when it is needed that stamps are inferred before the first run of
 * the canonicalizer. For example, word type rewriting must run before the first run of the
 * canonicalizer because many nodes are not prepared to see the word type during
 * canonicalization.
 */
public static void inferStamps(StructuredGraph graph) {
    /*
         * We want to make the stamps more precise. For cyclic phi functions, this means we have to
         * ignore the initial stamp because the imprecise stamp would always propagate around the
         * cycle. We therefore set the stamp to an illegal stamp, which is automatically ignored
         * when the phi function performs the "meet" operator on its input stamps.
         */
    for (Node n : graph.getNodes()) {
        if (n instanceof ValuePhiNode) {
            ValueNode node = (ValueNode) n;
            if (node.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
                assert node.stamp(NodeView.DEFAULT).hasValues() : "We assume all Phi and Proxy stamps are legal before the analysis";
                node.setStamp(node.stamp(NodeView.DEFAULT).empty());
            }
        }
    }
    boolean stampChanged;
    // The algorithm is not guaranteed to reach a stable state.
    int z = 0;
    do {
        stampChanged = false;
        /*
             * We could use GraphOrder.forwardGraph() to process the nodes in a defined order and
             * propagate long def-use chains in fewer iterations. However, measurements showed that
             * we have few iterations anyway, and the overhead of computing the order is much higher
             * than the benefit.
             */
        for (Node n : graph.getNodes()) {
            if (n instanceof ValueNode) {
                ValueNode node = (ValueNode) n;
                if (node.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
                    stampChanged |= node.inferStamp();
                }
            }
        }
        ++z;
    } while (stampChanged && z < 10000);
    /*
         * Check that all the illegal stamps we introduced above are correctly replaced with real
         * stamps again.
         */
    assert checkNoEmptyStamp(graph);
}
Also used : ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) ValueNode(org.graalvm.compiler.nodes.ValueNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) Node(org.graalvm.compiler.graph.Node) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 7 with ObjectStamp

use of org.graalvm.compiler.core.common.type.ObjectStamp in project graal by oracle.

the class ObjectStampJoinTest method testJoinInterface1.

private void testJoinInterface1(Class<?> typeA, Class<?> typeI) {
    Stamp aNonNull = StampFactory.objectNonNull(getType(typeA));
    Stamp i = StampFactory.object(getType(typeI));
    Stamp join = join(aNonNull, i);
    Assert.assertTrue(join instanceof ObjectStamp);
    Assert.assertTrue(((ObjectStamp) join).nonNull());
}
Also used : ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) Stamp(org.graalvm.compiler.core.common.type.Stamp) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp)

Example 8 with ObjectStamp

use of org.graalvm.compiler.core.common.type.ObjectStamp in project graal by oracle.

the class CInterfaceEnumTool method createEnumLookupInvoke.

public ValueNode createEnumLookupInvoke(HostedGraphKit kit, ResolvedJavaType enumType, EnumInfo enumInfo, JavaKind parameterKind, ValueNode arg) {
    InvokeNode invoke = invokeEnumLookup(kit, CallTargetFactory.from(kit), kit.getFrameState(), kit.bci(), enumInfo, parameterKind, arg);
    ObjectStamp resultStamp = StampFactory.object(TypeReference.create(null, enumType), false);
    return kit.unique(new PiNode(invoke, resultStamp));
}
Also used : ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) PiNode(org.graalvm.compiler.nodes.PiNode)

Example 9 with ObjectStamp

use of org.graalvm.compiler.core.common.type.ObjectStamp in project graal by oracle.

the class StrengthenStampsPhase method strengthenStamp.

private Stamp strengthenStamp(ValueNode node, JavaTypeProfile typeProfile) {
    ObjectStamp oldStamp = (ObjectStamp) node.stamp(NodeView.DEFAULT);
    HostedType oldType = toHosted(oldStamp.type());
    if (oldStamp.alwaysNull()) {
        /* We cannot make that more precise. */
        return oldStamp;
    }
    boolean nonNull = oldStamp.nonNull() || typeProfile.getNullSeen() == TriState.FALSE;
    ProfiledType[] exactTypes = typeProfile.getTypes();
    if (exactTypes.length == 1) {
        ResolvedJavaType exactType = exactTypes[0].getType();
        assert oldType == null || oldType.isAssignableFrom(exactType);
        if (!oldStamp.isExactType() || !exactType.equals(oldType) || nonNull != oldStamp.nonNull()) {
            TypeReference typeRef = TypeReference.createExactTrusted(toTarget(exactType));
            return nonNull ? StampFactory.objectNonNull(typeRef) : StampFactory.object(typeRef);
        } else {
            return oldStamp;
        }
    }
    if (exactTypes.length == 0) {
        if (!nonNull) {
            return StampFactory.alwaysNull();
        } else {
            /*
                 * The code after the node is unreachable. We just insert a always-failing guard
                 * after the node and let dead code elimination remove everything after the node.
                 */
            StructuredGraph graph = node.graph();
            FixedWithNextNode insertionPoint;
            if (node instanceof ParameterNode) {
                /* The whole method is unreachable. */
                insertionPoint = graph.start();
            } else if (node instanceof InvokeWithExceptionNode) {
                /* The invoked method never returns normally (but can throw an exception). */
                insertionPoint = ((InvokeWithExceptionNode) node).next();
            } else {
                insertionPoint = (FixedWithNextNode) node;
            }
            graph.addAfterFixed(insertionPoint, graph.add(new FixedGuardNode(LogicConstantNode.forBoolean(true, graph), DeoptimizationReason.UnreachedCode, DeoptimizationAction.None, true)));
            return oldStamp;
        }
    }
    ResolvedJavaType baseType;
    if (oldStamp.isExactType()) {
        /* Base type cannot be more precise. */
        baseType = oldType;
    } else {
        assert exactTypes.length > 1;
        assert oldType == null || oldType.isAssignableFrom(exactTypes[0].getType());
        baseType = exactTypes[0].getType();
        for (int i = 1; i < exactTypes.length; i++) {
            assert oldType == null || oldType.isAssignableFrom(exactTypes[i].getType());
            baseType = baseType.findLeastCommonAncestor(exactTypes[i].getType());
        }
        if (oldType != null && !oldType.isAssignableFrom(baseType)) {
            /*
                 * When the original stamp is an interface type, we do not want to weaken that type
                 * with the common base class of all implementation types (which could even be
                 * java.lang.Object).
                 */
            baseType = oldType;
        }
    }
    if (!baseType.equals(oldType) || nonNull != oldStamp.nonNull()) {
        TypeReference typeRef = TypeReference.createTrustedWithoutAssumptions(toTarget(baseType));
        return nonNull ? StampFactory.objectNonNull(typeRef) : StampFactory.object(typeRef);
    }
    return oldStamp;
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ProfiledType(jdk.vm.ci.meta.JavaTypeProfile.ProfiledType) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) AbstractObjectStamp(org.graalvm.compiler.core.common.type.AbstractObjectStamp) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) HostedType(com.oracle.svm.hosted.meta.HostedType) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference)

Example 10 with ObjectStamp

use of org.graalvm.compiler.core.common.type.ObjectStamp in project graal by oracle.

the class StrengthenStampsPhase method run.

@Override
protected void run(StructuredGraph graph) {
    for (Node n : graph.getNodes()) {
        if (n instanceof ValueNode && !(n instanceof LimitedValueProxy) && !(n instanceof PhiNode)) {
            /*
                 * The stamp of proxy nodes and phi nodes is inferred automatically, so we do not
                 * need to improve them.
                 */
            ValueNode node = (ValueNode) n;
            /*
                 * First ask the node to improve the stamp itself, to incorporate already improved
                 * input stamps.
                 */
            node.inferStamp();
            Stamp newStamp = strengthen(node.stamp(NodeView.DEFAULT));
            if (newStamp != null) {
                node.setStamp(newStamp);
            }
        }
        if (n instanceof LoadFieldNode) {
            LoadFieldNode node = (LoadFieldNode) n;
            updateStamp(node, toHosted(node.field()).getFieldTypeProfile());
        } else if (n instanceof InstanceOfNode) {
            InstanceOfNode node = (InstanceOfNode) n;
            ObjectStamp newStamp = (ObjectStamp) strengthen(node.getCheckedStamp());
            if (newStamp != null) {
                node.strengthenCheckedStamp(newStamp);
            }
        } else if (n instanceof PiNode) {
            PiNode node = (PiNode) n;
            Stamp newStamp = strengthen(node.piStamp());
            if (newStamp != null) {
                node.strengthenPiStamp(newStamp);
            }
        }
    }
}
Also used : PhiNode(org.graalvm.compiler.nodes.PhiNode) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) AbstractObjectStamp(org.graalvm.compiler.core.common.type.AbstractObjectStamp) Stamp(org.graalvm.compiler.core.common.type.Stamp) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) AbstractObjectStamp(org.graalvm.compiler.core.common.type.AbstractObjectStamp) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) AssertStampNode(com.oracle.svm.hosted.nodes.AssertStampNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) PiNode(org.graalvm.compiler.nodes.PiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) AssertTypeStateNode(com.oracle.svm.hosted.nodes.AssertTypeStateNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) PiNode(org.graalvm.compiler.nodes.PiNode) LimitedValueProxy(org.graalvm.compiler.nodes.spi.LimitedValueProxy) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode)

Aggregations

ObjectStamp (org.graalvm.compiler.core.common.type.ObjectStamp)31 ValueNode (org.graalvm.compiler.nodes.ValueNode)14 Stamp (org.graalvm.compiler.core.common.type.Stamp)12 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)10 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)8 Node (org.graalvm.compiler.graph.Node)6 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)6 ParameterNode (org.graalvm.compiler.nodes.ParameterNode)6 PiNode (org.graalvm.compiler.nodes.PiNode)6 TypeReference (org.graalvm.compiler.core.common.type.TypeReference)5 LogicNode (org.graalvm.compiler.nodes.LogicNode)5 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)4 JavaConstant (jdk.vm.ci.meta.JavaConstant)3 JavaType (jdk.vm.ci.meta.JavaType)3 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)3 LoadHubNode (org.graalvm.compiler.nodes.extended.LoadHubNode)3 LoadFieldNode (org.graalvm.compiler.nodes.java.LoadFieldNode)3 MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)3 HotSpotResolvedObjectType (jdk.vm.ci.hotspot.HotSpotResolvedObjectType)2 Constant (jdk.vm.ci.meta.Constant)2