Search in sources :

Example 36 with FixedWithNextNode

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

the class AMD64NodeLIRBuilder method peephole.

@Override
protected boolean peephole(ValueNode valueNode) {
    if (valueNode instanceof IntegerDivRemNode) {
        AMD64ArithmeticLIRGenerator arithmeticGen = (AMD64ArithmeticLIRGenerator) gen.getArithmetic();
        IntegerDivRemNode divRem = (IntegerDivRemNode) valueNode;
        FixedNode node = divRem.next();
        while (true) {
            if (node instanceof IfNode) {
                IfNode ifNode = (IfNode) node;
                double probability = ifNode.getTrueSuccessorProbability();
                if (probability == 1.0) {
                    node = ifNode.trueSuccessor();
                } else if (probability == 0.0) {
                    node = ifNode.falseSuccessor();
                } else {
                    break;
                }
            } else if (!(node instanceof FixedWithNextNode)) {
                break;
            }
            FixedWithNextNode fixedWithNextNode = (FixedWithNextNode) node;
            if (fixedWithNextNode instanceof IntegerDivRemNode) {
                IntegerDivRemNode otherDivRem = (IntegerDivRemNode) fixedWithNextNode;
                if (divRem.getOp() != otherDivRem.getOp() && divRem.getType() == otherDivRem.getType()) {
                    if (otherDivRem.getX() == divRem.getX() && otherDivRem.getY() == divRem.getY() && !hasOperand(otherDivRem)) {
                        Value[] results;
                        switch(divRem.getType()) {
                            case SIGNED:
                                results = arithmeticGen.emitSignedDivRem(operand(divRem.getX()), operand(divRem.getY()), state((DeoptimizingNode) valueNode));
                                break;
                            case UNSIGNED:
                                results = arithmeticGen.emitUnsignedDivRem(operand(divRem.getX()), operand(divRem.getY()), state((DeoptimizingNode) valueNode));
                                break;
                            default:
                                throw GraalError.shouldNotReachHere();
                        }
                        switch(divRem.getOp()) {
                            case DIV:
                                assert otherDivRem.getOp() == Op.REM;
                                setResult(divRem, results[0]);
                                setResult(otherDivRem, results[1]);
                                break;
                            case REM:
                                assert otherDivRem.getOp() == Op.DIV;
                                setResult(divRem, results[1]);
                                setResult(otherDivRem, results[0]);
                                break;
                            default:
                                throw GraalError.shouldNotReachHere();
                        }
                        return true;
                    }
                }
            }
            node = fixedWithNextNode.next();
        }
    }
    return false;
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) IntegerDivRemNode(org.graalvm.compiler.nodes.calc.IntegerDivRemNode) Value(jdk.vm.ci.meta.Value) AllocatableValue(jdk.vm.ci.meta.AllocatableValue) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode)

Example 37 with FixedWithNextNode

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

the class BytecodeParser method guardIntrinsic.

/**
 * Weaves a test of the receiver type to ensure the dispatch will select {@code targetMethod}
 * and not another method that overrides it. This should only be called if there is an intrinsic
 * (i.e., an {@link InvocationPlugin}) for {@code targetMethod} and the invocation is indirect.
 *
 * The control flow woven around the intrinsic is as follows:
 *
 * <pre>
 *  if (LoadMethod(LoadHub(receiver)) == targetMethod) {
 *       <intrinsic for targetMethod>
 *  } else {
 *       <virtual call to targetMethod>
 *  }
 * </pre>
 *
 * The {@code else} branch is woven by {@link #afterInvocationPluginExecution}.
 *
 * @return {@code null} if the intrinsic cannot be used otherwise an object to be used by
 *         {@link #afterInvocationPluginExecution} to weave code for the non-intrinsic branch
 */
protected IntrinsicGuard guardIntrinsic(ValueNode[] args, ResolvedJavaMethod targetMethod, InvocationPluginReceiver pluginReceiver) {
    ValueNode intrinsicReceiver = args[0];
    ResolvedJavaType receiverType = StampTool.typeOrNull(intrinsicReceiver);
    if (receiverType == null) {
        // The verifier guarantees it to be at least type declaring targetMethod
        receiverType = targetMethod.getDeclaringClass();
    }
    ResolvedJavaMethod resolvedMethod = receiverType.resolveMethod(targetMethod, method.getDeclaringClass());
    if (resolvedMethod == null || resolvedMethod.equals(targetMethod)) {
        assert resolvedMethod == null || targetMethod.getDeclaringClass().isAssignableFrom(resolvedMethod.getDeclaringClass());
        Mark mark = graph.getMark();
        FixedWithNextNode currentLastInstr = lastInstr;
        ValueNode nonNullReceiver = pluginReceiver.get();
        Stamp methodStamp = stampProvider.createMethodStamp();
        LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver));
        LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub));
        ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess()));
        LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, CanonicalCondition.EQ, actual, expected, NodeView.DEFAULT));
        JavaTypeProfile profile = null;
        if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
            profile = profilingInfo.getTypeProfile(bci());
            if (profile != null) {
                JavaTypeProfile newProfile = adjustProfileForInvocationPlugin(profile, targetMethod);
                if (newProfile != profile) {
                    if (newProfile.getTypes().length == 0) {
                        // All profiled types select the intrinsic so
                        // emit a fixed guard instead of an if-then-else.
                        lastInstr = append(new FixedGuardNode(compare, TypeCheckedInliningViolated, InvalidateReprofile, false));
                        return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, null, null);
                    }
                } else {
                    // No profiled types select the intrinsic so emit a virtual call
                    return null;
                }
                profile = newProfile;
            }
        }
        AbstractBeginNode intrinsicBranch = graph.add(new BeginNode());
        AbstractBeginNode nonIntrinsicBranch = graph.add(new BeginNode());
        append(new IfNode(compare, intrinsicBranch, nonIntrinsicBranch, FAST_PATH_PROBABILITY));
        lastInstr = intrinsicBranch;
        return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, nonIntrinsicBranch, profile);
    } else {
        // Receiver selects an overriding method so emit a virtual call
        return null;
    }
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) LoadHubNode(org.graalvm.compiler.nodes.extended.LoadHubNode) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) Stamp(org.graalvm.compiler.core.common.type.Stamp) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) Mark(org.graalvm.compiler.graph.Graph.Mark) IfNode(org.graalvm.compiler.nodes.IfNode) LoadMethodNode(org.graalvm.compiler.nodes.extended.LoadMethodNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) JavaTypeProfile(jdk.vm.ci.meta.JavaTypeProfile) ValueNode(org.graalvm.compiler.nodes.ValueNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 38 with FixedWithNextNode

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

the class CheckcastArrayCopyCallNode method computeBase.

private ValueNode computeBase(ValueNode base, ValueNode pos) {
    FixedWithNextNode basePtr = graph().add(new GetObjectAddressNode(base));
    graph().addBeforeFixed(this, basePtr);
    int shift = CodeUtil.log2(getArrayIndexScale(JavaKind.Object));
    ValueNode extendedPos = IntegerConvertNode.convert(pos, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph(), NodeView.DEFAULT);
    ValueNode scaledIndex = graph().unique(new LeftShiftNode(extendedPos, ConstantNode.forInt(shift, graph())));
    ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forIntegerBits(PrimitiveStamp.getBits(scaledIndex.stamp(NodeView.DEFAULT)), getArrayBaseOffset(JavaKind.Object), graph())));
    return graph().unique(new OffsetAddressNode(basePtr, offset));
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) OffsetAddressNode(org.graalvm.compiler.nodes.memory.address.OffsetAddressNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LeftShiftNode(org.graalvm.compiler.nodes.calc.LeftShiftNode) AddNode(org.graalvm.compiler.nodes.calc.AddNode) GetObjectAddressNode(org.graalvm.compiler.hotspot.nodes.GetObjectAddressNode) AbstractMemoryCheckpoint(org.graalvm.compiler.nodes.memory.AbstractMemoryCheckpoint) MemoryCheckpoint(org.graalvm.compiler.nodes.memory.MemoryCheckpoint)

Example 39 with FixedWithNextNode

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

the class ControlFlowGraph method identifyBlock.

private void identifyBlock(Block block) {
    FixedWithNextNode cur = block.getBeginNode();
    while (true) {
        assert !cur.isDeleted();
        assert nodeToBlock.get(cur) == null;
        nodeToBlock.set(cur, block);
        FixedNode next = cur.next();
        if (next instanceof AbstractBeginNode) {
            block.endNode = cur;
            return;
        } else if (next instanceof FixedWithNextNode) {
            cur = (FixedWithNextNode) next;
        } else {
            nodeToBlock.set(next, block);
            block.endNode = next;
            return;
        }
    }
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 40 with FixedWithNextNode

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

the class ReplaceConstantNodesPhase method handleLoadMethodCounters.

/**
 * Replace {@link LoadMethodCountersNode} with indirect load
 * {@link ResolveMethodAndLoadCountersNode}, expose a klass constant of the holder.
 *
 * @param graph
 * @param stateMapper
 * @param node
 * @param context
 */
private static void handleLoadMethodCounters(StructuredGraph graph, FrameStateMapperClosure stateMapper, LoadMethodCountersNode node, PhaseContext context) {
    ResolvedJavaType type = node.getMethod().getDeclaringClass();
    Stamp hubStamp = context.getStampProvider().createHubStamp((ObjectStamp) StampFactory.objectNonNull());
    ConstantReflectionProvider constantReflection = context.getConstantReflection();
    ConstantNode klassHint = ConstantNode.forConstant(hubStamp, constantReflection.asObjectHub(type), context.getMetaAccess(), graph);
    FixedWithNextNode replacement = graph.add(new ResolveMethodAndLoadCountersNode(node.getMethod(), klassHint));
    insertReplacement(graph, stateMapper, node, replacement);
    node.replaceAtUsages(replacement, n -> !(n instanceof ResolveMethodAndLoadCountersNode));
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ResolveDynamicConstantNode(org.graalvm.compiler.hotspot.nodes.aot.ResolveDynamicConstantNode) ResolveConstantNode(org.graalvm.compiler.hotspot.nodes.aot.ResolveConstantNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) Stamp(org.graalvm.compiler.core.common.type.Stamp) ResolveMethodAndLoadCountersNode(org.graalvm.compiler.hotspot.nodes.aot.ResolveMethodAndLoadCountersNode) ConstantReflectionProvider(jdk.vm.ci.meta.ConstantReflectionProvider) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) HotSpotResolvedJavaType(jdk.vm.ci.hotspot.HotSpotResolvedJavaType)

Aggregations

FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)57 FixedNode (org.graalvm.compiler.nodes.FixedNode)33 ValueNode (org.graalvm.compiler.nodes.ValueNode)29 Node (org.graalvm.compiler.graph.Node)26 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)22 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)21 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)20 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)13 EndNode (org.graalvm.compiler.nodes.EndNode)12 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)12 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)10 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)9 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)9 Invoke (org.graalvm.compiler.nodes.Invoke)9 LogicNode (org.graalvm.compiler.nodes.LogicNode)9 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)9 PhiNode (org.graalvm.compiler.nodes.PhiNode)9 IfNode (org.graalvm.compiler.nodes.IfNode)8 ControlSinkNode (org.graalvm.compiler.nodes.ControlSinkNode)7 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)7