@@ -74,6 +74,11 @@ using namespace llvm::objcarc;
7474
7575#define DEBUG_TYPE " objc-arc-opts"
7676
77+ static cl::opt<unsigned > MaxPtrStates (" arc-opt-max-ptr-states" ,
78+ cl::Hidden,
79+ cl::desc (" Maximum number of ptr states the optimizer keeps track of" ),
80+ cl::init(4095 ));
81+
7782// / \defgroup ARCUtilities Utility declarations/definitions specific to ARC.
7883// / @{
7984
@@ -220,6 +225,10 @@ namespace {
220225 return !PerPtrTopDown.empty ();
221226 }
222227
228+ unsigned top_down_ptr_list_size () const {
229+ return std::distance (top_down_ptr_begin (), top_down_ptr_end ());
230+ }
231+
223232 using bottom_up_ptr_iterator = decltype (PerPtrBottomUp)::iterator;
224233 using const_bottom_up_ptr_iterator =
225234 decltype (PerPtrBottomUp)::const_iterator;
@@ -238,6 +247,10 @@ namespace {
238247 return !PerPtrBottomUp.empty ();
239248 }
240249
250+ unsigned bottom_up_ptr_list_size () const {
251+ return std::distance (bottom_up_ptr_begin (), bottom_up_ptr_end ());
252+ }
253+
241254 // / Mark this block as being an entry block, which has one path from the
242255 // / entry by definition.
243256 void SetAsEntry () { TopDownPathCount = 1 ; }
@@ -481,6 +494,10 @@ namespace {
481494 // / A flag indicating whether this optimization pass should run.
482495 bool Run;
483496
497+ // / A flag indicating whether the optimization that removes or moves
498+ // / retain/release pairs should be performed.
499+ bool DisableRetainReleasePairing = false ;
500+
484501 // / Flags which determine whether each of the interesting runtime functions
485502 // / is in fact used in the current function.
486503 unsigned UsedInThisFunction;
@@ -1273,6 +1290,13 @@ bool ObjCARCOpt::VisitBottomUp(BasicBlock *BB,
12731290 LLVM_DEBUG (dbgs () << " Visiting " << *Inst << " \n " );
12741291
12751292 NestingDetected |= VisitInstructionBottomUp (Inst, BB, Retains, MyStates);
1293+
1294+ // Bail out if the number of pointers being tracked becomes too large so
1295+ // that this pass can complete in a reasonable amount of time.
1296+ if (MyStates.bottom_up_ptr_list_size () > MaxPtrStates) {
1297+ DisableRetainReleasePairing = true ;
1298+ return false ;
1299+ }
12761300 }
12771301
12781302 // If there's a predecessor with an invoke, visit the invoke as if it were
@@ -1395,6 +1419,13 @@ ObjCARCOpt::VisitTopDown(BasicBlock *BB,
13951419 LLVM_DEBUG (dbgs () << " Visiting " << Inst << " \n " );
13961420
13971421 NestingDetected |= VisitInstructionTopDown (&Inst, Releases, MyStates);
1422+
1423+ // Bail out if the number of pointers being tracked becomes too large so
1424+ // that this pass can complete in a reasonable amount of time.
1425+ if (MyStates.top_down_ptr_list_size () > MaxPtrStates) {
1426+ DisableRetainReleasePairing = true ;
1427+ return false ;
1428+ }
13981429 }
13991430
14001431 LLVM_DEBUG (dbgs () << " \n State Before Checking for CFG Hazards:\n "
@@ -1501,13 +1532,19 @@ bool ObjCARCOpt::Visit(Function &F,
15011532
15021533 // Use reverse-postorder on the reverse CFG for bottom-up.
15031534 bool BottomUpNestingDetected = false ;
1504- for (BasicBlock *BB : llvm::reverse (ReverseCFGPostOrder))
1535+ for (BasicBlock *BB : llvm::reverse (ReverseCFGPostOrder)) {
15051536 BottomUpNestingDetected |= VisitBottomUp (BB, BBStates, Retains);
1537+ if (DisableRetainReleasePairing)
1538+ return false ;
1539+ }
15061540
15071541 // Use reverse-postorder for top-down.
15081542 bool TopDownNestingDetected = false ;
1509- for (BasicBlock *BB : llvm::reverse (PostOrder))
1543+ for (BasicBlock *BB : llvm::reverse (PostOrder)) {
15101544 TopDownNestingDetected |= VisitTopDown (BB, BBStates, Releases);
1545+ if (DisableRetainReleasePairing)
1546+ return false ;
1547+ }
15111548
15121549 return TopDownNestingDetected && BottomUpNestingDetected;
15131550}
@@ -2003,6 +2040,9 @@ bool ObjCARCOpt::OptimizeSequences(Function &F) {
20032040 // Analyze the CFG of the function, and all instructions.
20042041 bool NestingDetected = Visit (F, BBStates, Retains, Releases);
20052042
2043+ if (DisableRetainReleasePairing)
2044+ return false ;
2045+
20062046 // Transform.
20072047 bool AnyPairsCompletelyEliminated = PerformCodePlacement (BBStates, Retains,
20082048 Releases,
0 commit comments