@@ -399,6 +399,7 @@ class IRGenSILFunction :
399
399
std::pair<unsigned , std::pair<const SILDebugScope *, StringRef>>;
400
400
// / Keeps track of the mapping of source variables to -O0 shadow copy allocas.
401
401
llvm::SmallDenseMap<StackSlotKey, Address, 8 > ShadowStackSlots;
402
+ llvm::SmallDenseMap<llvm::Value *, Address, 8 > TaskAllocStackSlots;
402
403
llvm::SmallDenseMap<Decl *, SmallString<4 >, 8 > AnonymousVariables;
403
404
unsigned NumAnonVars = 0 ;
404
405
@@ -732,10 +733,118 @@ class IRGenSILFunction :
732
733
}
733
734
#endif
734
735
736
+ static bool isCallToSwiftTaskAlloc (llvm::Value *val) {
737
+ auto *call = dyn_cast<llvm::CallInst>(val);
738
+ if (!call)
739
+ return false ;
740
+ auto *callee = call->getCalledFunction ();
741
+ if (!callee)
742
+ return false ;
743
+ auto isTaskAlloc = callee->getName ().equals (" swift_task_alloc" );
744
+ return isTaskAlloc;
745
+ }
746
+
747
+ static bool isTaskAlloc (llvm::Value *Storage) {
748
+ while (Storage) {
749
+ if (auto *LdInst = dyn_cast<llvm::LoadInst>(Storage))
750
+ Storage = LdInst->getOperand (0 );
751
+ else if (auto *GEPInst = dyn_cast<llvm::GetElementPtrInst>(Storage))
752
+ Storage = GEPInst->getOperand (0 );
753
+ else if (auto *BCInst = dyn_cast<llvm::BitCastInst>(Storage))
754
+ Storage = BCInst->getOperand (0 );
755
+ else if (auto *CallInst = dyn_cast<llvm::CallInst>(Storage))
756
+ return isCallToSwiftTaskAlloc (CallInst);
757
+ else
758
+ break ;
759
+ }
760
+ return false ;
761
+ }
762
+
763
+ // / Emit a direct path to an Argument.
764
+ llvm::Value *getDirectCoroutineArgument (llvm::Value *Addr) {
765
+ auto getDirect = [&](llvm::Instruction *Orig) {
766
+ llvm::Value *Buffered = Orig->getOperand (0 );
767
+ llvm::Value *Direct = getDirectCoroutineArgument (Buffered);
768
+ if (Buffered == Direct)
769
+ return Orig;
770
+ llvm::Instruction *Cloned = Orig->clone ();
771
+ Cloned->setOperand (0 , Direct);
772
+ Cloned->insertBefore (Orig);
773
+ return Cloned;
774
+ };
775
+ if (auto *LdInst = dyn_cast<llvm::LoadInst>(Addr))
776
+ return getDirect (LdInst);
777
+ if (auto *GEPInst = dyn_cast<llvm::GetElementPtrInst>(Addr))
778
+ return getDirect (GEPInst);
779
+ if (auto *BCInst = dyn_cast<llvm::BitCastInst>(Addr))
780
+ return getDirect (BCInst);
781
+ if (auto *CallInst = dyn_cast<llvm::CallInst>(Addr)) {
782
+ llvm::Value *Buffered = CallInst->getArgOperand (0 );
783
+ if (CallInst->getCalledFunction () != IGM.getProjectBoxFn ()) {
784
+ assert (false && " unhandled projection" );
785
+ return CallInst;
786
+ }
787
+ llvm::Value *Direct = getDirectCoroutineArgument (Buffered);
788
+ if (Buffered == Direct)
789
+ return CallInst;
790
+ auto *Cloned = cast<llvm::CallInst>(CallInst->clone ());
791
+ Cloned->setArgOperand (0 , Direct);
792
+ Cloned->insertBefore (CallInst);
793
+ return Cloned;
794
+ }
795
+ if (auto *AllocaInst = dyn_cast<llvm::AllocaInst>(Addr)) {
796
+ llvm::Value *Direct = nullptr ;
797
+ unsigned NumStores = 0 ;
798
+ for (auto &AIUse : AllocaInst->uses ()) {
799
+ llvm::User *U = AIUse.getUser ();
800
+ if (llvm::StoreInst *StInst = llvm::dyn_cast<llvm::StoreInst>(U)) {
801
+ ++NumStores;
802
+ Direct = StInst->getOperand (0 );
803
+ }
804
+ }
805
+ if (NumStores == 1 )
806
+ return Direct;
807
+ }
808
+ return Addr;
809
+ }
810
+
811
+ llvm::Value *emitTaskAllocShadowCopy (llvm::Value *Storage,
812
+ const SILDebugScope *Scope) {
813
+ auto getRec = [&](llvm::Instruction *Orig) {
814
+ llvm::Instruction *Cloned = Orig->clone ();
815
+ Cloned->setOperand (0 , emitTaskAllocShadowCopy (Orig->getOperand (0 ), Scope));
816
+ Cloned->insertBefore (Orig);
817
+ return Cloned;
818
+ };
819
+ if (auto *LdInst = dyn_cast<llvm::LoadInst>(Storage))
820
+ return getRec (LdInst);
821
+ if (auto *GEPInst = dyn_cast<llvm::GetElementPtrInst>(Storage))
822
+ return getRec (GEPInst);
823
+ if (auto *BCInst = dyn_cast<llvm::BitCastInst>(Storage))
824
+ return getRec (BCInst);
825
+ if (auto *CallInst = dyn_cast<llvm::CallInst>(Storage)) {
826
+ assert (isTaskAlloc (CallInst));
827
+ auto Align = IGM.getPointerAlignment ();
828
+ auto &Alloca = TaskAllocStackSlots[CallInst];
829
+ if (!Alloca.isValid ())
830
+ Alloca = createAlloca (Storage->getType (), Align, " taskalloc.debug" );
831
+ zeroInit (cast<llvm::AllocaInst>(Alloca.getAddress ()));
832
+ ArtificialLocation AutoRestore (Scope, IGM.DebugInfo .get (), Builder);
833
+ auto *Store =
834
+ Builder.CreateStore (Storage, Alloca.getAddress (), Align);
835
+ Store->moveAfter (CallInst);
836
+ return Alloca.getAddress ();
837
+ }
838
+ return Storage;
839
+ }
840
+
735
841
// / Unconditionally emit a stack shadow copy of an \c llvm::Value.
736
842
llvm::Value *emitShadowCopy (llvm::Value *Storage, const SILDebugScope *Scope,
737
843
SILDebugVariable VarInfo,
738
844
llvm::Optional<Alignment> _Align) {
845
+ if (CurSILFn->isAsync ())
846
+ if (isTaskAlloc (Storage))
847
+ return emitTaskAllocShadowCopy (Storage, Scope);
739
848
auto Align = _Align.getValueOr (IGM.getPointerAlignment ());
740
849
unsigned ArgNo = VarInfo.ArgNo ;
741
850
auto &Alloca = ShadowStackSlots[{ArgNo, {Scope, VarInfo.Name }}];
@@ -764,7 +873,8 @@ class IRGenSILFunction :
764
873
// debug info during coroutine splitting. Instead we are relying on LLVM's
765
874
// CoroSplit.cpp to emit shadow copies.
766
875
if (IGM.IRGen .Opts .DisableDebuggerShadowCopies ||
767
- IGM.IRGen .Opts .shouldOptimize () || IsAnonymous || CurSILFn->isAsync () ||
876
+ IGM.IRGen .Opts .shouldOptimize () || IsAnonymous ||
877
+ (CurSILFn->isAsync () && VarInfo.ArgNo ) ||
768
878
isa<llvm::AllocaInst>(Storage) || isa<llvm::UndefValue>(Storage) ||
769
879
!needsShadowCopy (Storage))
770
880
return Storage;
@@ -791,7 +901,8 @@ class IRGenSILFunction :
791
901
792
902
// Only do this at -O0.
793
903
if (IGM.IRGen .Opts .DisableDebuggerShadowCopies ||
794
- IGM.IRGen .Opts .shouldOptimize () || IsAnonymous || CurSILFn->isAsync ()) {
904
+ IGM.IRGen .Opts .shouldOptimize () || IsAnonymous ||
905
+ (CurSILFn->isAsync () && VarInfo.ArgNo )) {
795
906
auto vals = e.claimAll ();
796
907
copy.append (vals.begin (), vals.end ());
797
908
return ;
@@ -853,8 +964,6 @@ class IRGenSILFunction :
853
964
IGM.DebugInfo ->emitVariableDeclaration (Builder, Storage, Ty, DS, VarDecl,
854
965
VarInfo, Indirection);
855
966
}
856
- // / Emit a direct path to an Argument.
857
- llvm::Value *getDirectCoroutineArgument (llvm::Value *Addr);
858
967
859
968
void emitFailBB () {
860
969
if (!FailBBs.empty ()) {
@@ -4321,53 +4430,6 @@ void IRGenSILFunction::emitErrorResultVar(CanSILFunctionType FnTy,
4321
4430
IndirectValue, ArtificialValue);
4322
4431
}
4323
4432
4324
- llvm::Value *IRGenSILFunction::getDirectCoroutineArgument (llvm::Value *Addr) {
4325
- auto getDirect = [&](llvm::Instruction *Orig) {
4326
- llvm::Value *Buffered = Orig->getOperand (0 );
4327
- llvm::Value *Direct = getDirectCoroutineArgument (Buffered);
4328
- if (Buffered == Direct)
4329
- return Orig;
4330
- llvm::Instruction *Cloned = Orig->clone ();
4331
- Cloned->setOperand (0 , Direct);
4332
- Cloned->insertBefore (Orig);
4333
- return Cloned;
4334
- };
4335
- if (auto *LdInst = dyn_cast<llvm::LoadInst>(Addr))
4336
- return getDirect (LdInst);
4337
- if (auto *GEPInst = dyn_cast<llvm::GetElementPtrInst>(Addr))
4338
- return getDirect (GEPInst);
4339
- if (auto *BCInst = dyn_cast<llvm::BitCastInst>(Addr))
4340
- return getDirect (BCInst);
4341
- if (auto *CallInst = dyn_cast<llvm::CallInst>(Addr)) {
4342
- llvm::Value *Buffered = CallInst->getArgOperand (0 );
4343
- if (CallInst->getCalledFunction () != IGM.getProjectBoxFn ()) {
4344
- assert (false && " unhandled projection" );
4345
- return CallInst;
4346
- }
4347
- llvm::Value *Direct = getDirectCoroutineArgument (Buffered);
4348
- if (Buffered == Direct)
4349
- return CallInst;
4350
- auto *Cloned = cast<llvm::CallInst>(CallInst->clone ());
4351
- Cloned->setArgOperand (0 , Direct);
4352
- Cloned->insertBefore (CallInst);
4353
- return Cloned;
4354
- }
4355
- if (auto *AllocaInst = dyn_cast<llvm::AllocaInst>(Addr)) {
4356
- llvm::Value *Direct = nullptr ;
4357
- unsigned NumStores = 0 ;
4358
- for (auto &AIUse : AllocaInst->uses ()) {
4359
- llvm::User *U = AIUse.getUser ();
4360
- if (llvm::StoreInst *StInst = llvm::dyn_cast<llvm::StoreInst>(U)) {
4361
- ++NumStores;
4362
- Direct = StInst->getOperand (0 );
4363
- }
4364
- }
4365
- if (NumStores == 1 )
4366
- return Direct;
4367
- }
4368
- return Addr;
4369
- }
4370
-
4371
4433
void IRGenSILFunction::visitDebugValueInst (DebugValueInst *i) {
4372
4434
if (i->getDebugScope ()->getInlinedFunction ()->isTransparent ())
4373
4435
return ;
@@ -4742,17 +4804,6 @@ void IRGenSILFunction::visitIsEscapingClosureInst(
4742
4804
setLoweredExplosion (i, out);
4743
4805
}
4744
4806
4745
- static bool isCallToSwiftTaskAlloc (llvm::Value *val) {
4746
- auto *call = dyn_cast<llvm::CallInst>(val);
4747
- if (!call)
4748
- return false ;
4749
- auto *callee = call->getCalledFunction ();
4750
- if (!callee)
4751
- return false ;
4752
- auto isTaskAlloc = callee->getName ().equals (" swift_task_alloc" );
4753
- return isTaskAlloc;
4754
- }
4755
-
4756
4807
void IRGenSILFunction::emitDebugInfoForAllocStack (AllocStackInst *i,
4757
4808
const TypeInfo &type,
4758
4809
llvm::Value *addr) {
0 commit comments