Skip to content

Commit e6ec4e4

Browse files
committed
SimplifyCFG OSSA support for trivial switch_enum.
1 parent 5493362 commit e6ec4e4

File tree

1 file changed

+28
-9
lines changed

1 file changed

+28
-9
lines changed

lib/SILOptimizer/Transforms/SimplifyCFG.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ getEnumCaseRecursive(SILValue Val, SILBasicBlock *UsedInBB, int RecursionDepth,
829829
Pred = UsedInBB->getSinglePredecessorBlock();
830830
}
831831

832-
// In case of a block argument, recursively check the enum cases of all
832+
// In case of a phi, recursively check the enum cases of all
833833
// incoming predecessors.
834834
if (auto *Arg = dyn_cast<SILArgument>(Val)) {
835835
HandledArgs.insert(Arg);
@@ -2697,8 +2697,6 @@ bool SimplifyCFG::simplifyTryApplyBlock(TryApplyInst *TAI) {
26972697
bool SimplifyCFG::simplifyTermWithIdenticalDestBlocks(SILBasicBlock *BB) {
26982698
TrampolineDest commonDest;
26992699
for (auto *SuccBlock : BB->getSuccessorBlocks()) {
2700-
if (SuccBlock->getNumArguments() != 0)
2701-
return false;
27022700
auto trampolineDest = TrampolineDest(BB, SuccBlock);
27032701
if (!trampolineDest) {
27042702
return false;
@@ -2911,11 +2909,7 @@ bool SimplifyCFG::simplifyBlocks() {
29112909
/// Canonicalize all switch_enum and switch_enum_addr instructions.
29122910
/// If possible, replace the default with the corresponding unique case.
29132911
bool SimplifyCFG::canonicalizeSwitchEnums() {
2914-
if (!EnableOSSARewriteTerminator && Fn.hasOwnership()) {
2915-
// TODO: OSSA. In OSSA, the default switch_enum case passes the
2916-
// original enum as a block argument. This needs to check that the block
2917-
// argument is dead, then replace it with the a new argument for the default
2918-
// payload.
2912+
if (!EnableOSSASimplifyCFG && Fn.hasOwnership()) {
29192913
return false;
29202914
}
29212915
bool Changed = false;
@@ -2933,6 +2927,15 @@ bool SimplifyCFG::canonicalizeSwitchEnums() {
29332927
if (!elementDecl)
29342928
continue;
29352929

2930+
if (!EnableOSSARewriteTerminator && Fn.hasOwnership()) {
2931+
if (!SWI.getOperand()->getType().isTrivial(Fn)) {
2932+
// TODO: OSSA. In OSSA, the default switch_enum case passes the original
2933+
// enum as a block argument. This needs to check that the block argument
2934+
// is dead, then replace it with the a new argument for the default
2935+
// payload.
2936+
continue;
2937+
}
2938+
}
29362939
LLVM_DEBUG(llvm::dbgs() << "simplify canonical switch_enum\n");
29372940

29382941
// Construct a new instruction by copying all the case entries.
@@ -2941,9 +2944,25 @@ bool SimplifyCFG::canonicalizeSwitchEnums() {
29412944
CaseBBs.push_back(SWI.getCase(idx));
29422945
}
29432946
// Add the default-entry of the original instruction as case-entry.
2944-
CaseBBs.push_back(std::make_pair(elementDecl.get(), SWI.getDefaultBB()));
2947+
auto *defaultBB = SWI.getDefaultBB();
2948+
CaseBBs.push_back(std::make_pair(elementDecl.get(), defaultBB));
29452949

29462950
if (isa<SwitchEnumInst>(*SWI)) {
2951+
if (Fn.hasOwnership()) {
2952+
assert(defaultBB->getNumArguments() == 1);
2953+
defaultBB->getArgument(0)->replaceAllUsesWith(SWI.getOperand());
2954+
defaultBB->eraseArgument(0);
2955+
// TODO: handle non-trivial payloads. The new block argument must be
2956+
// destroyed. The old default argument may need to be copied. But it may
2957+
// also be possible to optimize the common case on-the-fly without the
2958+
// extra copy/destroy.
2959+
if (elementDecl.get()->hasAssociatedValues()) {
2960+
// Note: this is not really a phi.
2961+
auto elementTy = SWI.getOperand()->getType().getEnumElementType(
2962+
elementDecl.get(), Fn.getModule(), Fn.getTypeExpansionContext());
2963+
defaultBB->createPhiArgument(elementTy, OwnershipKind::None);
2964+
}
2965+
}
29472966
SILBuilderWithScope(SWI).createSwitchEnum(SWI->getLoc(), SWI.getOperand(),
29482967
nullptr, CaseBBs);
29492968
} else {

0 commit comments

Comments
 (0)