use of org.graalvm.compiler.nodes.FixedNode in project graal by oracle.
the class PEGraphDecoder method doInline.
protected LoopScope doInline(PEMethodScope methodScope, LoopScope loopScope, InvokeData invokeData, InlineInfo inlineInfo, ValueNode[] arguments) {
ResolvedJavaMethod inlineMethod = inlineInfo.getMethodToInline();
EncodedGraph graphToInline = lookupEncodedGraph(inlineMethod, inlineInfo.getOriginalMethod(), inlineInfo.getIntrinsicBytecodeProvider(), graph.trackNodeSourcePosition());
if (graphToInline == null) {
return null;
}
assert !graph.trackNodeSourcePosition() || graphToInline.trackNodeSourcePosition() : graph + " " + graphToInline;
if (methodScope.inliningDepth > Options.InliningDepthError.getValue(options)) {
throw tooDeepInlining(methodScope);
}
for (InlineInvokePlugin plugin : inlineInvokePlugins) {
plugin.notifyBeforeInline(inlineMethod);
}
Invoke invoke = invokeData.invoke;
FixedNode invokeNode = invoke.asNode();
FixedWithNextNode predecessor = (FixedWithNextNode) invokeNode.predecessor();
invokeNode.replaceAtPredecessor(null);
PEMethodScope inlineScope = new PEMethodScope(graph, methodScope, loopScope, graphToInline, inlineMethod, invokeData, methodScope.inliningDepth + 1, loopExplosionPlugin, arguments);
if (!inlineMethod.isStatic()) {
if (StampTool.isPointerAlwaysNull(arguments[0])) {
/*
* The receiver is null, so we can unconditionally throw a NullPointerException
* instead of performing any inlining.
*/
DeoptimizeNode deoptimizeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException));
predecessor.setNext(deoptimizeNode);
finishInlining(inlineScope);
/* Continue decoding in the caller. */
return loopScope;
} else if (!StampTool.isPointerNonNull(arguments[0])) {
/* The receiver might be null, so we need to insert a null check. */
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(inlineScope, predecessor);
arguments[0] = graphBuilderContext.nullCheckedValue(arguments[0]);
predecessor = graphBuilderContext.lastInstr;
}
}
LoopScope inlineLoopScope = createInitialLoopScope(inlineScope, predecessor);
/*
* The GraphEncoder assigns parameters a nodeId immediately after the fixed nodes.
* Initializing createdNodes here avoid decoding and immediately replacing the
* ParameterNodes.
*/
int firstArgumentNodeId = inlineScope.maxFixedNodeOrderId + 1;
for (int i = 0; i < arguments.length; i++) {
inlineLoopScope.createdNodes[firstArgumentNodeId + i] = arguments[i];
}
// Copy assumptions from inlinee to caller
Assumptions assumptions = graph.getAssumptions();
Assumptions inlinedAssumptions = graphToInline.getAssumptions();
if (assumptions != null) {
if (inlinedAssumptions != null) {
assumptions.record(inlinedAssumptions);
}
} else {
assert inlinedAssumptions == null : String.format("cannot inline graph (%s) which makes assumptions into a graph (%s) that doesn't", inlineMethod, graph);
}
// Copy inlined methods from inlinee to caller
List<ResolvedJavaMethod> inlinedMethods = graphToInline.getInlinedMethods();
if (inlinedMethods != null) {
graph.getMethods().addAll(inlinedMethods);
}
if (graphToInline.getFields() != null) {
for (ResolvedJavaField field : graphToInline.getFields()) {
graph.recordField(field);
}
}
if (graphToInline.hasUnsafeAccess()) {
graph.markUnsafeAccess();
}
/*
* Do the actual inlining by returning the initial loop scope for the inlined method scope.
*/
return inlineLoopScope;
}
use of org.graalvm.compiler.nodes.FixedNode in project graal by oracle.
the class PEGraphDecoder method nodeAfterInvoke.
public FixedNode nodeAfterInvoke(PEMethodScope methodScope, LoopScope loopScope, InvokeData invokeData, AbstractBeginNode lastBlock) {
assert lastBlock.isAlive();
FixedNode n;
if (invokeData.invoke instanceof InvokeWithExceptionNode) {
registerNode(loopScope, invokeData.nextOrderId, lastBlock, false, false);
n = makeStubNode(methodScope, loopScope, invokeData.nextNextOrderId);
} else {
n = makeStubNode(methodScope, loopScope, invokeData.nextOrderId);
}
return n;
}
use of org.graalvm.compiler.nodes.FixedNode in project graal by oracle.
the class IntegerExactArithmeticSplitNode method lower.
static void lower(LoweringTool tool, IntegerExactArithmeticNode node) {
if (node.asNode().graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
FloatingNode floatingNode = (FloatingNode) node;
FixedWithNextNode previous = tool.lastFixedNode();
FixedNode next = previous.next();
previous.setNext(null);
DeoptimizeNode deopt = floatingNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ArithmeticException));
AbstractBeginNode normalBegin = floatingNode.graph().add(new BeginNode());
normalBegin.setNext(next);
IntegerExactArithmeticSplitNode split = node.createSplit(normalBegin, BeginNode.begin(deopt));
previous.setNext(split);
floatingNode.replaceAndDelete(split);
}
}
use of org.graalvm.compiler.nodes.FixedNode in project graal by oracle.
the class MethodHandleNode method simplify.
@Override
public void simplify(SimplifierTool tool) {
MethodHandleAccessProvider methodHandleAccess = tool.getConstantReflection().getMethodHandleAccess();
ValueNode[] argumentsArray = arguments.toArray(new ValueNode[arguments.size()]);
final FixedNode before = this;
GraphAdder adder = new GraphAdder(graph()) {
@Override
public <T extends ValueNode> T add(T node) {
T added = graph().addOrUnique(node);
if (added instanceof FixedWithNextNode) {
graph().addBeforeFixed(before, (FixedWithNextNode) added);
}
return added;
}
};
InvokeNode invoke = tryResolveTargetInvoke(adder, methodHandleAccess, intrinsicMethod, targetMethod, bci, returnStamp, argumentsArray);
if (invoke != null) {
assert invoke.graph() == null;
invoke = graph().addOrUniqueWithInputs(invoke);
invoke.setStateAfter(stateAfter());
FixedNode currentNext = next();
replaceAtUsages(invoke);
GraphUtil.removeFixedWithUnusedInputs(this);
graph().addBeforeFixed(currentNext, invoke);
}
}
use of org.graalvm.compiler.nodes.FixedNode 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;
}
Aggregations