use of org.graalvm.compiler.nodes.BeginNode in project graal by oracle.
the class SchedulingTest2 method testValueProxyInputs.
@Test
public void testValueProxyInputs() {
StructuredGraph graph = parseEager("testSnippet", AllowAssumptions.YES);
DebugContext debug = graph.getDebug();
ReturnNode returnNode = graph.getNodes(ReturnNode.TYPE).first();
BeginNode beginNode = graph.add(new BeginNode());
returnNode.replaceAtPredecessor(beginNode);
beginNode.setNext(returnNode);
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER);
schedulePhase.apply(graph);
ScheduleResult schedule = graph.getLastSchedule();
BlockMap<List<Node>> blockToNodesMap = schedule.getBlockToNodesMap();
NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap();
assertDeepEquals(2, schedule.getCFG().getBlocks().length);
for (BinaryArithmeticNode<?> node : graph.getNodes().filter(BinaryArithmeticNode.class)) {
if (node instanceof AddNode) {
assertTrue(node.toString() + " expected: " + nodeToBlock.get(beginNode) + " but was: " + nodeToBlock.get(node), nodeToBlock.get(node) != nodeToBlock.get(beginNode));
}
}
for (FrameState fs : graph.getNodes(FrameState.TYPE)) {
Block block = nodeToBlock.get(fs);
assertTrue(fs.toString(), block == schedule.getCFG().getStartBlock());
for (Node usage : fs.usages()) {
if (usage instanceof StateSplit && ((StateSplit) usage).stateAfter() == fs) {
assertTrue(usage.toString(), nodeToBlock.get(usage) == block);
if (usage != block.getBeginNode()) {
List<Node> map = blockToNodesMap.get(block);
assertTrue(map.indexOf(fs) + " < " + map.indexOf(usage), map.indexOf(fs) < map.indexOf(usage));
}
}
}
}
PhaseContext context = new PhaseContext(getProviders());
new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
MidTierContext midContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
new GuardLoweringPhase().apply(graph, midContext);
FrameStateAssignmentPhase phase = new FrameStateAssignmentPhase();
phase.apply(graph);
schedulePhase.apply(graph);
schedule = graph.getLastSchedule();
blockToNodesMap = schedule.getBlockToNodesMap();
nodeToBlock = schedule.getNodeToBlockMap();
for (FrameState fs : graph.getNodes(FrameState.TYPE)) {
Block block = nodeToBlock.get(fs);
assertTrue(fs.toString(), block == schedule.getCFG().getStartBlock());
for (Node usage : fs.usages()) {
if ((usage instanceof StateSplit && ((StateSplit) usage).stateAfter() == fs) || (usage instanceof DeoptDuring && ((DeoptDuring) usage).stateDuring() == fs)) {
assertTrue(usage.toString(), nodeToBlock.get(usage) == block);
if (usage != block.getBeginNode()) {
List<Node> map = blockToNodesMap.get(block);
assertTrue(map.indexOf(fs) + " < " + map.indexOf(usage), map.indexOf(fs) < map.indexOf(usage));
}
}
}
}
}
use of org.graalvm.compiler.nodes.BeginNode in project graal by oracle.
the class UseTrappingNullChecksPhase method replaceWithTrappingNullCheck.
private static void replaceWithTrappingNullCheck(AbstractDeoptimizeNode deopt, IfNode ifNode, LogicNode condition, DeoptimizationReason deoptimizationReason, long implicitNullCheckLimit) {
DebugContext debug = deopt.getDebug();
counterTrappingNullCheck.increment(debug);
if (deopt instanceof DynamicDeoptimizeNode) {
counterTrappingNullCheckDynamicDeoptimize.increment(debug);
}
if (deoptimizationReason == DeoptimizationReason.UnreachedCode) {
counterTrappingNullCheckUnreached.increment(debug);
}
IsNullNode isNullNode = (IsNullNode) condition;
AbstractBeginNode nonTrappingContinuation = ifNode.falseSuccessor();
AbstractBeginNode trappingContinuation = ifNode.trueSuccessor();
DeoptimizingFixedWithNextNode trappingNullCheck = null;
FixedNode nextNonTrapping = nonTrappingContinuation.next();
ValueNode value = isNullNode.getValue();
if (OptImplicitNullChecks.getValue(ifNode.graph().getOptions()) && implicitNullCheckLimit > 0) {
if (nextNonTrapping instanceof FixedAccessNode) {
FixedAccessNode fixedAccessNode = (FixedAccessNode) nextNonTrapping;
if (fixedAccessNode.canNullCheck()) {
AddressNode address = fixedAccessNode.getAddress();
ValueNode base = address.getBase();
ValueNode index = address.getIndex();
// intervening uncompress out of the address chain
if (base != null && base instanceof CompressionNode) {
base = ((CompressionNode) base).getValue();
}
if (index != null && index instanceof CompressionNode) {
index = ((CompressionNode) index).getValue();
}
if (((base == value && index == null) || (base == null && index == value)) && address.getMaxConstantDisplacement() < implicitNullCheckLimit) {
// Opportunity for implicit null check as part of an existing read found!
fixedAccessNode.setStateBefore(deopt.stateBefore());
fixedAccessNode.setNullCheck(true);
deopt.graph().removeSplit(ifNode, nonTrappingContinuation);
trappingNullCheck = fixedAccessNode;
counterTrappingNullCheckExistingRead.increment(debug);
}
}
}
}
if (trappingNullCheck == null) {
// Need to add a null check node.
trappingNullCheck = deopt.graph().add(new NullCheckNode(value));
deopt.graph().replaceSplit(ifNode, trappingNullCheck, nonTrappingContinuation);
}
trappingNullCheck.setStateBefore(deopt.stateBefore());
/*
* We now have the pattern NullCheck/BeginNode/... It's possible some node is using the
* BeginNode as a guard input, so replace guard users of the Begin with the NullCheck and
* then remove the Begin from the graph.
*/
nonTrappingContinuation.replaceAtUsages(InputType.Guard, trappingNullCheck);
if (nonTrappingContinuation instanceof BeginNode) {
GraphUtil.unlinkFixedNode(nonTrappingContinuation);
nonTrappingContinuation.safeDelete();
}
GraphUtil.killCFG(trappingContinuation);
GraphUtil.tryKillUnused(isNullNode);
}
use of org.graalvm.compiler.nodes.BeginNode in project graal by oracle.
the class MultiTypeGuardInlineInfo method inlineSingleMethod.
private EconomicSet<Node> inlineSingleMethod(StructuredGraph graph, StampProvider stampProvider, ConstantReflectionProvider constantReflection) {
assert concretes.size() == 1 && inlineableElements.length == 1 && ptypes.size() > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0;
AbstractBeginNode calleeEntryNode = graph.add(new BeginNode());
AbstractBeginNode unknownTypeSux = createUnknownTypeSuccessor(graph);
AbstractBeginNode[] successors = new AbstractBeginNode[] { calleeEntryNode, unknownTypeSux };
createDispatchOnTypeBeforeInvoke(graph, successors, false, stampProvider, constantReflection);
calleeEntryNode.setNext(invoke.asNode());
return inline(invoke, methodAt(0), inlineableElementAt(0), false);
}
use of org.graalvm.compiler.nodes.BeginNode in project graal by oracle.
the class MultiTypeGuardInlineInfo method devirtualizeWithTypeSwitch.
private void devirtualizeWithTypeSwitch(StructuredGraph graph, InvokeKind kind, ResolvedJavaMethod target, StampProvider stampProvider, ConstantReflectionProvider constantReflection) {
AbstractBeginNode invocationEntry = graph.add(new BeginNode());
AbstractBeginNode unknownTypeSux = createUnknownTypeSuccessor(graph);
AbstractBeginNode[] successors = new AbstractBeginNode[] { invocationEntry, unknownTypeSux };
createDispatchOnTypeBeforeInvoke(graph, successors, true, stampProvider, constantReflection);
invocationEntry.setNext(invoke.asNode());
ValueNode receiver = ((MethodCallTargetNode) invoke.callTarget()).receiver();
PiNode anchoredReceiver = InliningUtil.createAnchoredReceiver(graph, invocationEntry, target.getDeclaringClass(), receiver, false);
invoke.callTarget().replaceFirstInput(receiver, anchoredReceiver);
InliningUtil.replaceInvokeCallTarget(invoke, graph, kind, target);
}
Aggregations