use of org.graalvm.compiler.java.BciBlockMapping.BciBlock in project graal by oracle.
the class BytecodeParser method genIf.
protected void genIf(LogicNode conditionInput, BciBlock trueBlockInput, BciBlock falseBlockInput, double probabilityInput) {
BciBlock trueBlock = trueBlockInput;
BciBlock falseBlock = falseBlockInput;
LogicNode condition = conditionInput;
double probability = probabilityInput;
FrameState stateBefore = null;
ProfilingPlugin profilingPlugin = this.graphBuilderConfig.getPlugins().getProfilingPlugin();
if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
}
// Remove a logic negation node.
if (condition instanceof LogicNegationNode) {
LogicNegationNode logicNegationNode = (LogicNegationNode) condition;
BciBlock tmpBlock = trueBlock;
trueBlock = falseBlock;
falseBlock = tmpBlock;
probability = 1 - probability;
condition = logicNegationNode.getValue();
}
if (condition instanceof LogicConstantNode) {
genConstantTargetIf(trueBlock, falseBlock, condition);
} else {
if (condition.graph() == null) {
condition = genUnique(condition);
}
if (isNeverExecutedCode(probability)) {
append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, true));
if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
profilingPlugin.profileGoto(this, method, bci(), falseBlock.startBci, stateBefore);
}
appendGoto(falseBlock);
return;
} else if (isNeverExecutedCode(1 - probability)) {
append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, false));
if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
profilingPlugin.profileGoto(this, method, bci(), trueBlock.startBci, stateBefore);
}
appendGoto(trueBlock);
return;
}
if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
profilingPlugin.profileIf(this, method, bci(), condition, trueBlock.startBci, falseBlock.startBci, stateBefore);
}
int oldBci = stream.currentBCI();
int trueBlockInt = checkPositiveIntConstantPushed(trueBlock);
if (trueBlockInt != -1) {
int falseBlockInt = checkPositiveIntConstantPushed(falseBlock);
if (falseBlockInt != -1) {
if (tryGenConditionalForIf(trueBlock, falseBlock, condition, oldBci, trueBlockInt, falseBlockInt)) {
return;
}
}
}
this.controlFlowSplit = true;
FixedNode trueSuccessor = createTarget(trueBlock, frameState, false, false);
FixedNode falseSuccessor = createTarget(falseBlock, frameState, false, true);
ValueNode ifNode = genIfNode(condition, trueSuccessor, falseSuccessor, probability);
postProcessIfNode(ifNode);
append(ifNode);
}
}
use of org.graalvm.compiler.java.BciBlockMapping.BciBlock in project graal by oracle.
the class BytecodeParser method genInstanceOf.
private void genInstanceOf() {
int cpi = getStream().readCPI();
JavaType type = lookupType(cpi, INSTANCEOF);
ValueNode object = frameState.pop(JavaKind.Object);
if (!(type instanceof ResolvedJavaType)) {
handleUnresolvedInstanceOf(type, object);
return;
}
TypeReference resolvedType = TypeReference.createTrusted(graph.getAssumptions(), (ResolvedJavaType) type);
JavaTypeProfile profile = getProfileForTypeCheck(resolvedType);
for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
if (plugin.handleInstanceOf(this, object, resolvedType.getType(), profile)) {
return;
}
}
LogicNode instanceOfNode = null;
if (profile != null) {
if (profile.getNullSeen().isFalse()) {
object = nullCheckedValue(object);
ResolvedJavaType singleType = profile.asSingleType();
if (singleType != null) {
LogicNode typeCheck = append(createInstanceOf(TypeReference.createExactTrusted(singleType), object, profile));
if (!typeCheck.isTautology()) {
append(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile));
}
instanceOfNode = LogicConstantNode.forBoolean(resolvedType.getType().isAssignableFrom(singleType));
}
}
}
if (instanceOfNode == null) {
instanceOfNode = createInstanceOf(resolvedType, object, null);
}
LogicNode logicNode = genUnique(instanceOfNode);
int next = getStream().nextBCI();
int value = getStream().readUByte(next);
if (next <= currentBlock.endBci && (value == Bytecodes.IFEQ || value == Bytecodes.IFNE)) {
getStream().next();
BciBlock firstSucc = currentBlock.getSuccessor(0);
BciBlock secondSucc = currentBlock.getSuccessor(1);
if (firstSucc != secondSucc) {
boolean negate = value != Bytecodes.IFNE;
if (negate) {
BciBlock tmp = firstSucc;
firstSucc = secondSucc;
secondSucc = tmp;
}
genIf(instanceOfNode, firstSucc, secondSucc, getProfileProbability(negate));
} else {
appendGoto(firstSucc);
}
} else {
// Most frequent for value is IRETURN, followed by ISTORE.
frameState.push(JavaKind.Int, append(genConditional(logicNode)));
}
}
use of org.graalvm.compiler.java.BciBlockMapping.BciBlock 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.java.BciBlockMapping.BciBlock in project graal by oracle.
the class BytecodeParser method genConstantTargetIf.
private void genConstantTargetIf(BciBlock trueBlock, BciBlock falseBlock, LogicNode condition) {
LogicConstantNode constantLogicNode = (LogicConstantNode) condition;
boolean value = constantLogicNode.getValue();
BciBlock nextBlock = falseBlock;
if (value) {
nextBlock = trueBlock;
}
int startBci = nextBlock.startBci;
int targetAtStart = stream.readUByte(startBci);
if (targetAtStart == Bytecodes.GOTO && nextBlock.getPredecessorCount() == 1) {
// This is an empty block. Skip it.
BciBlock successorBlock = nextBlock.successors.get(0);
ProfilingPlugin profilingPlugin = graphBuilderConfig.getPlugins().getProfilingPlugin();
if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
FrameState stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
profilingPlugin.profileGoto(this, method, bci(), successorBlock.startBci, stateBefore);
}
appendGoto(successorBlock);
assert nextBlock.numNormalSuccessors() == 1;
} else {
ProfilingPlugin profilingPlugin = graphBuilderConfig.getPlugins().getProfilingPlugin();
if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
FrameState stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
profilingPlugin.profileGoto(this, method, bci(), nextBlock.startBci, stateBefore);
}
appendGoto(nextBlock);
}
}
use of org.graalvm.compiler.java.BciBlockMapping.BciBlock in project graal by oracle.
the class BytecodeParser method genJsr.
protected void genJsr(int dest) {
BciBlock successor = currentBlock.getJsrSuccessor();
assert successor.startBci == dest : successor.startBci + " != " + dest + " @" + bci();
JsrScope scope = currentBlock.getJsrScope();
int nextBci = getStream().nextBCI();
if (!successor.getJsrScope().pop().equals(scope)) {
throw new JsrNotSupportedBailout("unstructured control flow (internal limitation)");
}
if (successor.getJsrScope().nextReturnAddress() != nextBci) {
throw new JsrNotSupportedBailout("unstructured control flow (internal limitation)");
}
ConstantNode nextBciNode = getJsrConstant(nextBci);
frameState.push(JavaKind.Object, nextBciNode);
appendGoto(successor);
}
Aggregations