Search in sources :

Example 26 with ObjectStamp

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

the class InstanceOfNode method tryFold.

@Override
public TriState tryFold(Stamp valueStamp) {
    if (valueStamp instanceof ObjectStamp) {
        ObjectStamp inputStamp = (ObjectStamp) valueStamp;
        ObjectStamp joinedStamp = (ObjectStamp) checkedStamp.join(inputStamp);
        if (joinedStamp.isEmpty()) {
            // The check can never succeed, the intersection of the two stamps is empty.
            return TriState.FALSE;
        } else {
            ObjectStamp meetStamp = (ObjectStamp) checkedStamp.meet(inputStamp);
            if (checkedStamp.equals(meetStamp)) {
                // checked stamp.
                return TriState.TRUE;
            }
        }
    }
    return TriState.UNKNOWN;
}
Also used : ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp)

Example 27 with ObjectStamp

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

the class InstanceOfNode method findSynonym.

public static LogicNode findSynonym(ObjectStamp checkedStamp, ValueNode object, NodeView view) {
    ObjectStamp inputStamp = (ObjectStamp) object.stamp(view);
    ObjectStamp joinedStamp = (ObjectStamp) checkedStamp.join(inputStamp);
    if (joinedStamp.isEmpty()) {
        // The check can never succeed, the intersection of the two stamps is empty.
        return LogicConstantNode.contradiction();
    } else {
        ObjectStamp meetStamp = (ObjectStamp) checkedStamp.meet(inputStamp);
        if (checkedStamp.equals(meetStamp)) {
            // checked stamp.
            return LogicConstantNode.tautology();
        } else if (checkedStamp.alwaysNull()) {
            return IsNullNode.create(object);
        } else if (Objects.equals(checkedStamp.type(), meetStamp.type()) && checkedStamp.isExactType() == meetStamp.isExactType() && checkedStamp.alwaysNull() == meetStamp.alwaysNull()) {
            assert checkedStamp.nonNull() != inputStamp.nonNull();
            // The only difference makes the null-ness of the value => simplify the check.
            if (checkedStamp.nonNull()) {
                return LogicNegationNode.create(IsNullNode.create(object));
            } else {
                return IsNullNode.create(object);
            }
        }
        assert checkedStamp.type() != null;
    }
    return null;
}
Also used : ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp)

Example 28 with ObjectStamp

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

the class TypeSwitchNode method simplify.

@Override
public void simplify(SimplifierTool tool) {
    NodeView view = NodeView.from(tool);
    if (value() instanceof ConstantNode) {
        Constant constant = value().asConstant();
        int survivingEdge = keySuccessorIndex(keyCount());
        for (int i = 0; i < keyCount(); i++) {
            Constant typeHub = keyAt(i);
            Boolean equal = tool.getConstantReflection().constantEquals(constant, typeHub);
            if (equal == null) {
                /* We don't know if this key is a match or not, so we cannot simplify. */
                return;
            } else if (equal.booleanValue()) {
                survivingEdge = keySuccessorIndex(i);
            }
        }
        killOtherSuccessors(tool, survivingEdge);
    }
    if (value() instanceof LoadHubNode && ((LoadHubNode) value()).getValue().stamp(view) instanceof ObjectStamp) {
        ObjectStamp objectStamp = (ObjectStamp) ((LoadHubNode) value()).getValue().stamp(view);
        if (objectStamp.type() != null) {
            int validKeys = 0;
            for (int i = 0; i < keyCount(); i++) {
                if (objectStamp.type().isAssignableFrom(keys[i])) {
                    validKeys++;
                }
            }
            if (validKeys == 0) {
                tool.addToWorkList(defaultSuccessor());
                graph().removeSplitPropagate(this, defaultSuccessor());
            } else if (validKeys != keys.length) {
                ArrayList<AbstractBeginNode> newSuccessors = new ArrayList<>(blockSuccessorCount());
                ResolvedJavaType[] newKeys = new ResolvedJavaType[validKeys];
                int[] newKeySuccessors = new int[validKeys + 1];
                double[] newKeyProbabilities = new double[validKeys + 1];
                double totalProbability = 0;
                int current = 0;
                for (int i = 0; i < keyCount() + 1; i++) {
                    if (i == keyCount() || objectStamp.type().isAssignableFrom(keys[i])) {
                        int index = newSuccessors.indexOf(keySuccessor(i));
                        if (index == -1) {
                            index = newSuccessors.size();
                            newSuccessors.add(keySuccessor(i));
                        }
                        newKeySuccessors[current] = index;
                        if (i < keyCount()) {
                            newKeys[current] = keys[i];
                        }
                        newKeyProbabilities[current] = keyProbability(i);
                        totalProbability += keyProbability(i);
                        current++;
                    }
                }
                if (totalProbability > 0) {
                    for (int i = 0; i < current; i++) {
                        newKeyProbabilities[i] /= totalProbability;
                    }
                } else {
                    for (int i = 0; i < current; i++) {
                        newKeyProbabilities[i] = 1.0 / current;
                    }
                }
                for (int i = 0; i < blockSuccessorCount(); i++) {
                    AbstractBeginNode successor = blockSuccessor(i);
                    if (!newSuccessors.contains(successor)) {
                        tool.deleteBranch(successor);
                    }
                    setBlockSuccessor(i, null);
                }
                AbstractBeginNode[] successorsArray = newSuccessors.toArray(new AbstractBeginNode[newSuccessors.size()]);
                TypeSwitchNode newSwitch = graph().add(new TypeSwitchNode(value(), successorsArray, newKeys, newKeyProbabilities, newKeySuccessors, tool.getConstantReflection()));
                ((FixedWithNextNode) predecessor()).setNext(newSwitch);
                GraphUtil.killWithUnusedFloatingInputs(this);
            }
        }
    }
}
Also used : ConstantNode(org.graalvm.compiler.nodes.ConstantNode) LoadHubNode(org.graalvm.compiler.nodes.extended.LoadHubNode) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) Constant(jdk.vm.ci.meta.Constant) ArrayList(java.util.ArrayList) NodeView(org.graalvm.compiler.nodes.NodeView) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 29 with ObjectStamp

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

the class VerifyUsageWithEquals method isAssignableToRestrictedType.

/**
 * Determines whether the type of {@code node} is assignable to the {@link #restrictedClass}.
 */
private boolean isAssignableToRestrictedType(ValueNode node, MetaAccessProvider metaAccess) {
    if (node.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
        ResolvedJavaType restrictedType = metaAccess.lookupJavaType(restrictedClass);
        ResolvedJavaType nodeType = StampTool.typeOrNull(node);
        if (nodeType == null && node instanceof LoadFieldNode) {
            nodeType = (ResolvedJavaType) ((LoadFieldNode) node).field().getType();
        }
        if (nodeType == null && node instanceof Invoke) {
            ResolvedJavaMethod target = ((Invoke) node).callTarget().targetMethod();
            nodeType = (ResolvedJavaType) target.getSignature().getReturnType(target.getDeclaringClass());
        }
        if (nodeType == null && node instanceof UncheckedInterfaceProvider) {
            nodeType = StampTool.typeOrNull(((UncheckedInterfaceProvider) node).uncheckedStamp());
        }
        if (nodeType != null && restrictedType.isAssignableFrom(nodeType)) {
            return true;
        }
    }
    return false;
}
Also used : ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) UncheckedInterfaceProvider(org.graalvm.compiler.nodes.spi.UncheckedInterfaceProvider) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) Invoke(org.graalvm.compiler.nodes.Invoke)

Example 30 with ObjectStamp

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

the class InliningData method getInlineInfo.

/**
 * Determines if inlining is possible at the given invoke node.
 *
 * @param invoke the invoke that should be inlined
 * @return an instance of InlineInfo, or null if no inlining is possible at the given invoke
 */
private InlineInfo getInlineInfo(Invoke invoke) {
    final String failureMessage = InliningUtil.checkInvokeConditions(invoke);
    if (failureMessage != null) {
        InliningUtil.logNotInlinedMethod(invoke, failureMessage);
        return null;
    }
    MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
    ResolvedJavaMethod targetMethod = callTarget.targetMethod();
    if (callTarget.invokeKind() == CallTargetNode.InvokeKind.Special || targetMethod.canBeStaticallyBound()) {
        return getExactInlineInfo(invoke, targetMethod);
    }
    assert callTarget.invokeKind().isIndirect();
    ResolvedJavaType holder = targetMethod.getDeclaringClass();
    if (!(callTarget.receiver().stamp(NodeView.DEFAULT) instanceof ObjectStamp)) {
        return null;
    }
    ObjectStamp receiverStamp = (ObjectStamp) callTarget.receiver().stamp(NodeView.DEFAULT);
    if (receiverStamp.alwaysNull()) {
        // Don't inline if receiver is known to be null
        return null;
    }
    ResolvedJavaType contextType = invoke.getContextType();
    if (receiverStamp.type() != null) {
        // the invoke target might be more specific than the holder (happens after inlining:
        // parameters lose their declared type...)
        ResolvedJavaType receiverType = receiverStamp.type();
        if (receiverType != null && holder.isAssignableFrom(receiverType)) {
            holder = receiverType;
            if (receiverStamp.isExactType()) {
                assert targetMethod.getDeclaringClass().isAssignableFrom(holder) : holder + " subtype of " + targetMethod.getDeclaringClass() + " for " + targetMethod;
                ResolvedJavaMethod resolvedMethod = holder.resolveConcreteMethod(targetMethod, contextType);
                if (resolvedMethod != null) {
                    return getExactInlineInfo(invoke, resolvedMethod);
                }
            }
        }
    }
    if (holder.isArray()) {
        // arrays can be treated as Objects
        ResolvedJavaMethod resolvedMethod = holder.resolveConcreteMethod(targetMethod, contextType);
        if (resolvedMethod != null) {
            return getExactInlineInfo(invoke, resolvedMethod);
        }
    }
    AssumptionResult<ResolvedJavaType> leafConcreteSubtype = holder.findLeafConcreteSubtype();
    if (leafConcreteSubtype != null) {
        ResolvedJavaMethod resolvedMethod = leafConcreteSubtype.getResult().resolveConcreteMethod(targetMethod, contextType);
        if (resolvedMethod != null) {
            if (leafConcreteSubtype.canRecordTo(callTarget.graph().getAssumptions())) {
                return getAssumptionInlineInfo(invoke, resolvedMethod, leafConcreteSubtype);
            } else {
                return getTypeCheckedAssumptionInfo(invoke, resolvedMethod, leafConcreteSubtype.getResult());
            }
        }
    }
    AssumptionResult<ResolvedJavaMethod> concrete = holder.findUniqueConcreteMethod(targetMethod);
    if (concrete != null && concrete.canRecordTo(callTarget.graph().getAssumptions())) {
        return getAssumptionInlineInfo(invoke, concrete.getResult(), concrete);
    }
    // type check based inlining
    return getTypeCheckedInlineInfo(invoke, targetMethod);
}
Also used : MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

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