use of org.graalvm.compiler.debug.GraalError in project graal by oracle.
the class MacroNode method lower.
@Override
public void lower(LoweringTool tool) {
StructuredGraph replacementGraph = getLoweredSnippetGraph(tool);
InvokeNode invoke = replaceWithInvoke();
assert invoke.verify();
if (replacementGraph != null) {
// 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, targetMethod);
replacementGraph.getDebug().dump(DebugContext.DETAILED_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) {
// 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);
}
}
use of org.graalvm.compiler.debug.GraalError in project graal by oracle.
the class MacroStateSplitNode method replaceSnippetInvokes.
protected void replaceSnippetInvokes(StructuredGraph snippetGraph) {
for (MethodCallTargetNode call : snippetGraph.getNodes(MethodCallTargetNode.TYPE)) {
Invoke invoke = call.invoke();
if (!call.targetMethod().equals(getTargetMethod())) {
throw new GraalError("unexpected invoke %s in snippet", getClass().getSimpleName());
}
assert invoke.stateAfter().bci == BytecodeFrame.AFTER_BCI;
// Here we need to fix the bci of the invoke
InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.callTarget(), bci()));
newInvoke.setStateAfter(invoke.stateAfter());
snippetGraph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke);
}
}
use of org.graalvm.compiler.debug.GraalError in project graal by oracle.
the class CompilationResultBuilder method emitOp.
private static void emitOp(CompilationResultBuilder crb, LIRInstruction op) {
try {
int start = crb.asm.position();
op.emitCode(crb);
if (op.getPosition() != null) {
crb.recordSourceMapping(start, crb.asm.position(), op.getPosition());
}
} catch (AssertionError t) {
throw new GraalError(t);
} catch (RuntimeException t) {
throw new GraalError(t);
}
}
use of org.graalvm.compiler.debug.GraalError in project graal by oracle.
the class LinearScan method verifyIntervals.
@SuppressWarnings("try")
protected void verifyIntervals() {
try (Indent indent = debug.logAndIndent("verifying intervals")) {
int len = intervalsSize;
for (int i = 0; i < len; i++) {
Interval i1 = intervals[i];
if (i1 == null) {
continue;
}
i1.checkSplitChildren();
if (i1.operandNumber != i) {
debug.log("Interval %d is on position %d in list", i1.operandNumber, i);
debug.log(i1.logString(this));
throw new GraalError("");
}
if (isVariable(i1.operand) && i1.kind().equals(LIRKind.Illegal)) {
debug.log("Interval %d has no type assigned", i1.operandNumber);
debug.log(i1.logString(this));
throw new GraalError("");
}
if (i1.location() == null) {
debug.log("Interval %d has no register assigned", i1.operandNumber);
debug.log(i1.logString(this));
throw new GraalError("");
}
if (i1.first().isEndMarker()) {
debug.log("Interval %d has no Range", i1.operandNumber);
debug.log(i1.logString(this));
throw new GraalError("");
}
for (Range r = i1.first(); !r.isEndMarker(); r = r.next) {
if (r.from >= r.to) {
debug.log("Interval %d has zero length range", i1.operandNumber);
debug.log(i1.logString(this));
throw new GraalError("");
}
}
for (int j = i + 1; j < len; j++) {
Interval i2 = intervals[j];
if (i2 == null) {
continue;
}
// . ignore them because the range information has no meaning there
if (i1.from() == 1 && i1.to() == 2) {
continue;
}
if (i2.from() == 1 && i2.to() == 2) {
continue;
}
Value l1 = i1.location();
Value l2 = i2.location();
if (i1.intersects(i2) && !isIllegal(l1) && (l1.equals(l2))) {
throw GraalError.shouldNotReachHere(String.format("Intervals %d and %d overlap and have the same register assigned\n%s\n%s", i1.operandNumber, i2.operandNumber, i1.logString(this), i2.logString(this)));
}
}
}
}
}
use of org.graalvm.compiler.debug.GraalError in project graal by oracle.
the class LinearScanLifetimeAnalysisPhase method computeGlobalLiveSets.
/**
* Performs a backward dataflow analysis to compute global live sets (i.e.
* {@link BlockData#liveIn} and {@link BlockData#liveOut}) for each block.
*/
@SuppressWarnings("try")
protected void computeGlobalLiveSets() {
try (Indent indent = debug.logAndIndent("compute global live sets")) {
int numBlocks = allocator.blockCount();
boolean changeOccurred;
boolean changeOccurredInBlock;
int iterationCount = 0;
// scratch set for calculations
BitSet liveOut = new BitSet(allocator.liveSetSize());
/*
* Perform a backward dataflow analysis to compute liveOut and liveIn for each block.
* The loop is executed until a fixpoint is reached (no changes in an iteration).
*/
do {
changeOccurred = false;
try (Indent indent2 = debug.logAndIndent("new iteration %d", iterationCount)) {
// iterate all blocks in reverse order
for (int i = numBlocks - 1; i >= 0; i--) {
AbstractBlockBase<?> block = allocator.blockAt(i);
BlockData blockSets = allocator.getBlockData(block);
changeOccurredInBlock = false;
/*
* liveOut(block) is the union of liveIn(sux), for successors sux of block.
*/
int n = block.getSuccessorCount();
if (n > 0) {
liveOut.clear();
// block has successors
if (n > 0) {
for (AbstractBlockBase<?> successor : block.getSuccessors()) {
liveOut.or(allocator.getBlockData(successor).liveIn);
}
}
if (!blockSets.liveOut.equals(liveOut)) {
/*
* A change occurred. Swap the old and new live out sets to avoid
* copying.
*/
BitSet temp = blockSets.liveOut;
blockSets.liveOut = liveOut;
liveOut = temp;
changeOccurred = true;
changeOccurredInBlock = true;
}
}
if (iterationCount == 0 || changeOccurredInBlock) {
/*
* liveIn(block) is the union of liveGen(block) with (liveOut(block) &
* !liveKill(block)).
*
* Note: liveIn has to be computed only in first iteration or if liveOut
* has changed!
*/
BitSet liveIn = blockSets.liveIn;
liveIn.clear();
liveIn.or(blockSets.liveOut);
liveIn.andNot(blockSets.liveKill);
liveIn.or(blockSets.liveGen);
if (debug.isLogEnabled()) {
debug.log("block %d: livein = %s, liveout = %s", block.getId(), liveIn, blockSets.liveOut);
}
}
}
iterationCount++;
if (changeOccurred && iterationCount > 50) {
/*
* Very unlikely, should never happen: If it happens we cannot guarantee it
* won't happen again.
*/
throw new PermanentBailoutException("too many iterations in computeGlobalLiveSets");
}
}
} while (changeOccurred);
if (Assertions.detailedAssertionsEnabled(allocator.getOptions())) {
verifyLiveness();
}
// check that the liveIn set of the first block is empty
AbstractBlockBase<?> startBlock = allocator.getLIR().getControlFlowGraph().getStartBlock();
if (allocator.getBlockData(startBlock).liveIn.cardinality() != 0) {
if (Assertions.detailedAssertionsEnabled(allocator.getOptions())) {
reportFailure(numBlocks);
}
// bailout if this occurs in product mode.
throw new GraalError("liveIn set of first block must be empty: " + allocator.getBlockData(startBlock).liveIn);
}
}
}
Aggregations