@@ -245,7 +245,7 @@ bool SimplifyCFG::threadEdge(const ThreadInfo &ti) {
245
245
dyn_cast<BranchInst>(ThreadedSuccessorBlock->getTerminator ())) {
246
246
simplifyBranchBlock (branchInst);
247
247
}
248
- Cloner.updateOSSAAfterCloning ();
248
+ Cloner.updateSSAAfterCloning ();
249
249
return true ;
250
250
}
251
251
@@ -924,6 +924,11 @@ bool SimplifyCFG::tryJumpThreading(BranchInst *BI) {
924
924
if (destTerminator->isFunctionExiting ())
925
925
return false ;
926
926
927
+ // There is no benefit duplicating such a destination.
928
+ if (DestBB->getSinglePredecessorBlock () != nullptr ) {
929
+ return false ;
930
+ }
931
+
927
932
// Jump threading only makes sense if there is an argument on the branch
928
933
// (which is reacted on in the DestBB), or if this goes through a memory
929
934
// location (switch_enum_addr is the only address-instruction which we
@@ -942,6 +947,7 @@ bool SimplifyCFG::tryJumpThreading(BranchInst *BI) {
942
947
for (unsigned i : indices (BI->getArgs ())) {
943
948
SILValue Arg = BI->getArg (i);
944
949
950
+ // TODO: Verify if we need to jump thread to remove releases in OSSA.
945
951
// If the value being substituted on is release there is a chance we could
946
952
// remove the release after jump threading.
947
953
if (!Arg->getType ().isTrivial (*SrcBB->getParent ()) &&
@@ -1030,7 +1036,7 @@ bool SimplifyCFG::tryJumpThreading(BranchInst *BI) {
1030
1036
// Duplicate the destination block into this one, rewriting uses of the BBArgs
1031
1037
// to use the branch arguments as we go.
1032
1038
Cloner.cloneBranchTarget (BI);
1033
- Cloner.updateOSSAAfterCloning ();
1039
+ Cloner.updateSSAAfterCloning ();
1034
1040
1035
1041
// Once all the instructions are copied, we can nuke BI itself. We also add
1036
1042
// the threaded and edge block to the worklist now that they (likely) can be
@@ -1278,13 +1284,13 @@ bool SimplifyCFG::simplifyBranchBlock(BranchInst *BI) {
1278
1284
//
1279
1285
SILBasicBlock *remainingBlock = nullptr , *deletedBlock = nullptr ;
1280
1286
if (BB != Fn.getEntryBlock () && hasLessInstructions (BB, DestBB)) {
1287
+ DestBB->spliceAtBegin (BB);
1288
+ DestBB->dropAllArguments ();
1289
+ DestBB->moveArgumentList (BB);
1281
1290
while (!BB->pred_empty ()) {
1282
1291
SILBasicBlock *pred = *BB->pred_begin ();
1283
1292
replaceBranchTarget (pred->getTerminator (), BB, DestBB, true );
1284
1293
}
1285
- DestBB->spliceAtBegin (BB);
1286
- DestBB->dropAllArguments ();
1287
- DestBB->moveArgumentList (BB);
1288
1294
remainingBlock = DestBB;
1289
1295
deletedBlock = BB;
1290
1296
} else {
@@ -1715,10 +1721,6 @@ static bool isOnlyUnreachable(SILBasicBlock *BB) {
1715
1721
// / switch_enum where all but one block consists of just an
1716
1722
// / "unreachable" with an unchecked_enum_data and branch.
1717
1723
bool SimplifyCFG::simplifySwitchEnumUnreachableBlocks (SwitchEnumInst *SEI) {
1718
- if (!EnableOSSARewriteTerminator && Fn.hasOwnership ()) {
1719
- if (!SEI->getOperand ()->getType ().isTrivial (Fn))
1720
- return false ;
1721
- }
1722
1724
auto Count = SEI->getNumCases ();
1723
1725
1724
1726
SILBasicBlock *Dest = nullptr ;
@@ -1851,7 +1853,9 @@ static bool containsOnlyObjMethodCallOnOptional(SILValue optionalValue,
1851
1853
1852
1854
// The branch should forward one of the objc_method call.
1853
1855
if (auto *br = dyn_cast<BranchInst>(inst)) {
1854
- if (br->getNumArgs () == 0 || br->getNumArgs () > 1 )
1856
+ if (br->getNumArgs () == 0 )
1857
+ continue ;
1858
+ if (br->getNumArgs () > 1 )
1855
1859
return false ;
1856
1860
auto branchArg = br->getArg (0 );
1857
1861
if (std::find (objCApplies.begin (), objCApplies.end (), branchArg) ==
@@ -1899,6 +1903,9 @@ static bool onlyForwardsNone(SILBasicBlock *noneBB, SILBasicBlock *someBB,
1899
1903
continue ;
1900
1904
}
1901
1905
if (auto *noneBranch = dyn_cast<BranchInst>(inst)) {
1906
+ if (noneBranch->getNumArgs () == 0 ) {
1907
+ continue ;
1908
+ }
1902
1909
if (noneBranch->getNumArgs () != 1 ||
1903
1910
(noneBranch->getArg (0 ) != SEI->getOperand () &&
1904
1911
noneBranch->getArg (0 ) != optionalNone))
@@ -2010,12 +2017,6 @@ static bool hasSameUltimateSuccessor(SILBasicBlock *noneBB, SILBasicBlock *someB
2010
2017
// / %4 = enum #Optional.none
2011
2018
// / br mergeBB(%4)
2012
2019
bool SimplifyCFG::simplifySwitchEnumOnObjcClassOptional (SwitchEnumInst *SEI) {
2013
- // TODO: OSSA; handle non-trivial enum case cleanup
2014
- // (simplify_switch_enum_objc.sil).
2015
- if (!EnableOSSARewriteTerminator && Fn.hasOwnership ()) {
2016
- return false ;
2017
- }
2018
-
2019
2020
auto optional = SEI->getOperand ();
2020
2021
auto optionalPayloadType = optional->getType ().getOptionalObjectType ();
2021
2022
if (!optionalPayloadType ||
@@ -2052,10 +2053,20 @@ bool SimplifyCFG::simplifySwitchEnumOnObjcClassOptional(SwitchEnumInst *SEI) {
2052
2053
optionalPayloadType);
2053
2054
optionalPayload->replaceAllUsesWith (payloadCast);
2054
2055
auto *switchBB = SEI->getParent ();
2055
- if (someBB->getNumArguments ())
2056
- Builder.createBranch (SEI->getLoc (), someBB, SILValue (payloadCast));
2057
- else
2056
+
2057
+ if (!someBB->args_empty ()) {
2058
+ assert (someBB->getNumArguments () == 1 );
2059
+ auto *someBBArg = someBB->getArgument (0 );
2060
+ if (!someBBArg->use_empty ()) {
2061
+ assert (optionalPayload != someBBArg);
2062
+ someBBArg->replaceAllUsesWith (payloadCast);
2063
+ }
2064
+ someBB->eraseArgument (0 );
2065
+ Builder.createBranch (SEI->getLoc (), someBB);
2066
+ } else {
2067
+ assert (!Fn.hasOwnership ());
2058
2068
Builder.createBranch (SEI->getLoc (), someBB);
2069
+ }
2059
2070
2060
2071
SEI->eraseFromParent ();
2061
2072
addToWorklist (switchBB);
@@ -2076,12 +2087,6 @@ bool SimplifyCFG::simplifySwitchEnumBlock(SwitchEnumInst *SEI) {
2076
2087
auto *LiveBlock = SEI->getCaseDestination (EnumCase.get ());
2077
2088
auto *ThisBB = SEI->getParent ();
2078
2089
2079
- if (!EnableOSSARewriteTerminator && Fn.hasOwnership ()) {
2080
- // TODO: OSSA; cleanup terminator results.
2081
- if (!SEI->getOperand ()->getType ().isTrivial (Fn))
2082
- return false ;
2083
- }
2084
-
2085
2090
bool DroppedLiveBlock = false ;
2086
2091
// Copy the successors into a vector, dropping one entry for the liveblock.
2087
2092
SmallVector<SILBasicBlock*, 4 > Dests;
@@ -2096,29 +2101,27 @@ bool SimplifyCFG::simplifySwitchEnumBlock(SwitchEnumInst *SEI) {
2096
2101
LLVM_DEBUG (llvm::dbgs () << " fold switch " << *SEI);
2097
2102
2098
2103
auto *EI = dyn_cast<EnumInst>(SEI->getOperand ());
2104
+ auto loc = SEI->getLoc ();
2099
2105
SILBuilderWithScope Builder (SEI);
2100
2106
if (!LiveBlock->args_empty ()) {
2101
2107
SILValue PayLoad;
2102
2108
if (SEI->hasDefault () && LiveBlock == SEI->getDefaultBB ()) {
2103
2109
assert (Fn.hasOwnership () && " Only OSSA default case has an argument" );
2104
2110
PayLoad = SEI->getOperand ();
2105
2111
} else {
2106
- if (EI) {
2107
- PayLoad = EI->getOperand ();
2108
- } else {
2109
- PayLoad = Builder.createUncheckedEnumData (SEI->getLoc (),
2110
- SEI->getOperand (),
2111
- EnumCase.get ());
2112
- }
2112
+ PayLoad = Builder.createUncheckedEnumData (loc, SEI->getOperand (),
2113
+ EnumCase.get ());
2113
2114
}
2114
- Builder.createBranch (SEI-> getLoc () , LiveBlock, PayLoad);
2115
+ Builder.createBranch (loc , LiveBlock, PayLoad);
2115
2116
} else {
2116
- Builder.createBranch (SEI-> getLoc () , LiveBlock);
2117
+ Builder.createBranch (loc , LiveBlock);
2117
2118
}
2119
+
2118
2120
SEI->eraseFromParent ();
2119
- // TODO: also remove this EnumInst in OSSA default case when the only
2120
- // remaining uses are destroys, and incidental uses.
2121
- if (EI && EI->use_empty ()) EI->eraseFromParent ();
2121
+ if (EI && isInstructionTriviallyDead (EI)) {
2122
+ EI->replaceAllUsesOfAllResultsWithUndef ();
2123
+ EI->eraseFromParent ();
2124
+ }
2122
2125
2123
2126
addToWorklist (ThisBB);
2124
2127
@@ -2547,15 +2550,6 @@ bool SimplifyCFG::simplifyTermWithIdenticalDestBlocks(SILBasicBlock *BB) {
2547
2550
return false ;
2548
2551
}
2549
2552
TermInst *Term = BB->getTerminator ();
2550
- // TODO: OSSA; cleanup nontrivial terminator operands (if this ever actually
2551
- // happens)
2552
- if (!EnableOSSARewriteTerminator && Fn.hasOwnership ()) {
2553
- if (llvm::any_of (Term->getOperandValues (), [this ](SILValue op) {
2554
- return !op->getType ().isTrivial (Fn);
2555
- })) {
2556
- return false ;
2557
- }
2558
- }
2559
2553
LLVM_DEBUG (llvm::dbgs () << " replace term with identical dests: " << *Term);
2560
2554
SILBuilderWithScope (Term).createBranch (Term->getLoc (), commonDest.destBB ,
2561
2555
commonDest.newSourceBranchArgs );
@@ -2877,7 +2871,7 @@ bool SimplifyCFG::tailDuplicateObjCMethodCallSuccessorBlocks() {
2877
2871
continue ;
2878
2872
2879
2873
Cloner.cloneBranchTarget (Branch);
2880
- Cloner.updateOSSAAfterCloning ();
2874
+ Cloner.updateSSAAfterCloning ();
2881
2875
2882
2876
Changed = true ;
2883
2877
// Simplify the cloned block and continue tail duplicating through its new
@@ -3832,16 +3826,21 @@ bool SimplifyCFG::simplifyArgument(SILBasicBlock *BB, unsigned i) {
3832
3826
// the uses in this block, and then rewrite the branch operands.
3833
3827
LLVM_DEBUG (llvm::dbgs () << " unwrap argument:" << *A);
3834
3828
A->replaceAllUsesWith (SILUndef::get (A->getType (), *BB->getParent ()));
3835
- auto *NewArg =
3836
- BB->replacePhiArgument (i, proj-> getType (), OwnershipKind::Owned );
3829
+ auto *NewArg = BB-> replacePhiArgument (i, proj-> getType (),
3830
+ BB->getArgument (i)-> getOwnershipKind () );
3837
3831
proj->replaceAllUsesWith (NewArg);
3838
3832
3839
3833
// Rewrite the branch operand for each incoming branch.
3840
3834
for (auto *Pred : BB->getPredecessorBlocks ()) {
3841
3835
if (auto *Branch = cast<BranchInst>(Pred->getTerminator ())) {
3836
+ auto *BranchOpValue = cast<SingleValueInstruction>(Branch->getOperand (i));
3842
3837
auto V = getInsertedValue (cast<SingleValueInstruction>(Branch->getArg (i)),
3843
3838
proj);
3844
3839
Branch->setOperand (i, V);
3840
+ if (isInstructionTriviallyDead (BranchOpValue)) {
3841
+ BranchOpValue->replaceAllUsesWithUndef ();
3842
+ BranchOpValue->eraseFromParent ();
3843
+ }
3845
3844
addToWorklist (Pred);
3846
3845
}
3847
3846
}
@@ -3887,15 +3886,6 @@ bool SimplifyCFG::simplifyArgs(SILBasicBlock *BB) {
3887
3886
if (BB->pred_empty ())
3888
3887
return false ;
3889
3888
3890
- if (!EnableOSSARewriteTerminator && Fn.hasOwnership ()) {
3891
- // TODO: OSSA phi support
3892
- if (llvm::any_of (BB->getArguments (), [this ](SILArgument *arg) {
3893
- return !arg->getType ().isTrivial (Fn);
3894
- })) {
3895
- return false ;
3896
- }
3897
- }
3898
-
3899
3889
// Ignore blocks that are successors of terminators with mandatory args.
3900
3890
for (SILBasicBlock *pred : BB->getPredecessorBlocks ()) {
3901
3891
if (hasMandatoryArgument (pred->getTerminator ()))
0 commit comments