Search in sources :

Example 1 with BoxNode

use of org.graalvm.compiler.nodes.extended.BoxNode in project graal by oracle.

the class TruffleGraphBuilderPlugins method registerCompilerDirectivesPlugins.

public static void registerCompilerDirectivesPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, boolean canDelayIntrinsification) {
    final ResolvedJavaType compilerDirectivesType = getRuntime().resolveType(metaAccess, "com.oracle.truffle.api.CompilerDirectives");
    Registration r = new Registration(plugins, new ResolvedJavaSymbol(compilerDirectivesType));
    r.register0("inInterpreter", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(false));
            return true;
        }
    });
    r.register0("inCompiledCode", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            return true;
        }
    });
    r.register0("inCompilationRoot", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            GraphBuilderContext.ExternalInliningContext inliningContext = b.getExternalInliningContext();
            if (inliningContext != null) {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(inliningContext.getInlinedDepth() == 0));
                return true;
            }
            return false;
        }
    });
    r.register0("transferToInterpreter", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter));
            return true;
        }
    });
    r.register0("transferToInterpreterAndInvalidate", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter));
            return true;
        }
    });
    r.register1("interpreterOnly", Runnable.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
            return true;
        }
    });
    r.register1("interpreterOnly", Callable.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
            return true;
        }
    });
    r.register2("injectBranchProbability", double.class, boolean.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode probability, ValueNode condition) {
            b.addPush(JavaKind.Boolean, new BranchProbabilityNode(probability, condition));
            return true;
        }
    });
    r.register1("bailout", String.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode message) {
            if (canDelayIntrinsification) {
                /*
                     * We do not want to bailout yet, since we are still parsing individual methods
                     * and constant folding could still eliminate the call to bailout(). However, we
                     * also want to stop parsing, since we are sure that we will never need the
                     * graph beyond the bailout point.
                     *
                     * Therefore, we manually emit the call to bailout, which will be intrinsified
                     * later when intrinsifications can no longer be delayed. The call is followed
                     * by a NeverPartOfCompilationNode, which is a control sink and therefore stops
                     * any further parsing.
                     */
                StampPair returnStamp = b.getInvokeReturnStamp(b.getAssumptions());
                CallTargetNode callTarget = b.add(new MethodCallTargetNode(InvokeKind.Static, targetMethod, new ValueNode[] { message }, returnStamp, null));
                b.add(new InvokeNode(callTarget, b.bci()));
                b.add(new NeverPartOfCompilationNode("intrinsification of call to bailout() will abort entire compilation"));
                return true;
            }
            if (message.isConstant()) {
                throw b.bailout(message.asConstant().toValueString());
            }
            throw b.bailout("bailout (message is not compile-time constant, so no additional information is available)");
        }
    });
    r.register1("isCompilationConstant", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            if ((value instanceof BoxNode ? ((BoxNode) value).getValue() : value).isConstant()) {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            } else {
                b.addPush(JavaKind.Boolean, new IsCompilationConstantNode(value));
            }
            return true;
        }
    });
    r.register1("isPartialEvaluationConstant", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            if ((value instanceof BoxNode ? ((BoxNode) value).getValue() : value).isConstant()) {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            } else if (canDelayIntrinsification) {
                return false;
            } else {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(false));
            }
            return true;
        }
    });
    r.register1("materialize", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            AllowMaterializeNode materializedValue = b.append(new AllowMaterializeNode(value));
            b.add(new ForceMaterializeNode(materializedValue));
            return true;
        }
    });
    r.register1("ensureVirtualized", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
            b.add(new EnsureVirtualizedNode(object, false));
            return true;
        }
    });
    r.register1("ensureVirtualizedHere", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
            b.add(new EnsureVirtualizedNode(object, true));
            return true;
        }
    });
    r.register2("castExact", Object.class, Class.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object, ValueNode javaClass) {
            ValueNode nullCheckedClass = b.addNonNullCast(javaClass);
            LogicNode condition = b.append(InstanceOfDynamicNode.create(b.getAssumptions(), b.getConstantReflection(), nullCheckedClass, object, true, true));
            if (condition.isTautology()) {
                b.addPush(JavaKind.Object, object);
            } else {
                FixedGuardNode fixedGuard = b.add(new FixedGuardNode(condition, DeoptimizationReason.ClassCastException, DeoptimizationAction.InvalidateReprofile, false));
                b.addPush(JavaKind.Object, DynamicPiNode.create(b.getAssumptions(), b.getConstantReflection(), object, fixedGuard, nullCheckedClass, true));
            }
            return true;
        }
    });
}
Also used : EnsureVirtualizedNode(org.graalvm.compiler.nodes.virtual.EnsureVirtualizedNode) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) BranchProbabilityNode(org.graalvm.compiler.nodes.extended.BranchProbabilityNode) AllowMaterializeNode(org.graalvm.compiler.truffle.compiler.nodes.frame.AllowMaterializeNode) ResolvedJavaSymbol(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.ResolvedJavaSymbol) NeverPartOfCompilationNode(org.graalvm.compiler.truffle.compiler.nodes.asserts.NeverPartOfCompilationNode) ForceMaterializeNode(org.graalvm.compiler.truffle.compiler.nodes.frame.ForceMaterializeNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) IsCompilationConstantNode(org.graalvm.compiler.truffle.compiler.nodes.IsCompilationConstantNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) ValueNode(org.graalvm.compiler.nodes.ValueNode) StampPair(org.graalvm.compiler.core.common.type.StampPair) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) InvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode)

Example 2 with BoxNode

use of org.graalvm.compiler.nodes.extended.BoxNode in project graal by oracle.

the class MethodTypeFlowBuilder method registerUsedElements.

public static void registerUsedElements(BigBang bb, StructuredGraph graph, MethodTypeFlow methodFlow) {
    for (Node n : graph.getNodes()) {
        if (n instanceof InstanceOfNode) {
            InstanceOfNode node = (InstanceOfNode) n;
            AnalysisType type = (AnalysisType) node.type().getType();
            type.registerAsInTypeCheck();
        } else if (n instanceof NewInstanceNode) {
            NewInstanceNode node = (NewInstanceNode) n;
            AnalysisType type = (AnalysisType) node.instanceClass();
            type.registerAsAllocated(node);
        } else if (n instanceof NewArrayNode) {
            NewArrayNode node = (NewArrayNode) n;
            AnalysisType type = ((AnalysisType) node.elementType()).getArrayClass();
            type.registerAsAllocated(node);
        } else if (n instanceof NewMultiArrayNode) {
            NewMultiArrayNode node = (NewMultiArrayNode) n;
            AnalysisType type = ((AnalysisType) node.type());
            for (int i = 0; i < node.dimensionCount(); i++) {
                type.registerAsAllocated(node);
                type = type.getComponentType();
            }
        } else if (n instanceof BoxNode) {
            BoxNode node = (BoxNode) n;
            AnalysisType type = (AnalysisType) StampTool.typeOrNull(node);
            type.registerAsAllocated(node);
        } else if (n instanceof LoadFieldNode) {
            LoadFieldNode node = (LoadFieldNode) n;
            AnalysisField field = (AnalysisField) node.field();
            field.registerAsRead(methodFlow);
        } else if (n instanceof StoreFieldNode) {
            StoreFieldNode node = (StoreFieldNode) n;
            AnalysisField field = (AnalysisField) node.field();
            field.registerAsWritten(methodFlow);
        } else if (n instanceof StoreIndexedNode) {
            StoreIndexedNode node = (StoreIndexedNode) n;
            AnalysisType arrayType = (AnalysisType) StampTool.typeOrNull(node.array());
            if (arrayType != null) {
                assert arrayType.isArray();
                arrayType.getComponentType().registerAsInTypeCheck();
            }
        } else if (n instanceof BytecodeExceptionNode) {
            BytecodeExceptionNode node = (BytecodeExceptionNode) n;
            AnalysisType type = bb.getMetaAccess().lookupJavaType(node.getExceptionClass());
            type.registerAsInHeap();
        } else if (n instanceof ConstantNode) {
            ConstantNode cn = (ConstantNode) n;
            if (cn.hasUsages() && cn.asJavaConstant().getJavaKind() == JavaKind.Object && cn.asJavaConstant().isNonNull()) {
                assert StampTool.isExactType(cn);
                AnalysisType type = (AnalysisType) StampTool.typeOrNull(cn);
                type.registerAsInHeap();
            }
        } else if (n instanceof ForeignCallNode) {
            ForeignCallNode node = (ForeignCallNode) n;
            registerForeignCall(bb, node.getDescriptor());
        } else if (n instanceof UnaryMathIntrinsicNode) {
            UnaryMathIntrinsicNode node = (UnaryMathIntrinsicNode) n;
            registerForeignCall(bb, node.getOperation().foreignCallDescriptor);
        } else if (n instanceof BinaryMathIntrinsicNode) {
            BinaryMathIntrinsicNode node = (BinaryMathIntrinsicNode) n;
            registerForeignCall(bb, node.getOperation().foreignCallDescriptor);
        }
    }
}
Also used : AnalysisType(com.oracle.graal.pointsto.meta.AnalysisType) StoreIndexedNode(org.graalvm.compiler.nodes.java.StoreIndexedNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) DynamicNewInstanceNode(org.graalvm.compiler.nodes.java.DynamicNewInstanceNode) DynamicNewArrayNode(org.graalvm.compiler.nodes.java.DynamicNewArrayNode) NewArrayNode(org.graalvm.compiler.nodes.java.NewArrayNode) UnaryMathIntrinsicNode(org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode) RawLoadNode(org.graalvm.compiler.nodes.extended.RawLoadNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) WordCastNode(org.graalvm.compiler.word.WordCastNode) DynamicNewArrayNode(org.graalvm.compiler.nodes.java.DynamicNewArrayNode) ObjectEqualsNode(org.graalvm.compiler.nodes.calc.ObjectEqualsNode) BasicObjectCloneNode(org.graalvm.compiler.replacements.nodes.BasicObjectCloneNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) AtomicReadAndWriteNode(org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode) ConvertUnknownValueNode(com.oracle.graal.pointsto.nodes.ConvertUnknownValueNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) AnalysisUnsafePartitionLoadNode(com.oracle.graal.pointsto.nodes.AnalysisUnsafePartitionLoadNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) ForeignCallNode(org.graalvm.compiler.nodes.extended.ForeignCallNode) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) AnalysisArraysCopyOfNode(com.oracle.graal.pointsto.nodes.AnalysisArraysCopyOfNode) DynamicNewInstanceNode(org.graalvm.compiler.nodes.java.DynamicNewInstanceNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) NewMultiArrayNode(org.graalvm.compiler.nodes.java.NewMultiArrayNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) BinaryMathIntrinsicNode(org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode) IfNode(org.graalvm.compiler.nodes.IfNode) RawStoreNode(org.graalvm.compiler.nodes.extended.RawStoreNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) NewArrayNode(org.graalvm.compiler.nodes.java.NewArrayNode) UnsafeCompareAndSwapNode(org.graalvm.compiler.nodes.java.UnsafeCompareAndSwapNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode) BasicArrayCopyNode(org.graalvm.compiler.replacements.nodes.BasicArrayCopyNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) UnaryMathIntrinsicNode(org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode) StoreIndexedNode(org.graalvm.compiler.nodes.java.StoreIndexedNode) MonitorEnterNode(org.graalvm.compiler.nodes.java.MonitorEnterNode) GetClassNode(org.graalvm.compiler.nodes.extended.GetClassNode) BytecodeExceptionNode(org.graalvm.compiler.nodes.extended.BytecodeExceptionNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) AnalysisUnsafePartitionStoreNode(com.oracle.graal.pointsto.nodes.AnalysisUnsafePartitionStoreNode) BytecodeExceptionNode(org.graalvm.compiler.nodes.extended.BytecodeExceptionNode) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) AnalysisField(com.oracle.graal.pointsto.meta.AnalysisField) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) BinaryMathIntrinsicNode(org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ForeignCallNode(org.graalvm.compiler.nodes.extended.ForeignCallNode) NewMultiArrayNode(org.graalvm.compiler.nodes.java.NewMultiArrayNode) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode)

Example 3 with BoxNode

use of org.graalvm.compiler.nodes.extended.BoxNode in project graal by oracle.

the class TruffleGraphBuilderPlugins method registerCompilerAssertsPlugins.

public static void registerCompilerAssertsPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, boolean canDelayIntrinsification) {
    final ResolvedJavaType compilerAssertsType = getRuntime().resolveType(metaAccess, "com.oracle.truffle.api.CompilerAsserts");
    Registration r = new Registration(plugins, new ResolvedJavaSymbol(compilerAssertsType));
    r.register1("partialEvaluationConstant", Object.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            ValueNode curValue = value;
            if (curValue instanceof BoxNode) {
                BoxNode boxNode = (BoxNode) curValue;
                curValue = boxNode.getValue();
            }
            if (curValue.isConstant()) {
                return true;
            } else if (canDelayIntrinsification) {
                return false;
            } else {
                StringBuilder sb = new StringBuilder();
                sb.append(curValue);
                if (curValue instanceof ValuePhiNode) {
                    ValuePhiNode valuePhi = (ValuePhiNode) curValue;
                    sb.append(" (");
                    for (Node n : valuePhi.inputs()) {
                        sb.append(n);
                        sb.append("; ");
                    }
                    sb.append(")");
                }
                value.getDebug().dump(DebugContext.VERBOSE_LEVEL, value.graph(), "Graph before bailout at node %s", sb);
                throw b.bailout("Partial evaluation did not reduce value to a constant, is a regular compiler node: " + sb);
            }
        }
    });
    r.register0("neverPartOfCompilation", new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new NeverPartOfCompilationNode("CompilerAsserts.neverPartOfCompilation()"));
            return true;
        }
    });
    r.register1("neverPartOfCompilation", String.class, new InvocationPlugin() {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode message) {
            if (message.isConstant()) {
                String messageString = message.asConstant().toValueString();
                b.add(new NeverPartOfCompilationNode(messageString));
                return true;
            } else {
                throw b.bailout("message for never part of compilation is non-constant");
            }
        }
    });
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) RawLoadNode(org.graalvm.compiler.nodes.extended.RawLoadNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) ForceMaterializeNode(org.graalvm.compiler.truffle.compiler.nodes.frame.ForceMaterializeNode) DynamicPiNode(org.graalvm.compiler.nodes.DynamicPiNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode) EnsureVirtualizedNode(org.graalvm.compiler.nodes.virtual.EnsureVirtualizedNode) VirtualFrameIsNode(org.graalvm.compiler.truffle.compiler.nodes.frame.VirtualFrameIsNode) RawStoreNode(org.graalvm.compiler.nodes.extended.RawStoreNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) PiNode(org.graalvm.compiler.nodes.PiNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) NewFrameNode(org.graalvm.compiler.truffle.compiler.nodes.frame.NewFrameNode) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) UnsafeAccessNode(org.graalvm.compiler.nodes.extended.UnsafeAccessNode) AllowMaterializeNode(org.graalvm.compiler.truffle.compiler.nodes.frame.AllowMaterializeNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) BranchProbabilityNode(org.graalvm.compiler.nodes.extended.BranchProbabilityNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ConditionAnchorNode(org.graalvm.compiler.nodes.ConditionAnchorNode) InstanceOfDynamicNode(org.graalvm.compiler.nodes.java.InstanceOfDynamicNode) UnsignedMulHighNode(org.graalvm.compiler.replacements.nodes.arithmetic.UnsignedMulHighNode) VirtualFrameGetNode(org.graalvm.compiler.truffle.compiler.nodes.frame.VirtualFrameGetNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) GuardedUnsafeLoadNode(org.graalvm.compiler.nodes.extended.GuardedUnsafeLoadNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) NeverPartOfCompilationNode(org.graalvm.compiler.truffle.compiler.nodes.asserts.NeverPartOfCompilationNode) PiArrayNode(org.graalvm.compiler.nodes.PiArrayNode) VirtualFrameSetNode(org.graalvm.compiler.truffle.compiler.nodes.frame.VirtualFrameSetNode) IntegerMulHighNode(org.graalvm.compiler.replacements.nodes.arithmetic.IntegerMulHighNode) Node(org.graalvm.compiler.graph.Node) IsCompilationConstantNode(org.graalvm.compiler.truffle.compiler.nodes.IsCompilationConstantNode) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) ResolvedJavaSymbol(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.ResolvedJavaSymbol) NeverPartOfCompilationNode(org.graalvm.compiler.truffle.compiler.nodes.asserts.NeverPartOfCompilationNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) ValueNode(org.graalvm.compiler.nodes.ValueNode) InvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 4 with BoxNode

use of org.graalvm.compiler.nodes.extended.BoxNode in project graal by oracle.

the class MethodTypeFlowBuilder method apply.

protected void apply() {
    // assert method.getAnnotation(Fold.class) == null : method;
    if (method.getAnnotation(NodeIntrinsic.class) != null) {
        graph.getDebug().log("apply MethodTypeFlow on node intrinsic %s", method);
        AnalysisType returnType = (AnalysisType) method.getSignature().getReturnType(method.getDeclaringClass());
        if (returnType.getJavaKind() == JavaKind.Object) {
            /*
                 * This is a method used in a snippet, so most likely the return value does not
                 * matter at all. However, some methods return an object, and the snippet continues
                 * to work with the object. So pretend that this method returns an object of the
                 * exact return type.
                 */
            TypeFlow<?> returnTypeFlow = methodFlow.getResultFlow().getDeclaredType().getTypeFlow(this.bb, true);
            returnTypeFlow = new ProxyTypeFlow(null, returnTypeFlow);
            FormalReturnTypeFlow resultFlow = new FormalReturnTypeFlow(null, returnType, method);
            returnTypeFlow.addOriginalUse(this.bb, resultFlow);
            methodFlow.addMiscEntry(returnTypeFlow);
            methodFlow.setResult(resultFlow);
        }
        return;
    }
    if (!parse()) {
        return;
    }
    this.bb.getUnsupportedFeatures().checkMethod(method, graph);
    processedNodes = new NodeBitMap(graph);
    TypeFlowsOfNodes typeFlows = new TypeFlowsOfNodes();
    for (Node n : graph.getNodes()) {
        if (n instanceof ParameterNode) {
            ParameterNode node = (ParameterNode) n;
            if (node.getStackKind() == JavaKind.Object) {
                TypeFlowBuilder<?> paramBuilder = TypeFlowBuilder.create(bb, node, FormalParamTypeFlow.class, () -> {
                    boolean isStatic = Modifier.isStatic(method.getModifiers());
                    int index = node.index();
                    FormalParamTypeFlow parameter;
                    if (!isStatic && index == 0) {
                        AnalysisType paramType = method.getDeclaringClass();
                        parameter = new FormalReceiverTypeFlow(node, paramType, method);
                    } else {
                        int offset = isStatic ? 0 : 1;
                        AnalysisType paramType = (AnalysisType) method.getSignature().getParameterType(index - offset, method.getDeclaringClass());
                        parameter = new FormalParamTypeFlow(node, paramType, method, index);
                    }
                    methodFlow.setParameter(index, parameter);
                    return parameter;
                });
                typeFlowGraphBuilder.checkFormalParameterBuilder(paramBuilder);
                typeFlows.add(node, paramBuilder);
            }
        } else if (n instanceof BoxNode) {
            BoxNode node = (BoxNode) n;
            Object key = uniqueKey(node);
            BytecodeLocation boxSite = bb.analysisPolicy().createAllocationSite(bb, key, methodFlow.getMethod());
            AnalysisType type = (AnalysisType) StampTool.typeOrNull(node);
            TypeFlowBuilder<?> boxBuilder = TypeFlowBuilder.create(bb, node, BoxTypeFlow.class, () -> {
                BoxTypeFlow boxFlow = new BoxTypeFlow(node, type, boxSite);
                methodFlow.addAllocation(boxFlow);
                return boxFlow;
            });
            typeFlows.add(node, boxBuilder);
        }
        for (Node input : n.inputs()) {
            /*
                 * TODO change the handling of constants so that the SourceTypeFlow is created on
                 * demand, with the optimization that only one SourceTypeFlow is created ever for
                 * every distinct object (using, e.g., caching in a global IdentityHashMap).
                 */
            if (input instanceof ConstantNode && !typeFlows.contains((ConstantNode) input)) {
                ConstantNode node = (ConstantNode) input;
                if (node.asJavaConstant().isNull()) {
                    TypeFlowBuilder<SourceTypeFlow> sourceBuilder = TypeFlowBuilder.create(bb, node, SourceTypeFlow.class, () -> {
                        SourceTypeFlow constantSource = new SourceTypeFlow(node, TypeState.forNull());
                        methodFlow.addSource(constantSource);
                        return constantSource;
                    });
                    typeFlows.add(node, sourceBuilder);
                } else if (node.asJavaConstant().getJavaKind() == JavaKind.Object) {
                    /*
                         * TODO a SubstrateObjectConstant wrapping a PrimitiveConstant has kind
                         * equals to Object. Do we care about the effective value of these primitive
                         * constants in the analysis?
                         */
                    assert StampTool.isExactType(node);
                    AnalysisType type = (AnalysisType) StampTool.typeOrNull(node);
                    assert type.isInstantiated();
                    TypeFlowBuilder<SourceTypeFlow> sourceBuilder = TypeFlowBuilder.create(bb, node, SourceTypeFlow.class, () -> {
                        SourceTypeFlow constantSource = new SourceTypeFlow(node, TypeState.forConstant(this.bb, node.asJavaConstant(), type));
                        methodFlow.addSource(constantSource);
                        return constantSource;
                    });
                    typeFlows.add(node, sourceBuilder);
                }
            }
        }
    }
    // Propagate the type flows through the method's graph
    new NodeIterator(graph.start(), typeFlows).apply();
    /* Prune the method graph. Eliminate nodes with no uses. */
    typeFlowGraphBuilder.build();
    /*
         * Make sure that all existing InstanceOfNodes are registered even when only used as an
         * input of a conditional.
         */
    for (Node n : graph.getNodes()) {
        if (n instanceof InstanceOfNode) {
            InstanceOfNode instanceOf = (InstanceOfNode) n;
            markFieldsUsedInComparison(instanceOf.getValue());
        } else if (n instanceof ObjectEqualsNode) {
            ObjectEqualsNode compareNode = (ObjectEqualsNode) n;
            markFieldsUsedInComparison(compareNode.getX());
            markFieldsUsedInComparison(compareNode.getY());
        }
    }
}
Also used : AnalysisType(com.oracle.graal.pointsto.meta.AnalysisType) TypeFlowBuilder(com.oracle.graal.pointsto.flow.builder.TypeFlowBuilder) RawLoadNode(org.graalvm.compiler.nodes.extended.RawLoadNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) WordCastNode(org.graalvm.compiler.word.WordCastNode) DynamicNewArrayNode(org.graalvm.compiler.nodes.java.DynamicNewArrayNode) ObjectEqualsNode(org.graalvm.compiler.nodes.calc.ObjectEqualsNode) BasicObjectCloneNode(org.graalvm.compiler.replacements.nodes.BasicObjectCloneNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) AtomicReadAndWriteNode(org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode) ConvertUnknownValueNode(com.oracle.graal.pointsto.nodes.ConvertUnknownValueNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) AnalysisUnsafePartitionLoadNode(com.oracle.graal.pointsto.nodes.AnalysisUnsafePartitionLoadNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) ForeignCallNode(org.graalvm.compiler.nodes.extended.ForeignCallNode) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) AnalysisArraysCopyOfNode(com.oracle.graal.pointsto.nodes.AnalysisArraysCopyOfNode) DynamicNewInstanceNode(org.graalvm.compiler.nodes.java.DynamicNewInstanceNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) NewMultiArrayNode(org.graalvm.compiler.nodes.java.NewMultiArrayNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) BinaryMathIntrinsicNode(org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode) IfNode(org.graalvm.compiler.nodes.IfNode) RawStoreNode(org.graalvm.compiler.nodes.extended.RawStoreNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) NewArrayNode(org.graalvm.compiler.nodes.java.NewArrayNode) UnsafeCompareAndSwapNode(org.graalvm.compiler.nodes.java.UnsafeCompareAndSwapNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode) BasicArrayCopyNode(org.graalvm.compiler.replacements.nodes.BasicArrayCopyNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) UnaryMathIntrinsicNode(org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode) StoreIndexedNode(org.graalvm.compiler.nodes.java.StoreIndexedNode) MonitorEnterNode(org.graalvm.compiler.nodes.java.MonitorEnterNode) GetClassNode(org.graalvm.compiler.nodes.extended.GetClassNode) BytecodeExceptionNode(org.graalvm.compiler.nodes.extended.BytecodeExceptionNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) AnalysisUnsafePartitionStoreNode(com.oracle.graal.pointsto.nodes.AnalysisUnsafePartitionStoreNode) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) BytecodeLocation(com.oracle.graal.pointsto.flow.context.BytecodeLocation) NodeIntrinsic(org.graalvm.compiler.graph.Node.NodeIntrinsic) PostOrderNodeIterator(org.graalvm.compiler.phases.graph.PostOrderNodeIterator) NodeBitMap(org.graalvm.compiler.graph.NodeBitMap) ObjectEqualsNode(org.graalvm.compiler.nodes.calc.ObjectEqualsNode) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode)

Aggregations

FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)4 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)4 LogicNode (org.graalvm.compiler.nodes.LogicNode)4 ValueNode (org.graalvm.compiler.nodes.ValueNode)4 BoxNode (org.graalvm.compiler.nodes.extended.BoxNode)4 MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)4 Node (org.graalvm.compiler.graph.Node)3 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)3 RawLoadNode (org.graalvm.compiler.nodes.extended.RawLoadNode)3 RawStoreNode (org.graalvm.compiler.nodes.extended.RawStoreNode)3 AnalysisType (com.oracle.graal.pointsto.meta.AnalysisType)2 AnalysisArraysCopyOfNode (com.oracle.graal.pointsto.nodes.AnalysisArraysCopyOfNode)2 AnalysisUnsafePartitionLoadNode (com.oracle.graal.pointsto.nodes.AnalysisUnsafePartitionLoadNode)2 AnalysisUnsafePartitionStoreNode (com.oracle.graal.pointsto.nodes.AnalysisUnsafePartitionStoreNode)2 ConvertUnknownValueNode (com.oracle.graal.pointsto.nodes.ConvertUnknownValueNode)2 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)2 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)2 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)2 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)2 BeginNode (org.graalvm.compiler.nodes.BeginNode)2