Skip to content

Commit f938bfa

Browse files
committed
[GR-46730] Make StackifierIRWalker extensible.
PullRequest: graal/14845
2 parents 0dc3de1 + 323aa58 commit f938bfa

File tree

1 file changed

+75
-66
lines changed

1 file changed

+75
-66
lines changed

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/hightiercodegen/irwalk/StackifierIRWalker.java

Lines changed: 75 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.graalvm.compiler.nodes.ControlSinkNode;
5252
import org.graalvm.compiler.nodes.ControlSplitNode;
5353
import org.graalvm.compiler.nodes.EndNode;
54+
import org.graalvm.compiler.nodes.FixedNode;
5455
import org.graalvm.compiler.nodes.IfNode;
5556
import org.graalvm.compiler.nodes.InvokeWithExceptionNode;
5657
import org.graalvm.compiler.nodes.LoopBeginNode;
@@ -77,9 +78,12 @@ public class StackifierIRWalker extends IRWalker {
7778
public static final String LABEL_PREFIX = "looplabel_";
7879
protected final BlockNestingVerifier blockNestingVerifier;
7980

81+
protected final StackifierData stackifierData;
82+
8083
public StackifierIRWalker(CodeGenTool codeGenTool, ControlFlowGraph cfg, BlockMap<List<Node>> blockToNodeMap, NodeMap<HIRBlock> nodeToBlockMap, ReconstructionData reconstructionData) {
8184
super(codeGenTool, cfg, blockToNodeMap, nodeToBlockMap, reconstructionData);
8285
this.blockNestingVerifier = new BlockNestingVerifier();
86+
this.stackifierData = (StackifierData) reconstructionData;
8387
}
8488

8589
/**
@@ -155,7 +159,7 @@ public StackifierIRWalker(CodeGenTool codeGenTool, ControlFlowGraph cfg, BlockMa
155159
* via {@code continue} statements. As a side note, the end of a loop has an implicit back-edge.
156160
* Since all back-edges are handled via {@link LoopEndNode} and the corresponding
157161
* {@code continue} statement we place a {@code break} at the end of the loop to avoid this
158-
* backwards jump, see {@link #lowerLoopStackifier(StackifierData, HIRBlock)}.
162+
* backwards jump, see {@link #lowerLoop(HIRBlock)}.
159163
*
160164
* Now an example where we assume {@code A()} might produce an exception
161165
*
@@ -193,7 +197,6 @@ public StackifierIRWalker(CodeGenTool codeGenTool, ControlFlowGraph cfg, BlockMa
193197
@Override
194198
@SuppressWarnings({"unused", "try"})
195199
protected void lower(DebugContext debugContext) {
196-
StackifierData stackifierData = (StackifierData) reconstructionData;
197200
stackifierData.debugDump(debugContext);
198201

199202
predeclareVariables(cfg.graph);
@@ -221,9 +224,7 @@ protected void predeclareVariables(StructuredGraph graph) {
221224
*
222225
* @param blocks blocks to be lowered
223226
*/
224-
@SuppressWarnings("deprecated")
225-
private void lowerBlocks(HIRBlock[] blocks) {
226-
StackifierData stackifierData = (StackifierData) reconstructionData;
227+
protected void lowerBlocks(HIRBlock[] blocks) {
227228
for (HIRBlock currentBlock : blocks) {
228229
if (blockHistory.blockVisited(currentBlock)) {
229230
continue;
@@ -255,15 +256,18 @@ private void lowerBlocks(HIRBlock[] blocks) {
255256
}
256257
}
257258

258-
LabeledBlock blockEnd = stackifierData.labeledBlockEnd(currentBlock);
259-
260259
/*
261260
* Generate the end of the labeled block before a possible loop header as well as all
262261
* labeled blocks that need to start before the loop header.
263262
*/
264263
if (!isInRecursiveLoopCall(isLoopHeader, currentBlock, blocks)) {
265264
// generate end of forward blocks
266-
genLabeledBlockEnd(blockEnd);
265+
LabeledBlock blockEnd = stackifierData.labeledBlockEnd(currentBlock);
266+
if (blockEnd != null) {
267+
genLabeledBlockEnd(blockEnd);
268+
}
269+
270+
// Open labeled blocks before loop header
267271
labeledBlockStartsBeforeLoop.forEach(this::genLabeledBlockHeader);
268272
}
269273

@@ -273,12 +277,13 @@ private void lowerBlocks(HIRBlock[] blocks) {
273277
* first basic block. If it does, we are already in that recursive call.
274278
*/
275279
if (newLoopStartsHere(isLoopHeader, currentBlock, blocks)) {
276-
lowerLoopStackifier(stackifierData, currentBlock);
280+
lowerLoop(currentBlock);
277281
continue;
278282
}
279283

280284
codeGenTool.genComment("Start of block " + currentBlock);
281285

286+
// Open labeled blocks after loop header
282287
labeledBlockStartsAfterLoop.forEach(this::genLabeledBlockHeader);
283288

284289
for (Node node : blockToNodeMap.get(currentBlock)) {
@@ -287,8 +292,8 @@ private void lowerBlocks(HIRBlock[] blocks) {
287292
} else if (node instanceof LoopBeginNode) {
288293
/*
289294
* We should only be able to visit a LoopBeginNode if we are recursively called
290-
* from lowerLoopStackifier and as such the node can be ignored since
291-
* lowerLoopStackifier already emitted the loop header.
295+
* from lowerLoop and as such the node can be ignored since lowerLoop already
296+
* emitted the loop header.
292297
*/
293298
assert currentBlock == blocks[0];
294299
} else if (!(node instanceof LoopExitNode)) {
@@ -298,35 +303,24 @@ private void lowerBlocks(HIRBlock[] blocks) {
298303
verifier.visitNode(node, codeGenTool);
299304
}
300305

301-
Node lastNode = currentBlock.getEndNode();
306+
FixedNode lastNode = currentBlock.getEndNode();
302307
if (lastNode instanceof ControlSinkNode) {
303308
lowerNode(lastNode);
304-
} else if (lastNode instanceof IfNode) {
305-
lowerIfStackifier(currentBlock, (IfNode) lastNode);
306-
} else if (lastNode instanceof IntegerSwitchNode) {
307-
lowerSwitch((IntegerSwitchNode) lastNode, stackifierData);
308-
} else if (lastNode instanceof TypeSwitchNode) {
309-
lowerTypeSwitch((TypeSwitchNode) lastNode, stackifierData);
309+
} else if (lastNode instanceof IfNode ifNode) {
310+
lowerIf(currentBlock, ifNode);
311+
} else if (lastNode instanceof IntegerSwitchNode switchNode) {
312+
lowerSwitch(switchNode);
313+
} else if (lastNode instanceof TypeSwitchNode switchNode) {
314+
lowerTypeSwitch(switchNode);
310315
} else if (isWithExceptionNode(lastNode)) {
311-
lowerWithExceptionStackifier(currentBlock, (WithExceptionNode) lastNode);
316+
lowerWithException(currentBlock, (WithExceptionNode) lastNode);
312317
} else if ((lastNode instanceof ControlSplitNode) && !(lastNode instanceof BasicArrayCopyNode)) {
313318
// BasicArrayCopyNode is also a ControlSplitNode
314319
assert false : "Unsupported control split node " + lastNode + " is not implemented yet";
315-
} else if (lastNode instanceof LoopEndNode) {
316-
lowerLoopEndResolver((LoopEndNode) lastNode);
317-
codeGenTool.genLoopContinue();
320+
} else if (lastNode instanceof LoopEndNode loopEnd) {
321+
lowerLoopEnd(loopEnd);
318322
} else {
319-
if (!(lastNode instanceof LoopExitNode) && !(lastNode instanceof LoopBeginNode)) {
320-
/*
321-
* Special case for basic blocks with only one node. LoopExitNode and
322-
* LoopBeginNode need to be handled separately again, as they must not be
323-
* lowered by the node lowerer.
324-
*/
325-
lowerNode(lastNode);
326-
}
327-
HIRBlock successor = nodeToBlockMap.get(lastNode.cfgSuccessors().iterator().next());
328-
generateForwardJump(currentBlock, successor, stackifierData);
329-
323+
lowerUnhandledBlockEnd(currentBlock, lastNode);
330324
}
331325

332326
verifier.visitNode(lastNode, codeGenTool);
@@ -337,8 +331,7 @@ private void lowerBlocks(HIRBlock[] blocks) {
337331

338332
/**
339333
* Whether the lowering of the given currentBlock happens inside a recursive call from
340-
* {@link #lowerLoopStackifier(StackifierData, HIRBlock)} and the current block is the start of
341-
* the loop.
334+
* {@link #lowerLoop(HIRBlock)} and the current block is the start of the loop.
342335
*
343336
* If this is true, the loop header was already emitted otherwise it hasn't.
344337
*/
@@ -359,9 +352,8 @@ protected boolean isWithExceptionNode(Node lastNode) {
359352
*
360353
* @param currentBlock block from which to jump from
361354
* @param successor target of the jump
362-
* @param stackifierData stackifier data
363355
*/
364-
private void generateForwardJump(HIRBlock currentBlock, HIRBlock successor, StackifierData stackifierData) {
356+
private void generateForwardJump(HIRBlock currentBlock, HIRBlock successor) {
365357
if (LabeledBlockGeneration.isNormalLoopExit(currentBlock, successor, stackifierData)) {
366358
Loop<HIRBlock> loop = currentBlock.getLoop();
367359
Scope loopScope = ((LoopScopeContainer) stackifierData.getScopeEntry(loop.getHeader().getBeginNode())).getLoopScope();
@@ -428,11 +420,10 @@ private void generateForwardJump(HIRBlock currentBlock, HIRBlock successor, Stac
428420
* we want is to go to {@code C()}. Therefore a {@code break} is inserted at the loop end which
429421
* makes the back-edge at the end of the loop unreachable and adds a loop exit.
430422
*
431-
* @param stackifierData data generated by the stackifier reconstruction algorithm
432423
* @param currentBlock current block
433424
*/
434-
private void lowerLoopStackifier(StackifierData stackifierData, HIRBlock currentBlock) {
435-
assert currentBlock.getBeginNode() instanceof LoopBeginNode;
425+
protected void lowerLoop(HIRBlock currentBlock) {
426+
assert currentBlock.isLoopHeader();
436427
LoopScopeContainer loopScopeEntry = (LoopScopeContainer) stackifierData.getScopeEntry(currentBlock.getBeginNode());
437428
Scope loopScope = loopScopeEntry.getLoopScope();
438429

@@ -442,15 +433,19 @@ private void lowerLoopStackifier(StackifierData stackifierData, HIRBlock current
442433
genLoopEnd(currentBlock);
443434
}
444435

436+
protected void lowerLoopEnd(LoopEndNode loopEnd) {
437+
lowerLoopEndResolver(loopEnd);
438+
codeGenTool.genLoopContinue();
439+
}
440+
445441
/**
446442
* Lower a WithExceptionNode. For an example how the generated code looks like, see
447443
* {@link #lower(DebugContext)}.
448444
*
449445
* @param currentBlock basic block that contains {@link WithExceptionNode}
450446
* @param lastNode the {@link WithExceptionNode}
451447
*/
452-
private void lowerWithExceptionStackifier(HIRBlock currentBlock, WithExceptionNode lastNode) {
453-
StackifierData stackifierData = (StackifierData) reconstructionData;
448+
protected void lowerWithException(HIRBlock currentBlock, WithExceptionNode lastNode) {
454449
HIRBlock normSucc = cfg.blockFor(lastNode.next());
455450
HIRBlock excpSucc = cfg.blockFor(lastNode.exceptionEdge());
456451
CatchScopeContainer scopeEntry = (CatchScopeContainer) stackifierData.getScopeEntry(lastNode);
@@ -463,7 +458,7 @@ private void lowerWithExceptionStackifier(HIRBlock currentBlock, WithExceptionNo
463458
* once it is encountered in its own basic block.
464459
*/
465460
lowerNode(lastNode);
466-
generateForwardJump(currentBlock, normSucc, stackifierData);
461+
generateForwardJump(currentBlock, normSucc);
467462

468463
String caughtObjectName = codeGenTool.getExceptionObjectId(excpSucc.getBeginNode());
469464
ResolvedJavaType caughtObjectType = codeGenTool.getProviders().getMetaAccess().lookupJavaType(Throwable.class);
@@ -473,15 +468,15 @@ private void lowerWithExceptionStackifier(HIRBlock currentBlock, WithExceptionNo
473468
* the caught object is set to Throwable, and only changed if the exception edge indeed is
474469
* an ExceptionObjectNode
475470
*/
476-
if (excpSucc.getBeginNode()instanceof ExceptionObjectNode excpObj) {
471+
if (excpSucc.getBeginNode() instanceof ExceptionObjectNode excpObj) {
477472
caughtObjectType = excpObj.stamp(NodeView.DEFAULT).javaType(codeGenTool.getProviders().getMetaAccess());
478473
}
479474
codeGenTool.genCatchBlockPrefix(caughtObjectName, caughtObjectType);
480475

481476
if (catchScope != null) {
482477
lowerBlocks(catchScope.getSortedBlocks());
483478
} else {
484-
generateForwardJump(currentBlock, excpSucc, stackifierData);
479+
generateForwardJump(currentBlock, excpSucc);
485480
}
486481
codeGenTool.genScopeEnd();
487482
}
@@ -497,28 +492,46 @@ protected void lowerIfHeader(IfNode ifNode) {
497492
* @param currentBlock basic block containing the {@link IfNode}
498493
* @param lastNode the {@link IfNode}
499494
*/
500-
private void lowerIfStackifier(HIRBlock currentBlock, IfNode lastNode) {
501-
StackifierData stackifierData = (StackifierData) reconstructionData;
502-
HIRBlock trueBlock = nodeToBlockMap.get(lastNode.trueSuccessor());
503-
HIRBlock falseBlock = nodeToBlockMap.get(lastNode.falseSuccessor());
495+
protected void lowerIf(HIRBlock currentBlock, IfNode lastNode) {
504496
IfScopeContainer ifScopeContainer = (IfScopeContainer) stackifierData.getScopeEntry(lastNode);
505497
Scope thenScope = ifScopeContainer.getThenScope();
506498
Scope elseScope = ifScopeContainer.getElseScope();
507499
lowerIfHeader(lastNode);
508500
if (thenScope != null) {
509501
lowerBlocks(thenScope.getSortedBlocks());
510502
} else {
511-
generateForwardJump(currentBlock, trueBlock, stackifierData);
503+
HIRBlock trueBlock = nodeToBlockMap.get(lastNode.trueSuccessor());
504+
generateForwardJump(currentBlock, trueBlock);
512505
}
513506
codeGenTool.genElseHeader();
514507
if (elseScope != null) {
515508
lowerBlocks(elseScope.getSortedBlocks());
516509
} else {
517-
generateForwardJump(currentBlock, falseBlock, stackifierData);
510+
HIRBlock falseBlock = nodeToBlockMap.get(lastNode.falseSuccessor());
511+
generateForwardJump(currentBlock, falseBlock);
518512
}
519513
codeGenTool.genScopeEnd();
520514
}
521515

516+
/**
517+
* Lowers the end of an HIR block (including the last node) in case the last node is not a
518+
* control-flow node.
519+
* <p>
520+
* Also generates a potential forward jump to the next basic block in the control-flow-graph.
521+
*/
522+
protected void lowerUnhandledBlockEnd(HIRBlock currentBlock, FixedNode lastNode) {
523+
if (!(lastNode instanceof LoopExitNode) && !(lastNode instanceof LoopBeginNode)) {
524+
/*
525+
* Special case for basic blocks with only one node. LoopExitNode and LoopBeginNode need
526+
* to be handled separately again, as they must not be lowered by the node lowerer.
527+
*/
528+
lowerNode(lastNode);
529+
}
530+
531+
HIRBlock successor = nodeToBlockMap.get(lastNode.cfgSuccessors().iterator().next());
532+
generateForwardJump(currentBlock, successor);
533+
}
534+
522535
/**
523536
* Determine whether a given {@link LabeledBlock} that starts at the same block as a loop starts
524537
* ends inside the loop or outside of it.
@@ -618,9 +631,8 @@ protected void lowerSwitchDefaultCase(IntegerSwitchNode switchNode) {
618631
* blocks.
619632
*
620633
* @param switchNode node to be lowered
621-
* @param stackifierData data for forward jumps
622634
*/
623-
public void lowerSwitch(IntegerSwitchNode switchNode, StackifierData stackifierData) {
635+
protected void lowerSwitch(IntegerSwitchNode switchNode) {
624636

625637
codeGenTool.genSwitchHeader(switchNode.value());
626638

@@ -658,7 +670,7 @@ public void lowerSwitch(IntegerSwitchNode switchNode, StackifierData stackifierD
658670
if (caseScopes[i] != null) {
659671
lowerBlocks(caseScopes[i].getSortedBlocks());
660672
} else {
661-
generateForwardJump(cfg.blockFor(switchNode), cfg.blockFor(succ), stackifierData);
673+
generateForwardJump(cfg.blockFor(switchNode), cfg.blockFor(succ));
662674
}
663675
codeGenTool.genBlockEndBreak();
664676
codeGenTool.genScopeEnd();
@@ -669,7 +681,7 @@ public void lowerSwitch(IntegerSwitchNode switchNode, StackifierData stackifierD
669681
if (caseScopes[defaultIndex] != null) {
670682
lowerBlocks(caseScopes[defaultIndex].getSortedBlocks());
671683
} else {
672-
generateForwardJump(cfg.blockFor(switchNode), cfg.blockFor(switchNode.defaultSuccessor()), stackifierData);
684+
generateForwardJump(cfg.blockFor(switchNode), cfg.blockFor(switchNode.defaultSuccessor()));
673685
}
674686
codeGenTool.genBlockEndBreak();
675687
codeGenTool.genScopeEnd();
@@ -764,9 +776,8 @@ protected void lowerTypeSwitchDefaultCase(TypeSwitchNode switchNode) {
764776
* blocks.
765777
*
766778
* @param switchNode node to be lowered
767-
* @param stackifierData data for forward jumps
768779
*/
769-
public void lowerTypeSwitch(TypeSwitchNode switchNode, StackifierData stackifierData) {
780+
protected void lowerTypeSwitch(TypeSwitchNode switchNode) {
770781
boolean hasdefault = switchNode.defaultSuccessor() != null;
771782
for (int i = 0; i < switchNode.blockSuccessorCount(); i++) {
772783
// one successor
@@ -788,29 +799,27 @@ public void lowerTypeSwitch(TypeSwitchNode switchNode, StackifierData stackifier
788799
}
789800
assert succKeys.size() > 0 : "no keys of " + switchNode + " have " + succ + " as block successor";
790801
lowerTypeSwitchCase(switchNode, succ, i, succKeys);
791-
generateForwardJump(cfg.blockFor(switchNode), cfg.blockFor(succ), stackifierData);
802+
generateForwardJump(cfg.blockFor(switchNode), cfg.blockFor(succ));
792803
codeGenTool.genBlockEndBreak();
793804
codeGenTool.genScopeEnd();
794805
}
795806
if (hasdefault) {
796807
lowerTypeSwitchDefaultCase(switchNode);
797-
generateForwardJump(cfg.blockFor(switchNode), cfg.blockFor(switchNode.defaultSuccessor()), stackifierData);
808+
generateForwardJump(cfg.blockFor(switchNode), cfg.blockFor(switchNode.defaultSuccessor()));
798809
codeGenTool.genBlockEndBreak();
799810
codeGenTool.genScopeEnd();
800811
}
801812
}
802813

803-
private void genLabeledBlockHeader(LabeledBlock labeledBlock) {
814+
protected void genLabeledBlockHeader(LabeledBlock labeledBlock) {
804815
blockNestingVerifier.pushLabel(labeledBlock);
805816
codeGenTool.genLabeledBlockHeader(labeledBlock.getLabel());
806817
}
807818

808-
private void genLabeledBlockEnd(LabeledBlock blockEnd) {
809-
if (blockEnd != null) {
810-
blockNestingVerifier.popLabel(blockEnd);
811-
codeGenTool.genScopeEnd();
812-
codeGenTool.genComment("End of LabeledBlock " + blockEnd.getLabel());
813-
}
819+
protected void genLabeledBlockEnd(LabeledBlock blockEnd) {
820+
blockNestingVerifier.popLabel(blockEnd);
821+
codeGenTool.genScopeEnd();
822+
codeGenTool.genComment("End of LabeledBlock " + blockEnd.getLabel());
814823
}
815824

816825
private void genLoopHeader(HIRBlock block) {

0 commit comments

Comments
 (0)