2222#include " CoroInternal.h"
2323#include " llvm/ADT/DenseMap.h"
2424#include " llvm/ADT/PriorityWorklist.h"
25+ #include " llvm/ADT/STLExtras.h"
2526#include " llvm/ADT/SmallPtrSet.h"
2627#include " llvm/ADT/SmallVector.h"
2728#include " llvm/ADT/StringExtras.h"
@@ -628,8 +629,8 @@ void CoroCloner::replaceRetconOrAsyncSuspendUses() {
628629
629630 // Otherwise, we need to create an aggregate.
630631 Value *Agg = PoisonValue::get (NewS->getType ());
631- for (size_t I = 0 , E = Args. size (); I != E; ++I )
632- Agg = Builder.CreateInsertValue (Agg, Args[I], I );
632+ for (auto Arg : llvm::enumerate (Args) )
633+ Agg = Builder.CreateInsertValue (Agg, Arg. value (), Arg. index () );
633634
634635 NewS->replaceAllUsesWith (Agg);
635636}
@@ -1833,8 +1834,8 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
18331834
18341835 // Create a continuation function for each of the suspend points.
18351836 Clones.reserve (Shape.CoroSuspends .size ());
1836- for (size_t Idx = 0 , End = Shape.CoroSuspends . size (); Idx != End; ++Idx ) {
1837- auto *Suspend = cast<CoroSuspendAsyncInst>(Shape. CoroSuspends [Idx] );
1837+ for (auto CS : llvm::enumerate ( Shape.CoroSuspends ) ) {
1838+ auto *Suspend = cast<CoroSuspendAsyncInst>(CS. value () );
18381839
18391840 // Create the clone declaration.
18401841 auto ResumeNameSuffix = " .resume." ;
@@ -1850,8 +1851,8 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
18501851 }
18511852 auto *Continuation = createCloneDeclaration (
18521853 F, Shape,
1853- UseSwiftMangling ? ResumeNameSuffix + Twine (Idx ) + " _"
1854- : ResumeNameSuffix + Twine (Idx ),
1854+ UseSwiftMangling ? ResumeNameSuffix + Twine (CS. index () ) + " _"
1855+ : ResumeNameSuffix + Twine (CS. index () ),
18551856 NextF, Suspend);
18561857 Clones.push_back (Continuation);
18571858
@@ -1884,12 +1885,12 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
18841885 }
18851886
18861887 assert (Clones.size () == Shape.CoroSuspends .size ());
1887- for (size_t Idx = 0 , End = Shape.CoroSuspends . size (); Idx != End; ++Idx ) {
1888- auto *Suspend = Shape. CoroSuspends [Idx] ;
1889- auto *Clone = Clones[Idx ];
1888+ for (auto CS : llvm::enumerate ( Shape.CoroSuspends ) ) {
1889+ auto *Suspend = CS. value () ;
1890+ auto *Clone = Clones[CS. index () ];
18901891
1891- CoroCloner::createClone (F, " resume." + Twine (Idx) , Shape, Clone, Suspend ,
1892- TTI);
1892+ CoroCloner::createClone (F, " resume." + Twine (CS. index ()) , Shape, Clone,
1893+ Suspend, TTI);
18931894 }
18941895}
18951896
@@ -1938,19 +1939,20 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
19381939
19391940 // Create a unique return block.
19401941 BasicBlock *ReturnBB = nullptr ;
1942+ PHINode *ContinuationPhi = nullptr ;
19411943 SmallVector<PHINode *, 4 > ReturnPHIs;
19421944
19431945 // Create all the functions in order after the main function.
19441946 auto NextF = std::next (F.getIterator ());
19451947
19461948 // Create a continuation function for each of the suspend points.
19471949 Clones.reserve (Shape.CoroSuspends .size ());
1948- for (size_t i = 0 , e = Shape.CoroSuspends . size (); i != e; ++i ) {
1949- auto Suspend = cast<CoroSuspendRetconInst>(Shape. CoroSuspends [i] );
1950+ for (auto CS : llvm::enumerate ( Shape.CoroSuspends ) ) {
1951+ auto Suspend = cast<CoroSuspendRetconInst>(CS. value () );
19501952
19511953 // Create the clone declaration.
1952- auto Continuation =
1953- createCloneDeclaration ( F, Shape, " .resume." + Twine (i ), NextF, nullptr );
1954+ auto Continuation = createCloneDeclaration (
1955+ F, Shape, " .resume." + Twine (CS. index () ), NextF, nullptr );
19541956 Clones.push_back (Continuation);
19551957
19561958 // Insert a branch to the unified return block immediately before
@@ -1968,12 +1970,12 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
19681970
19691971 IRBuilder<> Builder (ReturnBB);
19701972
1971- // Create PHIs for all the return values.
1972- assert (ReturnPHIs.empty ());
1973-
19741973 // First, the continuation.
1975- ReturnPHIs.push_back (Builder.CreatePHI (Continuation->getType (),
1976- Shape.CoroSuspends .size ()));
1974+ ContinuationPhi =
1975+ Builder.CreatePHI (Continuation->getType (), Shape.CoroSuspends .size ());
1976+
1977+ // Create PHIs for all other return values.
1978+ assert (ReturnPHIs.empty ());
19771979
19781980 // Next, all the directly-yielded values.
19791981 for (auto *ResultTy : Shape.getRetconResultTypes ())
@@ -1987,39 +1989,39 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
19871989 // We can't rely on the types matching up because that type would
19881990 // have to be infinite.
19891991 auto CastedContinuationTy =
1990- (ReturnPHIs.size () == 1 ? RetTy : RetTy->getStructElementType (0 ));
1992+ (ReturnPHIs.empty () ? RetTy : RetTy->getStructElementType (0 ));
19911993 auto *CastedContinuation =
1992- Builder.CreateBitCast (ReturnPHIs[ 0 ] , CastedContinuationTy);
1994+ Builder.CreateBitCast (ContinuationPhi , CastedContinuationTy);
19931995
1994- Value *RetV;
1995- if (ReturnPHIs.size () == 1 ) {
1996- RetV = CastedContinuation;
1997- } else {
1996+ Value *RetV = CastedContinuation;
1997+ if (!ReturnPHIs.empty ()) {
1998+ auto ValueIdx = 0 ;
19981999 RetV = PoisonValue::get (RetTy);
1999- RetV = Builder.CreateInsertValue (RetV, CastedContinuation, 0 );
2000- for (size_t I = 1 , E = ReturnPHIs.size (); I != E; ++I)
2001- RetV = Builder.CreateInsertValue (RetV, ReturnPHIs[I], I);
2000+ RetV = Builder.CreateInsertValue (RetV, CastedContinuation, ValueIdx++);
2001+
2002+ for (auto Phi : ReturnPHIs)
2003+ RetV = Builder.CreateInsertValue (RetV, Phi, ValueIdx++);
20022004 }
20032005
20042006 Builder.CreateRet (RetV);
20052007 }
20062008
20072009 // Branch to the return block.
20082010 Branch->setSuccessor (0 , ReturnBB);
2009- ReturnPHIs[ 0 ]-> addIncoming (Continuation, SuspendBB );
2010- size_t NextPHIIndex = 1 ;
2011- for (auto & VUse : Suspend-> value_operands ())
2012- ReturnPHIs[NextPHIIndex++]-> addIncoming (&*VUse, SuspendBB);
2013- assert (NextPHIIndex == ReturnPHIs. size () );
2011+ assert (ContinuationPhi );
2012+ ContinuationPhi-> addIncoming (Continuation, SuspendBB) ;
2013+ for (auto [Phi, VUse] :
2014+ llvm::zip_equal ( ReturnPHIs, Suspend-> value_operands ()))
2015+ Phi-> addIncoming (VUse, SuspendBB );
20142016 }
20152017
20162018 assert (Clones.size () == Shape.CoroSuspends .size ());
2017- for (size_t i = 0 , e = Shape.CoroSuspends . size (); i != e; ++i ) {
2018- auto Suspend = Shape. CoroSuspends [i] ;
2019- auto Clone = Clones[i ];
2019+ for (auto CS : llvm::enumerate ( Shape.CoroSuspends ) ) {
2020+ auto Suspend = CS. value () ;
2021+ auto Clone = Clones[CS. index () ];
20202022
2021- CoroCloner::createClone (F, " resume." + Twine (i) , Shape, Clone, Suspend ,
2022- TTI);
2023+ CoroCloner::createClone (F, " resume." + Twine (CS. index ()) , Shape, Clone,
2024+ Suspend, TTI);
20232025 }
20242026}
20252027
0 commit comments