use of org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult in project graal by oracle.
the class MemoryScheduleTest method testStringHashCode.
@Test
public void testStringHashCode() {
ScheduleResult schedule = getFinalSchedule("testStringHashCodeSnippet", TestMode.WITHOUT_FRAMESTATES);
assertReadWithinStartBlock(schedule, true);
assertReadWithinAllReturnBlocks(schedule, false);
hash = 0x1337;
value[0] = 'a';
value[1] = 'b';
value[2] = 'c';
test("testStringHashCodeSnippet");
}
use of org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult in project graal by oracle.
the class MemoryScheduleTest method testLoop7.
@Test
public void testLoop7() {
ScheduleResult schedule = getFinalSchedule("testLoop7Snippet", TestMode.WITHOUT_FRAMESTATES);
assertDeepEquals(18, schedule.getCFG().getBlocks().length);
assertReadWithinStartBlock(schedule, false);
assertReadWithinAllReturnBlocks(schedule, false);
}
use of org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult in project graal by oracle.
the class GraalCompiler method emitLIR0.
@SuppressWarnings("try")
private static LIRGenerationResult emitLIR0(Backend backend, StructuredGraph graph, Object stub, RegisterConfig registerConfig, LIRSuites lirSuites, String[] allocationRestrictedTo) {
DebugContext debug = graph.getDebug();
try (DebugContext.Scope ds = debug.scope("EmitLIR");
DebugCloseable a = EmitLIR.start(debug)) {
assert !graph.hasValueProxies();
ScheduleResult schedule = graph.getLastSchedule();
Block[] blocks = schedule.getCFG().getBlocks();
Block startBlock = schedule.getCFG().getStartBlock();
assert startBlock != null;
assert startBlock.getPredecessorCount() == 0;
AbstractBlockBase<?>[] codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock);
AbstractBlockBase<?>[] linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock);
LIR lir = new LIR(schedule.getCFG(), linearScanOrder, codeEmittingOrder, graph.getOptions(), graph.getDebug());
FrameMapBuilder frameMapBuilder = backend.newFrameMapBuilder(registerConfig);
LIRGenerationResult lirGenRes = backend.newLIRGenerationResult(graph.compilationId(), lir, frameMapBuilder, graph, stub);
LIRGeneratorTool lirGen = backend.newLIRGenerator(lirGenRes);
NodeLIRBuilderTool nodeLirGen = backend.newNodeLIRBuilder(graph, lirGen);
// LIR generation
LIRGenerationContext context = new LIRGenerationContext(lirGen, nodeLirGen, graph, schedule);
new LIRGenerationPhase().apply(backend.getTarget(), lirGenRes, context);
try (DebugContext.Scope s = debug.scope("LIRStages", nodeLirGen, lirGenRes, lir)) {
// Dump LIR along with HIR (the LIR is looked up from context)
debug.dump(DebugContext.BASIC_LEVEL, graph.getLastSchedule(), "After LIR generation");
LIRGenerationResult result = emitLowLevel(backend.getTarget(), lirGenRes, lirGen, lirSuites, backend.newRegisterAllocationConfig(registerConfig, allocationRestrictedTo));
return result;
} catch (Throwable e) {
throw debug.handle(e);
}
} catch (Throwable e) {
throw debug.handle(e);
} finally {
graph.checkCancellation();
}
}
use of org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult in project graal by oracle.
the class GraphOrder method assertSchedulableGraph.
/**
* This method schedules the graph and makes sure that, for every node, all inputs are available
* at the position where it is scheduled. This is a very expensive assertion.
*/
public static boolean assertSchedulableGraph(final StructuredGraph graph) {
assert graph.getGuardsStage() != GuardsStage.AFTER_FSA : "Cannot use the BlockIteratorClosure after FrameState Assignment, HIR Loop Data Structures are no longer valid.";
try {
final SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS, true);
final EconomicMap<LoopBeginNode, NodeBitMap> loopEntryStates = EconomicMap.create(Equivalence.IDENTITY);
schedulePhase.apply(graph, false);
final ScheduleResult schedule = graph.getLastSchedule();
BlockIteratorClosure<NodeBitMap> closure = new BlockIteratorClosure<NodeBitMap>() {
@Override
protected List<NodeBitMap> processLoop(Loop<Block> loop, NodeBitMap initialState) {
return ReentrantBlockIterator.processLoop(this, loop, initialState).exitStates;
}
@Override
protected NodeBitMap processBlock(final Block block, final NodeBitMap currentState) {
final List<Node> list = graph.getLastSchedule().getBlockToNodesMap().get(block);
/*
* A stateAfter is not valid directly after its associated state split, but
* right before the next fixed node. Therefore a pending stateAfter is kept that
* will be checked at the correct position.
*/
FrameState pendingStateAfter = null;
for (final Node node : list) {
if (node instanceof ValueNode) {
FrameState stateAfter = node instanceof StateSplit ? ((StateSplit) node).stateAfter() : null;
if (node instanceof FullInfopointNode) {
stateAfter = ((FullInfopointNode) node).getState();
}
if (pendingStateAfter != null && node instanceof FixedNode) {
pendingStateAfter.applyToNonVirtual(new NodeClosure<Node>() {
@Override
public void apply(Node usage, Node nonVirtualNode) {
assert currentState.isMarked(nonVirtualNode) || nonVirtualNode instanceof VirtualObjectNode || nonVirtualNode instanceof ConstantNode : nonVirtualNode + " not available at virtualstate " + usage + " before " + node + " in block " + block + " \n" + list;
}
});
pendingStateAfter = null;
}
if (node instanceof AbstractMergeNode) {
// phis aren't scheduled, so they need to be added explicitly
currentState.markAll(((AbstractMergeNode) node).phis());
if (node instanceof LoopBeginNode) {
// remember the state at the loop entry, it's restored at exits
loopEntryStates.put((LoopBeginNode) node, currentState.copy());
}
} else if (node instanceof ProxyNode) {
assert false : "proxy nodes should not be in the schedule";
} else if (node instanceof LoopExitNode) {
if (graph.hasValueProxies()) {
for (ProxyNode proxy : ((LoopExitNode) node).proxies()) {
for (Node input : proxy.inputs()) {
if (input != proxy.proxyPoint()) {
assert currentState.isMarked(input) : input + " not available at " + proxy + " in block " + block + "\n" + list;
}
}
}
// loop contents are only accessible via proxies at the exit
currentState.clearAll();
currentState.markAll(loopEntryStates.get(((LoopExitNode) node).loopBegin()));
}
// Loop proxies aren't scheduled, so they need to be added
// explicitly
currentState.markAll(((LoopExitNode) node).proxies());
} else {
for (Node input : node.inputs()) {
if (input != stateAfter) {
if (input instanceof FrameState) {
((FrameState) input).applyToNonVirtual(new VirtualState.NodeClosure<Node>() {
@Override
public void apply(Node usage, Node nonVirtual) {
assert currentState.isMarked(nonVirtual) : nonVirtual + " not available at " + node + " in block " + block + "\n" + list;
}
});
} else {
assert currentState.isMarked(input) || input instanceof VirtualObjectNode || input instanceof ConstantNode : input + " not available at " + node + " in block " + block + "\n" + list;
}
}
}
}
if (node instanceof AbstractEndNode) {
AbstractMergeNode merge = ((AbstractEndNode) node).merge();
for (PhiNode phi : merge.phis()) {
ValueNode phiValue = phi.valueAt((AbstractEndNode) node);
assert phiValue == null || currentState.isMarked(phiValue) || phiValue instanceof ConstantNode : phiValue + " not available at phi " + phi + " / end " + node + " in block " + block;
}
}
if (stateAfter != null) {
assert pendingStateAfter == null;
pendingStateAfter = stateAfter;
}
currentState.mark(node);
}
}
if (pendingStateAfter != null) {
pendingStateAfter.applyToNonVirtual(new NodeClosure<Node>() {
@Override
public void apply(Node usage, Node nonVirtualNode) {
assert currentState.isMarked(nonVirtualNode) || nonVirtualNode instanceof VirtualObjectNode || nonVirtualNode instanceof ConstantNode : nonVirtualNode + " not available at virtualstate " + usage + " at end of block " + block + " \n" + list;
}
});
}
return currentState;
}
@Override
protected NodeBitMap merge(Block merge, List<NodeBitMap> states) {
NodeBitMap result = states.get(0);
for (int i = 1; i < states.size(); i++) {
result.intersect(states.get(i));
}
return result;
}
@Override
protected NodeBitMap getInitialState() {
NodeBitMap ret = graph.createNodeBitMap();
ret.markAll(graph.getNodes().filter(ConstantNode.class));
return ret;
}
@Override
protected NodeBitMap cloneState(NodeBitMap oldState) {
return oldState.copy();
}
};
ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock());
} catch (Throwable t) {
graph.getDebug().handle(t);
}
return true;
}
use of org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult in project graal by oracle.
the class EffectsPhase method runAnalysis.
@SuppressWarnings("try")
public boolean runAnalysis(StructuredGraph graph, PhaseContextT context) {
boolean changed = false;
CompilationAlarm compilationAlarm = CompilationAlarm.current();
DebugContext debug = graph.getDebug();
for (int iteration = 0; iteration < maxIterations && !compilationAlarm.hasExpired(); iteration++) {
try (DebugContext.Scope s = debug.scope(debug.areScopesEnabled() ? "iteration " + iteration : null)) {
ScheduleResult schedule;
ControlFlowGraph cfg;
if (unscheduled) {
schedule = null;
cfg = ControlFlowGraph.compute(graph, true, true, false, false);
} else {
new SchedulePhase(SchedulePhase.SchedulingStrategy.EARLIEST).apply(graph, false);
schedule = graph.getLastSchedule();
cfg = schedule.getCFG();
}
try (DebugContext.Scope scheduleScope = debug.scope("EffectsPhaseWithSchedule", schedule)) {
Closure<?> closure = createEffectsClosure(context, schedule, cfg);
ReentrantBlockIterator.apply(closure, cfg.getStartBlock());
if (closure.needsApplyEffects()) {
// apply the effects collected during this iteration
HashSetNodeEventListener listener = new HashSetNodeEventListener();
try (NodeEventScope nes = graph.trackNodeEvents(listener)) {
closure.applyEffects();
}
if (debug.isDumpEnabled(DebugContext.VERBOSE_LEVEL)) {
debug.dump(DebugContext.VERBOSE_LEVEL, graph, "%s iteration", getName());
}
new DeadCodeEliminationPhase(Required).apply(graph);
EconomicSet<Node> changedNodes = listener.getNodes();
for (Node node : graph.getNodes()) {
if (node instanceof Simplifiable) {
changedNodes.add(node);
}
}
postIteration(graph, context, changedNodes);
}
if (closure.hasChanged()) {
changed = true;
} else {
break;
}
} catch (Throwable t) {
throw debug.handle(t);
}
}
}
return changed;
}
Aggregations