use of org.graalvm.compiler.nodes.StartNode in project graal by oracle.
the class InliningUtilities method isTrivialMethod.
public static boolean isTrivialMethod(StructuredGraph graph) {
int numInvokes = 0;
int numOthers = 0;
for (Node n : graph.getNodes()) {
if (n instanceof StartNode || n instanceof ParameterNode || n instanceof FullInfopointNode || n instanceof ValueProxy || n instanceof AssertValueNode) {
continue;
}
if (n instanceof MethodCallTargetNode) {
numInvokes++;
} else {
numOthers++;
}
if (!shouldBeTrivial(numInvokes, numOthers, graph)) {
return false;
}
}
return true;
}
use of org.graalvm.compiler.nodes.StartNode in project graal by oracle.
the class SnippetTemplate method instantiate.
/**
* Replaces a given floating node with this specialized snippet.
*
* @param metaAccess
* @param replacee the node that will be replaced
* @param replacer object that replaces the usages of {@code replacee}
* @param tool lowering tool used to insert the snippet into the control-flow
* @param args the arguments to be bound to the flattened positional parameters of the snippet
*/
@SuppressWarnings("try")
public void instantiate(MetaAccessProvider metaAccess, FloatingNode replacee, UsageReplacer replacer, LoweringTool tool, Arguments args) {
DebugContext debug = replacee.getDebug();
assert assertSnippetKills(replacee);
try (DebugCloseable a = args.info.instantiationTimer.start(debug)) {
args.info.instantiationCounter.increment(debug);
// Inline the snippet nodes, replacing parameters with the given args in the process
StartNode entryPointNode = snippet.start();
FixedNode firstCFGNode = entryPointNode.next();
StructuredGraph replaceeGraph = replacee.graph();
EconomicMap<Node, Node> replacements = bind(replaceeGraph, metaAccess, args);
replacements.put(entryPointNode, tool.getCurrentGuardAnchor().asNode());
UnmodifiableEconomicMap<Node, Node> duplicates = inlineSnippet(replacee, debug, replaceeGraph, replacements);
FixedWithNextNode lastFixedNode = tool.lastFixedNode();
assert lastFixedNode != null && lastFixedNode.isAlive() : replaceeGraph + " lastFixed=" + lastFixedNode;
FixedNode next = lastFixedNode.next();
lastFixedNode.setNext(null);
FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
replaceeGraph.addAfterFixed(lastFixedNode, firstCFGNodeDuplicate);
rewireFrameStates(replacee, duplicates);
updateStamps(replacee, duplicates);
rewireMemoryGraph(replacee, duplicates);
// Replace all usages of the replacee with the value returned by the snippet
ReturnNode returnDuplicate = (ReturnNode) duplicates.get(returnNode);
ValueNode returnValue = returnDuplicate.result();
assert returnValue != null || replacee.hasNoUsages();
replacer.replace(replacee, returnValue);
if (returnDuplicate.isAlive()) {
returnDuplicate.replaceAndDelete(next);
}
debug.dump(DebugContext.DETAILED_LEVEL, replaceeGraph, "After lowering %s with %s", replacee, this);
}
}
use of org.graalvm.compiler.nodes.StartNode in project graal by oracle.
the class BytecodeParser method build.
@SuppressWarnings("try")
protected void build(FixedWithNextNode startInstruction, FrameStateBuilder startFrameState) {
if (PrintProfilingInformation.getValue(options) && profilingInfo != null) {
TTY.println("Profiling info for " + method.format("%H.%n(%p)"));
TTY.println(Util.indent(profilingInfo.toString(method, CodeUtil.NEW_LINE), " "));
}
try (Indent indent = debug.logAndIndent("build graph for %s", method)) {
if (bytecodeProvider.shouldRecordMethodDependencies()) {
assert getParent() != null || method.equals(graph.method());
// Record method dependency in the graph
graph.recordMethod(method);
}
// compute the block map, setup exception handlers and get the entrypoint(s)
BciBlockMapping newMapping = BciBlockMapping.create(stream, code, options, graph.getDebug());
this.blockMap = newMapping;
this.firstInstructionArray = new FixedWithNextNode[blockMap.getBlockCount()];
this.entryStateArray = new FrameStateBuilder[blockMap.getBlockCount()];
if (!method.isStatic()) {
originalReceiver = startFrameState.loadLocal(0, JavaKind.Object);
}
/*
* Configure the assertion checking behavior of the FrameStateBuilder. This needs to be
* done only when assertions are enabled, so it is wrapped in an assertion itself.
*/
assert computeKindVerification(startFrameState);
try (DebugContext.Scope s = debug.scope("LivenessAnalysis")) {
int maxLocals = method.getMaxLocals();
liveness = LocalLiveness.compute(debug, stream, blockMap.getBlocks(), maxLocals, blockMap.getLoopCount());
} catch (Throwable e) {
throw debug.handle(e);
}
lastInstr = startInstruction;
this.setCurrentFrameState(startFrameState);
stream.setBCI(0);
BciBlock startBlock = blockMap.getStartBlock();
if (this.parent == null) {
StartNode startNode = graph.start();
if (method.isSynchronized()) {
assert !parsingIntrinsic();
startNode.setStateAfter(createFrameState(BytecodeFrame.BEFORE_BCI, startNode));
} else {
if (!parsingIntrinsic()) {
if (graph.method() != null && graph.method().isJavaLangObjectInit()) {
/*
* Don't clear the receiver when Object.<init> is the compilation root.
* The receiver is needed as input to RegisterFinalizerNode.
*/
} else {
frameState.clearNonLiveLocals(startBlock, liveness, true);
}
assert bci() == 0;
startNode.setStateAfter(createFrameState(bci(), startNode));
} else {
if (startNode.stateAfter() == null) {
FrameState stateAfterStart = createStateAfterStartOfReplacementGraph();
startNode.setStateAfter(stateAfterStart);
}
}
}
}
try (DebugCloseable context = openNodeContext()) {
if (method.isSynchronized()) {
finishPrepare(lastInstr, BytecodeFrame.BEFORE_BCI);
// add a monitor enter to the start block
methodSynchronizedObject = synchronizedObject(frameState, method);
frameState.clearNonLiveLocals(startBlock, liveness, true);
assert bci() == 0;
genMonitorEnter(methodSynchronizedObject, bci());
}
ProfilingPlugin profilingPlugin = this.graphBuilderConfig.getPlugins().getProfilingPlugin();
if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
FrameState stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
profilingPlugin.profileInvoke(this, method, stateBefore);
}
finishPrepare(lastInstr, 0);
genInfoPointNode(InfopointReason.METHOD_START, null);
}
currentBlock = blockMap.getStartBlock();
setEntryState(startBlock, frameState);
if (startBlock.isLoopHeader) {
appendGoto(startBlock);
} else {
setFirstInstruction(startBlock, lastInstr);
}
BciBlock[] blocks = blockMap.getBlocks();
for (BciBlock block : blocks) {
processBlock(block);
}
}
}
use of org.graalvm.compiler.nodes.StartNode in project graal by oracle.
the class ConvertDeoptimizeToGuardPhase method propagateFixed.
@SuppressWarnings("try")
private void propagateFixed(FixedNode from, StaticDeoptimizingNode deopt, LoweringProvider loweringProvider) {
Node current = from;
while (current != null) {
if (GraalOptions.GuardPriorities.getValue(from.getOptions()) && current instanceof FixedGuardNode) {
FixedGuardNode otherGuard = (FixedGuardNode) current;
if (otherGuard.computePriority().isHigherPriorityThan(deopt.computePriority())) {
moveAsDeoptAfter(otherGuard, deopt);
return;
}
} else if (current instanceof AbstractBeginNode) {
if (current instanceof AbstractMergeNode) {
AbstractMergeNode mergeNode = (AbstractMergeNode) current;
FixedNode next = mergeNode.next();
while (mergeNode.isAlive()) {
AbstractEndNode end = mergeNode.forwardEnds().first();
propagateFixed(end, deopt, loweringProvider);
}
assert next.isAlive();
propagateFixed(next, deopt, loweringProvider);
return;
} else if (current.predecessor() instanceof IfNode) {
IfNode ifNode = (IfNode) current.predecessor();
// Prioritize the source position of the IfNode
try (DebugCloseable closable = ifNode.withNodeSourcePosition()) {
StructuredGraph graph = ifNode.graph();
LogicNode conditionNode = ifNode.condition();
boolean negateGuardCondition = current == ifNode.trueSuccessor();
FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deopt.getReason(), deopt.getAction(), deopt.getSpeculation(), negateGuardCondition));
FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
AbstractBeginNode survivingSuccessor;
if (negateGuardCondition) {
survivingSuccessor = ifNode.falseSuccessor();
} else {
survivingSuccessor = ifNode.trueSuccessor();
}
graph.removeSplitPropagate(ifNode, survivingSuccessor);
Node newGuard = guard;
if (survivingSuccessor instanceof LoopExitNode) {
newGuard = ProxyNode.forGuard(guard, (LoopExitNode) survivingSuccessor, graph);
}
survivingSuccessor.replaceAtUsages(InputType.Guard, newGuard);
graph.getDebug().log("Converting deopt on %-5s branch of %s to guard for remaining branch %s.", negateGuardCondition, ifNode, survivingSuccessor);
FixedNode next = pred.next();
pred.setNext(guard);
guard.setNext(next);
SimplifierTool simplifierTool = GraphUtil.getDefaultSimplifier(null, null, null, false, graph.getAssumptions(), graph.getOptions(), loweringProvider);
survivingSuccessor.simplify(simplifierTool);
return;
}
} else if (current.predecessor() == null || current.predecessor() instanceof ControlSplitNode) {
assert current.predecessor() != null || (current instanceof StartNode && current == ((AbstractBeginNode) current).graph().start());
moveAsDeoptAfter((AbstractBeginNode) current, deopt);
return;
}
}
current = current.predecessor();
}
}
use of org.graalvm.compiler.nodes.StartNode in project graal by oracle.
the class FoldTest method checkHighTierGraph.
@Override
protected boolean checkHighTierGraph(StructuredGraph graph) {
// check that folding happened correctly
StartNode start = graph.start();
assert start.next() instanceof ReturnNode : "expected ReturnNode, got " + start.next();
ReturnNode ret = (ReturnNode) start.next();
assert ret.result().isConstant() : "expected ConstantNode, got " + ret.result();
return true;
}
Aggregations