Skip to content

Commit a143cf6

Browse files
Merge branch 'master' of github.com:roberttoyonaga/graal into ObjectAllocationOutsideTLAB
2 parents 6346158 + 87021fd commit a143cf6

File tree

29 files changed

+1094
-626
lines changed

29 files changed

+1094
-626
lines changed

compiler/src/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LoopUnswitchTest.java

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,4 +390,90 @@ private void test(String snippet, String referenceSnippet, LoopPolicies policies
390390
throw debug.handle(e);
391391
}
392392
}
393+
394+
public static int manySwitch(int limit, int foo) {
395+
int result = 0;
396+
for (int i = 0; i < limit; i++) {
397+
switch (foo) {
398+
case -1:
399+
result += -1;
400+
break;
401+
case 0:
402+
result += 0;
403+
break;
404+
case 1:
405+
result += 1;
406+
break;
407+
case 2:
408+
result += 2;
409+
break;
410+
case 3:
411+
result += 3;
412+
break;
413+
case 4:
414+
result += 4;
415+
break;
416+
case 5:
417+
result += 5;
418+
break;
419+
case 6:
420+
result += 6;
421+
break;
422+
case 7:
423+
result += 7;
424+
break;
425+
case 8:
426+
result += 8;
427+
break;
428+
case 9:
429+
result += 9;
430+
break;
431+
case 10:
432+
result += 10;
433+
break;
434+
case 11:
435+
result += 11;
436+
break;
437+
case 12:
438+
result += 12;
439+
break;
440+
case 13:
441+
result += 13;
442+
break;
443+
case 14:
444+
result += 14;
445+
break;
446+
case 15:
447+
result += 15;
448+
break;
449+
case 16:
450+
result += 16;
451+
break;
452+
case 17:
453+
result += 17;
454+
break;
455+
case 18:
456+
result += 18;
457+
break;
458+
case 19:
459+
result += 19;
460+
break;
461+
case 20:
462+
result += 20;
463+
break;
464+
default:
465+
break;
466+
}
467+
468+
result++;
469+
}
470+
return result;
471+
}
472+
473+
@Test
474+
public void test05() {
475+
final StructuredGraph graph = parseEager("manySwitch", AllowAssumptions.NO);
476+
CanonicalizerPhase canonicalizer = createCanonicalizerPhase();
477+
new LoopUnswitchingPhase(new DefaultLoopPolicies(), canonicalizer).apply(graph, getDefaultHighTierContext());
478+
}
393479
}

compiler/src/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import org.graalvm.compiler.graph.Node.NodeInsertionStackTrace;
4545
import org.graalvm.compiler.graph.Node.ValueNumberable;
4646
import org.graalvm.compiler.graph.iterators.NodeIterable;
47+
import org.graalvm.compiler.graph.iterators.NodePredicate;
4748
import org.graalvm.compiler.options.Option;
4849
import org.graalvm.compiler.options.OptionKey;
4950
import org.graalvm.compiler.options.OptionType;
@@ -464,37 +465,51 @@ public <T extends Node> T addOrUnique(T node) {
464465
return node;
465466
}
466467
if (node.getNodeClass().valueNumberable()) {
467-
return uniqueHelper(node);
468+
return uniqueHelper(node, null);
468469
}
469470
return add(node);
470471
}
471472

472473
public <T extends Node> T addOrUniqueWithInputs(T node) {
474+
return addOrUniqueWithInputs(node, null);
475+
}
476+
477+
public <T extends Node> T addOrUniqueWithInputs(T node, NodePredicate predicate) {
473478
if (node.isAlive()) {
474479
assert node.graph() == this;
475480
return node;
476481
} else {
477482
assert node.isUnregistered();
478-
addInputs(node);
483+
addInputs(node, predicate);
479484
if (node.getNodeClass().valueNumberable()) {
480-
return uniqueHelper(node);
485+
return uniqueHelper(node, predicate);
481486
}
482487
return add(node);
483488
}
484489
}
485490

486491
public <T extends Node> T addWithoutUniqueWithInputs(T node) {
487-
addInputs(node);
492+
addInputs(node, null);
488493
return addHelper(node);
489494
}
490495

491496
private final class AddInputsFilter extends Node.EdgeVisitor {
492497

498+
private final NodePredicate predicate;
499+
500+
AddInputsFilter(NodePredicate predicate) {
501+
this.predicate = predicate;
502+
}
503+
504+
AddInputsFilter() {
505+
this(null);
506+
}
507+
493508
@Override
494509
public Node apply(Node self, Node input) {
495510
if (!input.isAlive()) {
496511
assert !input.isDeleted();
497-
return addOrUniqueWithInputs(input);
512+
return addOrUniqueWithInputs(input, predicate);
498513
} else {
499514
return input;
500515
}
@@ -504,8 +519,12 @@ public Node apply(Node self, Node input) {
504519

505520
private AddInputsFilter addInputsFilter = new AddInputsFilter();
506521

507-
private <T extends Node> void addInputs(T node) {
508-
node.applyInputs(addInputsFilter);
522+
private <T extends Node> void addInputs(T node, NodePredicate predicate) {
523+
if (predicate == null) {
524+
node.applyInputs(addInputsFilter);
525+
} else {
526+
node.applyInputs(new AddInputsFilter(predicate));
527+
}
509528
}
510529

511530
private <T extends Node> T addHelper(T node) {
@@ -736,12 +755,12 @@ public NodeEventScope trackNodeEvents(NodeEventListener listener) {
736755
* @return a node similar to {@code node} if one exists, otherwise {@code node}
737756
*/
738757
public <T extends Node & ValueNumberable> T unique(T node) {
739-
return uniqueHelper(node);
758+
return uniqueHelper(node, null);
740759
}
741760

742-
<T extends Node> T uniqueHelper(T node) {
761+
<T extends Node> T uniqueHelper(T node, NodePredicate predicate) {
743762
assert node.getNodeClass().valueNumberable();
744-
T other = this.findDuplicate(node);
763+
T other = this.findDuplicate(node, predicate);
745764
if (other != null) {
746765
if (other.getNodeSourcePosition() == null) {
747766
other.setNodeSourcePosition(node.getNodeSourcePosition());
@@ -802,18 +821,23 @@ Node findNodeInCache(Node node) {
802821
return result;
803822
}
804823

824+
@SuppressWarnings("unchecked")
825+
public <T extends Node> T findDuplicate(T node) {
826+
return findDuplicate(node, null);
827+
}
828+
805829
/**
806830
* Returns a possible duplicate for the given node in the graph or {@code null} if no such
807-
* duplicate exists.
831+
* duplicate exists. The predicate parameter is used to filter potential results.
808832
*/
809833
@SuppressWarnings("unchecked")
810-
public <T extends Node> T findDuplicate(T node) {
834+
public <T extends Node> T findDuplicate(T node, NodePredicate predicate) {
811835
NodeClass<?> nodeClass = node.getNodeClass();
812836
assert nodeClass.valueNumberable();
813837
if (nodeClass.isLeafNode()) {
814838
// Leaf node: look up in cache
815839
Node cachedNode = findNodeInCache(node);
816-
if (cachedNode != null && cachedNode != node) {
840+
if (cachedNode != null && cachedNode != node && (predicate == null || predicate.apply(cachedNode))) {
817841
return (T) cachedNode;
818842
} else {
819843
return null;
@@ -840,7 +864,7 @@ public <T extends Node> T findDuplicate(T node) {
840864
}
841865
if (minCountNode != null) {
842866
for (Node usage : minCountNode.usages()) {
843-
if (usage != node && nodeClass == usage.getNodeClass() && node.valueEquals(usage) && nodeClass.equalInputs(node, usage) &&
867+
if (usage != node && nodeClass == usage.getNodeClass() && (predicate == null || predicate.apply(usage)) && node.valueEquals(usage) && nodeClass.equalInputs(node, usage) &&
844868
nodeClass.equalSuccessors(node, usage)) {
845869
return (T) usage;
846870
}
@@ -910,13 +934,7 @@ public Mark getMark() {
910934
*/
911935
public NodeIterable<Node> getNewNodes(Mark mark) {
912936
final int index = mark == null ? 0 : mark.getValue();
913-
return new NodeIterable<>() {
914-
915-
@Override
916-
public Iterator<Node> iterator() {
917-
return new GraphNodeIterator(Graph.this, index);
918-
}
919-
};
937+
return () -> new GraphNodeIterator(Graph.this, index);
920938
}
921939

922940
/**

compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,15 +1453,15 @@ protected Node ensureNodeCreated(MethodScope methodScope, LoopScope loopScope, i
14531453
}
14541454

14551455
if (!newNode.isAlive()) {
1456-
newNode = addFloatingNode(methodScope, newNode);
1456+
newNode = addFloatingNode(methodScope, loopScope, newNode);
14571457
}
14581458
node = handleFloatingNodeAfterAdd(methodScope, loopScope, newNode);
14591459
}
14601460
registerNode(loopScope, nodeOrderId, node, false, false);
14611461
return node;
14621462
}
14631463

1464-
protected Node addFloatingNode(@SuppressWarnings("unused") MethodScope methodScope, Node node) {
1464+
protected Node addFloatingNode(@SuppressWarnings("unused") MethodScope methodScope, @SuppressWarnings("unused") LoopScope loopScope, Node node) {
14651465
/*
14661466
* We want to exactly reproduce the encoded graph. Even though nodes should be unique in the
14671467
* encoded graph, this is not always guaranteed.

compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ protected void handleMergeNode(MergeNode merge) {
191191
@Override
192192
protected void handleFixedNode(MethodScope methodScope, LoopScope loopScope, int nodeOrderId, FixedNode node) {
193193
try (DebugCloseable a = CanonicalizeFixedNode.start(debug)) {
194-
Node canonical = canonicalizeFixedNode(methodScope, node);
194+
Node canonical = canonicalizeFixedNode(methodScope, loopScope, node);
195195
if (canonical != node) {
196196
handleCanonicalization(loopScope, nodeOrderId, node, canonical);
197197
}
@@ -203,9 +203,10 @@ protected void handleFixedNode(MethodScope methodScope, LoopScope loopScope, int
203203
* canonicalized (and therefore be a non-fixed node).
204204
*
205205
* @param methodScope The current method.
206+
* @param loopScope The current loop.
206207
* @param originalNode The node to be canonicalized.
207208
*/
208-
protected Node canonicalizeFixedNode(MethodScope methodScope, Node originalNode) {
209+
protected Node canonicalizeFixedNode(MethodScope methodScope, LoopScope loopScope, Node originalNode) {
209210
Node node = originalNode;
210211
if (originalNode instanceof UnsafeAccessNode) {
211212
/*
@@ -403,7 +404,7 @@ protected Node handleFloatingNodeBeforeAdd(MethodScope methodScope, LoopScope lo
403404
}
404405

405406
@Override
406-
protected Node addFloatingNode(MethodScope methodScope, Node node) {
407+
protected Node addFloatingNode(MethodScope methodScope, LoopScope loopScope, Node node) {
407408
/*
408409
* In contrast to the base class implementation, we do not need to exactly reproduce the
409410
* encoded graph. Since we do canonicalization, we also want nodes to be unique.

compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/loop/DefaultLoopPolicies.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,10 @@ public static class Options {
8888
public static final OptionKey<Double> LoopUnswitchMinSplitFrequency = new OptionKey<>(1.0);
8989
@Option(help = "Default frequency for loops with unknown local frequency.", type = OptionType.Expert)
9090
public static final OptionKey<Double> DefaultLoopFrequency = new OptionKey<>(100.0);
91-
@Option(help = "Default unswitching factor for control split node with unkown profile data", type = OptionType.Expert)
91+
@Option(help = "Default unswitching factor for control split node with unkown profile data.", type = OptionType.Expert)
9292
public static final OptionKey<Double> DefaultUnswitchFactor = new OptionKey<>(0.7);
93+
@Option(help = "Maximum number of split successors before aborting unswitching.", type = OptionType.Expert)
94+
public static final OptionKey<Integer> MaxUnswitchSuccessors = new OptionKey<>(64);
9395

9496
@Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> FullUnrollMaxNodes = new OptionKey<>(400);
9597
@Option(help = "", type = OptionType.Expert) public static final OptionKey<Integer> FullUnrollConstantCompareBoost = new OptionKey<>(15);
@@ -293,6 +295,13 @@ private static int approxCodeSizeChange(LoopEx loop, List<ControlSplitNode> cont
293295
StructuredGraph graph = loop.loopBegin().graph();
294296
NodeBitMap branchNodes = graph.createNodeBitMap();
295297
for (ControlSplitNode controlSplit : controlSplits) {
298+
if (controlSplit.getSuccessorCount() > Options.MaxUnswitchSuccessors.getValue(graph.getOptions())) {
299+
/*
300+
* Computing the code size increase can result in complexity issues already, abort
301+
* this split.
302+
*/
303+
return Integer.MAX_VALUE;
304+
}
296305
for (Node successor : controlSplit.successors()) {
297306
AbstractBeginNode branch = (AbstractBeginNode) successor;
298307
// this may count twice because of fall-through in switches

compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/loop/LoopEx.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@
5353
import org.graalvm.compiler.nodes.NodeView;
5454
import org.graalvm.compiler.nodes.PhiNode;
5555
import org.graalvm.compiler.nodes.PiNode;
56+
import org.graalvm.compiler.nodes.ProfileData.ProfileSource;
5657
import org.graalvm.compiler.nodes.StructuredGraph;
5758
import org.graalvm.compiler.nodes.ValueNode;
5859
import org.graalvm.compiler.nodes.ValuePhiNode;
59-
import org.graalvm.compiler.nodes.ProfileData.ProfileSource;
6060
import org.graalvm.compiler.nodes.calc.AddNode;
6161
import org.graalvm.compiler.nodes.calc.BinaryArithmeticNode;
6262
import org.graalvm.compiler.nodes.calc.CompareNode;
@@ -67,8 +67,8 @@
6767
import org.graalvm.compiler.nodes.calc.SignExtendNode;
6868
import org.graalvm.compiler.nodes.calc.SubNode;
6969
import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
70-
import org.graalvm.compiler.nodes.cfg.HIRBlock;
7170
import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
71+
import org.graalvm.compiler.nodes.cfg.HIRBlock;
7272
import org.graalvm.compiler.nodes.debug.ControlFlowAnchored;
7373
import org.graalvm.compiler.nodes.debug.NeverStripMineNode;
7474
import org.graalvm.compiler.nodes.debug.NeverWriteSinkNode;
@@ -399,7 +399,9 @@ public void nodesInLoopBranch(NodeBitMap branchNodes, AbstractBeginNode branch)
399399
Collection<AbstractBeginNode> exits = new LinkedList<>();
400400
Queue<HIRBlock> work = new LinkedList<>();
401401
ControlFlowGraph cfg = loopsData().getCFG();
402-
work.add(cfg.blockFor(branch));
402+
NodeBitMap visited = cfg.graph.createNodeBitMap();
403+
HIRBlock firstSuccBlock = cfg.blockFor(branch);
404+
work.add(firstSuccBlock);
403405
while (!work.isEmpty()) {
404406
HIRBlock b = work.remove();
405407
if (loop().isLoopExit(b)) {
@@ -408,8 +410,16 @@ public void nodesInLoopBranch(NodeBitMap branchNodes, AbstractBeginNode branch)
408410
} else if (blocks.add(b.getBeginNode())) {
409411
HIRBlock d = b.getDominatedSibling();
410412
while (d != null) {
411-
if (loop.getBlocks().contains(d)) {
412-
work.add(d);
413+
/*
414+
* if the post dominator is reachable via a branch block it means it was a merge
415+
* of the current split. this is generally not part of the branch, but after the
416+
* branch.
417+
*/
418+
if (loop.getBlocks().contains(d) && firstSuccBlock.getPostdominator() != d) {
419+
if (!visited.isMarked(d.getBeginNode())) {
420+
visited.mark(d.getBeginNode());
421+
work.add(d);
422+
}
413423
}
414424
d = d.getDominatedSibling();
415425
}

0 commit comments

Comments
 (0)