private void test(final String snippet) { // No debug scope to reduce console noise for @Test(expected = ...) tests StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); Debug.dump(graph, "Graph"); new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders())); StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.YES); assertEquals(referenceGraph, graph); }
/** * Creates a graph for this stub. * * <p>If the stub returns an object, the graph created corresponds to this pseudo code: * * <pre> * Object foreignFunctionStub(args...) { * foreignFunction(currentThread, args); * if (clearPendingException(thread())) { * getAndClearObjectResult(thread()); * DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint); * } * return verifyObject(getAndClearObjectResult(thread())); * } * </pre> * * If the stub returns a primitive or word, the graph created corresponds to this pseudo code * (using {@code int} as the primitive return type): * * <pre> * int foreignFunctionStub(args...) { * int result = foreignFunction(currentThread, args); * if (clearPendingException(thread())) { * DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint); * } * return result; * } * </pre> * * If the stub is void, the graph created corresponds to this pseudo code: * * <pre> * void foreignFunctionStub(args...) { * foreignFunction(currentThread, args); * if (clearPendingException(thread())) { * DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint); * } * } * </pre> * * In each example above, the {@code currentThread} argument is the C++ JavaThread value (i.e., * %r15 on AMD64) and is only prepended if {@link #prependThread} is true. */ @Override protected StructuredGraph getGraph() { WordTypes wordTypes = providers.getWordTypes(); Class<?>[] args = linkage.getDescriptor().getArgumentTypes(); boolean isObjectResult = !linkage.getOutgoingCallingConvention().getReturn().getLIRKind().isValue(); StructuredGraph graph = new StructuredGraph(toString(), null, AllowAssumptions.NO); graph.disableUnsafeAccessTracking(); GraphKit kit = new GraphKit(graph, providers, wordTypes, providers.getGraphBuilderPlugins()); ParameterNode[] params = createParameters(kit, args); ReadRegisterNode thread = kit.append( new ReadRegisterNode( providers.getRegisters().getThreadRegister(), wordTypes.getWordKind(), true, false)); ValueNode result = createTargetCall(kit, params, thread); kit.createInvoke( StubUtil.class, "handlePendingException", thread, ConstantNode.forBoolean(isObjectResult, graph)); if (isObjectResult) { InvokeNode object = kit.createInvoke(HotSpotReplacementsUtil.class, "getAndClearObjectResult", thread); result = kit.createInvoke(StubUtil.class, "verifyObject", object); } kit.append( new ReturnNode(linkage.getDescriptor().getResultType() == void.class ? null : result)); if (Debug.isDumpEnabled()) { Debug.dump(graph, "Initial stub graph"); } kit.inlineInvokes(); if (Debug.isDumpEnabled()) { Debug.dump(graph, "Stub graph before compilation"); } return graph; }
@SuppressWarnings("try") private ScheduleResult getFinalSchedule( final String snippet, final TestMode mode, final SchedulingStrategy schedulingStrategy) { final StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); try (Scope d = Debug.scope("FloatingReadTest", graph)) { try (OverrideScope s = OptionValue.override( OptScheduleOutOfLoops, schedulingStrategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS, OptImplicitNullChecks, false)) { HighTierContext context = getDefaultHighTierContext(); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); canonicalizer.apply(graph, context); if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { new InliningPhase(canonicalizer).apply(graph, context); } new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER) .apply(graph, context); if (mode == TestMode.WITHOUT_FRAMESTATES || mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { graph.clearAllStateAfter(); } Debug.dump(graph, "after removal of framestates"); new FloatingReadPhase().apply(graph); new RemoveValueProxyPhase().apply(graph); MidTierContext midContext = new MidTierContext( getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo()); new GuardLoweringPhase().apply(graph, midContext); new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER) .apply(graph, midContext); new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.LOW_TIER) .apply(graph, midContext); SchedulePhase schedule = new SchedulePhase(schedulingStrategy); schedule.apply(graph); assertDeepEquals(1, graph.getNodes().filter(StartNode.class).count()); return graph.getLastSchedule(); } } catch (Throwable e) { throw Debug.handle(e); } }
public void finish(LIRGeneratorTool gen) { Debug.dump(gen.getResult().getLIR(), "Before SSI operands"); AbstractControlFlowGraph<?> cfg = gen.getResult().getLIR().getControlFlowGraph(); for (AbstractBlockBase<?> block : cfg.getBlocks()) { // set label BlockData data = blockData.get(block); if (data != null) { if (data.incoming != null && data.incoming.size() > 0) { LabelOp label = getLabel(gen, block); label.addIncomingValues(data.incoming.toArray(new Value[data.incoming.size()])); } // set block end if (data.outgoing != null && data.outgoing.size() > 0) { BlockEndOp blockEndOp = getBlockEnd(gen, block); blockEndOp.addOutgoingValues(data.outgoing.toArray(new Value[data.outgoing.size()])); } } } }
@Override public void lower(LoweringTool tool) { StructuredGraph replacementGraph = getLoweredSnippetGraph(tool); InvokeNode invoke = replaceWithInvoke(); assert invoke.verify(); if (replacementGraph != null) { // Pull out the receiver null check so that a replaced // receiver can be lowered if necessary if (!targetMethod.isStatic()) { ValueNode nonNullReceiver = InliningUtil.nonNullReceiver(invoke); if (nonNullReceiver instanceof Lowerable) { ((Lowerable) nonNullReceiver).lower(tool); } } InliningUtil.inline(invoke, replacementGraph, false, null); Debug.dump(Debug.INFO_LOG_LEVEL, graph(), "After inlining replacement %s", replacementGraph); } else { if (isPlaceholderBci(invoke.bci())) { throw new GraalError("%s: cannot lower to invoke with placeholder BCI: %s", graph(), this); } if (invoke.stateAfter() == null) { ResolvedJavaMethod method = graph().method(); if (method.getAnnotation(MethodSubstitution.class) != null || method.getAnnotation(Snippet.class) != null) { // One cause for this is that a MacroNode is created for a method that // no longer needs a MacroNode. For example, Class.getComponentType() // only needs a MacroNode prior to JDK9 as it was given a non-native // implementation in JDK9. throw new GraalError( "%s macro created for call to %s in %s must be lowerable to a snippet or intrinsic graph. " + "Maybe a macro node is not needed for this method in the current JDK?", getClass().getSimpleName(), targetMethod.format("%h.%n(%p)"), graph()); } throw new GraalError("%s: cannot lower to invoke without state: %s", graph(), this); } invoke.lower(tool); } }
private static void dumpGraph(final StructuredGraph graph) { Debug.dump(graph, "Graph"); }