use of org.graalvm.compiler.nodes.ParameterNode in project graal by oracle.
the class IfCanonicalizerTest method test.
private void test(String snippet) {
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
DebugContext debug = graph.getDebug();
ParameterNode param = graph.getNodes(ParameterNode.TYPE).iterator().next();
ConstantNode constant = ConstantNode.forInt(0, graph);
for (Node n : param.usages().snapshot()) {
if (!(n instanceof FrameState)) {
n.replaceFirstInput(param, constant);
}
}
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
for (FrameState fs : param.usages().filter(FrameState.class).snapshot()) {
fs.replaceFirstInput(param, null);
param.safeDelete();
}
StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.YES);
assertEquals(referenceGraph, graph);
}
use of org.graalvm.compiler.nodes.ParameterNode in project graal by oracle.
the class NodeLIRBuilder method emitPrologue.
protected void emitPrologue(StructuredGraph graph) {
CallingConvention incomingArguments = gen.getResult().getCallingConvention();
Value[] params = new Value[incomingArguments.getArgumentCount()];
for (int i = 0; i < params.length; i++) {
params[i] = incomingArguments.getArgument(i);
if (ValueUtil.isStackSlot(params[i])) {
StackSlot slot = ValueUtil.asStackSlot(params[i]);
if (slot.isInCallerFrame() && !gen.getResult().getLIR().hasArgInCallerFrame()) {
gen.getResult().getLIR().setHasArgInCallerFrame();
}
}
}
gen.emitIncomingValues(params);
for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
Value paramValue = params[param.index()];
assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT))) : paramValue + " " + getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT));
setResult(param, gen.emitMove(paramValue));
}
}
use of org.graalvm.compiler.nodes.ParameterNode in project graal by oracle.
the class InliningUtil method inline.
/**
* Performs an actual inlining, thereby replacing the given invoke with the given
* {@code inlineGraph}.
*
* @param invoke the invoke that will be replaced
* @param inlineGraph the graph that the invoke will be replaced with
* @param receiverNullCheck true if a null check needs to be generated for non-static inlinings,
* false if no such check is required
* @param inlineeMethod the actual method being inlined. Maybe be null for snippets.
* @param reason the reason for inlining, used in tracing
* @param phase the phase that invoked inlining
*/
@SuppressWarnings("try")
public static UnmodifiableEconomicMap<Node, Node> inline(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck, ResolvedJavaMethod inlineeMethod, String reason, String phase) {
FixedNode invokeNode = invoke.asNode();
StructuredGraph graph = invokeNode.graph();
final NodeInputList<ValueNode> parameters = invoke.callTarget().arguments();
assert inlineGraph.getGuardsStage().ordinal() >= graph.getGuardsStage().ordinal();
assert !invokeNode.graph().isAfterFloatingReadPhase() : "inline isn't handled correctly after floating reads phase";
if (receiverNullCheck && !((MethodCallTargetNode) invoke.callTarget()).isStatic()) {
nonNullReceiver(invoke);
}
ArrayList<Node> nodes = new ArrayList<>(inlineGraph.getNodes().count());
ArrayList<ReturnNode> returnNodes = new ArrayList<>(4);
ArrayList<Invoke> partialIntrinsicExits = new ArrayList<>();
UnwindNode unwindNode = null;
final StartNode entryPointNode = inlineGraph.start();
FixedNode firstCFGNode = entryPointNode.next();
if (firstCFGNode == null) {
throw new IllegalStateException("Inlined graph is in invalid state: " + inlineGraph);
}
for (Node node : inlineGraph.getNodes()) {
if (node == entryPointNode || (node == entryPointNode.stateAfter() && node.usages().count() == 1) || node instanceof ParameterNode) {
// Do nothing.
} else {
nodes.add(node);
if (node instanceof ReturnNode) {
returnNodes.add((ReturnNode) node);
} else if (node instanceof Invoke) {
Invoke invokeInInlineGraph = (Invoke) node;
if (invokeInInlineGraph.bci() == BytecodeFrame.UNKNOWN_BCI) {
ResolvedJavaMethod target1 = inlineeMethod;
ResolvedJavaMethod target2 = invokeInInlineGraph.callTarget().targetMethod();
assert target1.equals(target2) : String.format("invoke in inlined method expected to be partial intrinsic exit (i.e., call to %s), not a call to %s", target1.format("%H.%n(%p)"), target2.format("%H.%n(%p)"));
partialIntrinsicExits.add(invokeInInlineGraph);
}
} else if (node instanceof UnwindNode) {
assert unwindNode == null;
unwindNode = (UnwindNode) node;
}
}
}
final AbstractBeginNode prevBegin = AbstractBeginNode.prevBegin(invokeNode);
DuplicationReplacement localReplacement = new DuplicationReplacement() {
@Override
public Node replacement(Node node) {
if (node instanceof ParameterNode) {
return parameters.get(((ParameterNode) node).index());
} else if (node == entryPointNode) {
return prevBegin;
}
return node;
}
};
assert invokeNode.successors().first() != null : invoke;
assert invokeNode.predecessor() != null;
Mark mark = graph.getMark();
// Instead, attach the inlining log of the child graph to the current inlining log.
EconomicMap<Node, Node> duplicates;
try (InliningLog.UpdateScope scope = graph.getInliningLog().openDefaultUpdateScope()) {
duplicates = graph.addDuplicates(nodes, inlineGraph, inlineGraph.getNodeCount(), localReplacement);
if (scope != null) {
graph.getInliningLog().addDecision(invoke, true, reason, phase, duplicates, inlineGraph.getInliningLog());
}
}
FrameState stateAfter = invoke.stateAfter();
assert stateAfter == null || stateAfter.isAlive();
FrameState stateAtExceptionEdge = null;
if (invoke instanceof InvokeWithExceptionNode) {
InvokeWithExceptionNode invokeWithException = ((InvokeWithExceptionNode) invoke);
if (unwindNode != null) {
ExceptionObjectNode obj = (ExceptionObjectNode) invokeWithException.exceptionEdge();
stateAtExceptionEdge = obj.stateAfter();
}
}
updateSourcePositions(invoke, inlineGraph, duplicates, !Objects.equals(inlineGraph.method(), inlineeMethod), mark);
if (stateAfter != null) {
processFrameStates(invoke, inlineGraph, duplicates, stateAtExceptionEdge, returnNodes.size() > 1);
int callerLockDepth = stateAfter.nestedLockDepth();
if (callerLockDepth != 0) {
for (MonitorIdNode original : inlineGraph.getNodes(MonitorIdNode.TYPE)) {
MonitorIdNode monitor = (MonitorIdNode) duplicates.get(original);
processMonitorId(invoke.stateAfter(), monitor);
}
}
} else {
assert checkContainsOnlyInvalidOrAfterFrameState(duplicates);
}
firstCFGNode = (FixedNode) duplicates.get(firstCFGNode);
for (int i = 0; i < returnNodes.size(); i++) {
returnNodes.set(i, (ReturnNode) duplicates.get(returnNodes.get(i)));
}
for (Invoke exit : partialIntrinsicExits) {
// A partial intrinsic exit must be replaced with a call to
// the intrinsified method.
Invoke dup = (Invoke) duplicates.get(exit.asNode());
if (dup instanceof InvokeNode) {
InvokeNode repl = graph.add(new InvokeNode(invoke.callTarget(), invoke.bci()));
dup.intrinsify(repl.asNode());
} else {
((InvokeWithExceptionNode) dup).replaceWithNewBci(invoke.bci());
}
}
if (unwindNode != null) {
unwindNode = (UnwindNode) duplicates.get(unwindNode);
}
finishInlining(invoke, graph, firstCFGNode, returnNodes, unwindNode, inlineGraph.getAssumptions(), inlineGraph);
GraphUtil.killCFG(invokeNode);
return duplicates;
}
use of org.graalvm.compiler.nodes.ParameterNode in project graal by oracle.
the class InliningData method freshlyInstantiatedArguments.
/**
* Gets the freshly instantiated arguments.
* <p>
* A freshly instantiated argument is either:
* <uL>
* <li>an {@link InliningData#isFreshInstantiation(org.graalvm.compiler.nodes.ValueNode)}</li>
* <li>a fixed-param, ie a {@link ParameterNode} receiving a freshly instantiated argument</li>
* </uL>
* </p>
*
* @return the positions of freshly instantiated arguments in the argument list of the
* <code>invoke</code>, or null if no such positions exist.
*/
public static BitSet freshlyInstantiatedArguments(Invoke invoke, EconomicSet<ParameterNode> fixedParams) {
assert fixedParams != null;
assert paramsAndInvokeAreInSameGraph(invoke, fixedParams);
BitSet result = null;
int argIdx = 0;
for (ValueNode arg : invoke.callTarget().arguments()) {
assert arg != null;
if (isFreshInstantiation(arg) || (arg instanceof ParameterNode && fixedParams.contains((ParameterNode) arg))) {
if (result == null) {
result = new BitSet();
}
result.set(argIdx);
}
argIdx++;
}
return result;
}
use of org.graalvm.compiler.nodes.ParameterNode in project graal by oracle.
the class InlineableGraph method replaceParamsWithMoreInformativeArguments.
/**
* This method detects:
* <ul>
* <li>constants among the arguments to the <code>invoke</code></li>
* <li>arguments with more precise type than that declared by the corresponding parameter</li>
* </ul>
*
* <p>
* The corresponding parameters are updated to reflect the above information. Before doing so,
* their usages are added to <code>parameterUsages</code> for later incremental
* canonicalization.
* </p>
*
* @return null if no incremental canonicalization is need, a list of nodes for such
* canonicalization otherwise.
*/
private ArrayList<Node> replaceParamsWithMoreInformativeArguments(final Invoke invoke, final HighTierContext context) {
NodeInputList<ValueNode> args = invoke.callTarget().arguments();
ArrayList<Node> parameterUsages = null;
List<ParameterNode> params = graph.getNodes(ParameterNode.TYPE).snapshot();
assert params.size() <= args.size();
/*
* param-nodes that aren't used (eg, as a result of canonicalization) don't occur in
* `params`. Thus, in general, the sizes of `params` and `args` don't always match. Still,
* it's always possible to pair a param-node with its corresponding arg-node using
* param.index() as index into `args`.
*/
for (ParameterNode param : params) {
if (param.usages().isNotEmpty()) {
ValueNode arg = args.get(param.index());
if (arg.isConstant()) {
ConstantNode constant = (ConstantNode) arg;
parameterUsages = trackParameterUsages(param, parameterUsages);
// collect param usages before replacing the param
param.replaceAtUsagesAndDelete(graph.unique(ConstantNode.forConstant(arg.stamp(NodeView.DEFAULT), constant.getValue(), constant.getStableDimension(), constant.isDefaultStable(), context.getMetaAccess())));
// param-node gone, leaving a gap in the sequence given by param.index()
} else {
Stamp impro = improvedStamp(arg, param);
if (impro != null) {
param.setStamp(impro);
parameterUsages = trackParameterUsages(param, parameterUsages);
} else {
assert !isArgMoreInformativeThanParam(arg, param);
}
}
}
}
assert (parameterUsages == null) || (!parameterUsages.isEmpty());
return parameterUsages;
}
Aggregations