use of org.graalvm.compiler.nodes.loop.LoopEx in project graal by oracle.
the class LoopPartialUnrollPhase method checkCounted.
private static boolean checkCounted(StructuredGraph graph, LoopsDataProvider loopsDataProvider, Graph.Mark mark) {
LoopsData dataCounted;
dataCounted = loopsDataProvider.getLoopsData(graph);
dataCounted.detectedCountedLoops();
for (LoopEx anyLoop : dataCounted.loops()) {
if (graph.isNew(mark, anyLoop.loopBegin())) {
assert anyLoop.isCounted() : "pre/post transformation loses counted loop " + anyLoop.loopBegin();
}
}
return true;
}
use of org.graalvm.compiler.nodes.loop.LoopEx in project graal by oracle.
the class LoopPartialUnrollPhase method unroll.
@SuppressWarnings("try")
private void unroll(StructuredGraph graph, CoreProviders context) {
EconomicSetNodeEventListener listener = new EconomicSetNodeEventListener();
boolean changed = true;
EconomicMap<LoopBeginNode, OpaqueNode> opaqueUnrolledStrides = null;
boolean prePostInserted = false;
while (changed) {
changed = false;
try (Graph.NodeEventScope nes = graph.trackNodeEvents(listener)) {
LoopsData dataCounted = context.getLoopsDataProvider().getLoopsData(graph);
dataCounted.detectedCountedLoops();
Graph.Mark mark = graph.getMark();
for (LoopEx loop : dataCounted.countedLoops()) {
if (!LoopTransformations.isUnrollableLoop(loop)) {
continue;
}
if (getPolicies().shouldPartiallyUnroll(loop, context)) {
if (loop.loopBegin().isSimpleLoop()) {
// First perform the pre/post transformation and do the partial
// unroll when we come around again.
LoopTransformations.insertPrePostLoops(loop);
prePostInserted = true;
changed = true;
} else if (prePostInserted) {
if (opaqueUnrolledStrides == null) {
opaqueUnrolledStrides = EconomicMap.create(Equivalence.IDENTITY);
}
LoopTransformations.partialUnroll(loop, opaqueUnrolledStrides);
changed = true;
}
}
}
dataCounted.deleteUnusedNodes();
if (!listener.getNodes().isEmpty()) {
canonicalizer.applyIncremental(graph, context, listener.getNodes());
listener.getNodes().clear();
}
assert !prePostInserted || checkCounted(graph, context.getLoopsDataProvider(), mark);
}
}
if (opaqueUnrolledStrides != null) {
try (Graph.NodeEventScope nes = graph.trackNodeEvents(listener)) {
for (OpaqueNode opaque : opaqueUnrolledStrides.getValues()) {
opaque.remove();
}
if (!listener.getNodes().isEmpty()) {
canonicalizer.applyIncremental(graph, context, listener.getNodes());
}
}
}
}
use of org.graalvm.compiler.nodes.loop.LoopEx in project graal by oracle.
the class LoopSafepointEliminationPhase method run.
@Override
protected final void run(StructuredGraph graph, MidTierContext context) {
LoopsData loops = context.getLoopsDataProvider().getLoopsData(graph);
loops.detectedCountedLoops();
for (LoopEx loop : loops.countedLoops()) {
if (loop.loop().getChildren().isEmpty() && (loop.loopBegin().isPreLoop() || loop.loopBegin().isPostLoop() || loopIsIn32BitRange(loop))) {
boolean hasSafepoint = false;
for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) {
hasSafepoint |= loopEnd.canSafepoint();
}
if (hasSafepoint) {
if (!loop.counted().counterNeverOverflows()) {
// Counter can overflow, need to create a guard.
boolean allowsLoopLimitChecks = context.getOptimisticOptimizations().useLoopLimitChecks(graph.getOptions());
boolean allowsFloatingGuards = graph.getGuardsStage().allowsFloatingGuards();
if (allowsLoopLimitChecks && allowsFloatingGuards) {
loop.counted().createOverFlowGuard();
} else {
// Cannot disable this safepoint, because the loop could overflow.
continue;
}
}
loop.loopBegin().disableSafepoint();
onSafepointDisabledLoopBegin(loop);
}
}
}
for (LoopEx loop : loops.loops()) {
for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) {
Block b = loops.getCFG().blockFor(loopEnd);
blocks: while (b != loop.loop().getHeader()) {
assert b != null;
for (FixedNode node : b.getNodes()) {
boolean canDisableSafepoint = canDisableSafepoint(node, context);
boolean disabledInSubclass = onCallInLoop(loopEnd, node);
if (canDisableSafepoint) {
loopEnd.disableSafepoint();
// we can only stop if subclasses also say we can stop iterating blocks
if (disabledInSubclass) {
break blocks;
}
}
}
b = b.getDominator();
}
}
}
loops.deleteUnusedNodes();
}
use of org.graalvm.compiler.nodes.loop.LoopEx in project graal by oracle.
the class LoopUnswitchingPhase method run.
@Override
protected void run(StructuredGraph graph, CoreProviders context) {
DebugContext debug = graph.getDebug();
if (graph.hasLoops()) {
boolean unswitched;
do {
unswitched = false;
final LoopsData dataUnswitch = context.getLoopsDataProvider().getLoopsData(graph);
for (LoopEx loop : dataUnswitch.outerFirst()) {
if (getPolicies().shouldTryUnswitch(loop)) {
List<ControlSplitNode> controlSplits = LoopTransformations.findUnswitchable(loop);
if (controlSplits != null) {
UNSWITCH_CANDIDATES.increment(debug);
UnswitchingDecision decision = getPolicies().shouldUnswitch(loop, controlSplits);
if (decision.shouldUnswitch()) {
if (debug.isLogEnabled()) {
logUnswitch(loop, controlSplits);
}
LoopTransformations.unswitch(loop, controlSplits, decision.isTrivial());
debug.dump(DebugContext.DETAILED_LEVEL, graph, "After unswitch %s", controlSplits);
UNSWITCHED.increment(debug);
unswitched = true;
break;
}
}
} else {
UNSWITCH_EARLY_REJECTS.increment(debug);
}
}
} while (unswitched);
}
}
use of org.graalvm.compiler.nodes.loop.LoopEx in project graal by oracle.
the class LoopPartialUnrollTest method buildGraph.
@SuppressWarnings("try")
public StructuredGraph buildGraph(String name, boolean partialUnroll) {
CompilationIdentifier id = new CompilationIdentifier() {
@Override
public String toString(Verbosity verbosity) {
return name;
}
};
ResolvedJavaMethod method = getResolvedJavaMethod(name);
OptionValues options = new OptionValues(getInitialOptions(), DefaultLoopPolicies.Options.UnrollMaxIterations, 2);
StructuredGraph graph = parse(builder(method, StructuredGraph.AllowAssumptions.YES, id, options), getEagerGraphBuilderSuite());
try (DebugContext.Scope buildScope = graph.getDebug().scope(name, method, graph)) {
MidTierContext context = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, null);
CanonicalizerPhase canonicalizer = this.createCanonicalizerPhase();
canonicalizer.apply(graph, context);
new RemoveValueProxyPhase().apply(graph);
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
new FloatingReadPhase().apply(graph);
new DeadCodeEliminationPhase().apply(graph);
new ConditionalEliminationPhase(true).apply(graph, context);
new GuardLoweringPhase().apply(graph, context);
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
new FrameStateAssignmentPhase().apply(graph);
new DeoptimizationGroupingPhase().apply(graph, context);
canonicalizer.apply(graph, context);
new ConditionalEliminationPhase(true).apply(graph, context);
if (partialUnroll) {
LoopsData dataCounted = getDefaultMidTierContext().getLoopsDataProvider().getLoopsData(graph);
dataCounted.detectedCountedLoops();
assertTrue(!dataCounted.countedLoops().isEmpty(), "must have counted loops");
for (LoopEx loop : dataCounted.countedLoops()) {
LoopFragmentInside newSegment = loop.inside().duplicate();
newSegment.insertWithinAfter(loop, null);
}
canonicalizer.apply(graph, getDefaultMidTierContext());
}
new DeadCodeEliminationPhase().apply(graph);
canonicalizer.apply(graph, context);
graph.getDebug().dump(DebugContext.BASIC_LEVEL, graph, "before compare");
return graph;
} catch (Throwable e) {
throw getDebugContext().handle(e);
}
}
Aggregations