@@ -402,9 +402,9 @@ class IRGenSILFunction :
402
402
llvm::SmallDenseMap<llvm::Value *, Address, 8 > TaskAllocStackSlots;
403
403
llvm::SmallDenseMap<Decl *, SmallString<4 >, 8 > AnonymousVariables;
404
404
// / To avoid inserting elements into ValueDomPoints twice.
405
- llvm::SmallDenseSet<llvm::Instruction *, 8 > ValueVariables;
405
+ llvm::SmallDenseSet<llvm::Value *, 8 > ValueVariables;
406
406
// / Holds the DominancePoint of values that are storage for a source variable.
407
- SmallVector<std::pair<llvm::Instruction *, DominancePoint>, 8 > ValueDomPoints;
407
+ SmallVector<std::pair<llvm::Value *, DominancePoint>, 8 > ValueDomPoints;
408
408
unsigned NumAnonVars = 0 ;
409
409
410
410
// / Accumulative amount of allocated bytes on the stack. Used to limit the
@@ -742,7 +742,7 @@ class IRGenSILFunction :
742
742
if (IGM.IRGen .Opts .shouldOptimize ())
743
743
return ;
744
744
for (auto &Variable : ValueDomPoints) {
745
- llvm::Instruction *Var = Variable.first ;
745
+ llvm::Value *Var = Variable.first ;
746
746
DominancePoint VarDominancePoint = Variable.second ;
747
747
if (getActiveDominancePoint () == VarDominancePoint ||
748
748
isActiveDominancePointDominatedBy (VarDominancePoint)) {
@@ -754,7 +754,10 @@ class IRGenSILFunction :
754
754
// that this shouldn't be necessary. LiveDebugValues should be doing
755
755
// this but can't in general because it currently only tracks register
756
756
// locations.
757
- llvm::BasicBlock *BB = Var->getParent ();
757
+ llvm::BasicBlock *BB =
758
+ isa<llvm::Instruction>(Var)
759
+ ? cast<llvm::Instruction>(Var)->getParent ()
760
+ : &cast<llvm::Argument>(Var)->getParent ()->getEntryBlock ();
758
761
llvm::BasicBlock *CurBB = Builder.GetInsertBlock ();
759
762
if (BB == CurBB)
760
763
// The current basic block must be a successor of the dbg.value().
@@ -841,56 +844,6 @@ class IRGenSILFunction :
841
844
return false ;
842
845
}
843
846
844
- // / Emit a direct path to an Argument.
845
- llvm::Value *getDirectCoroutineArgument (llvm::Value *Addr) {
846
- auto getDirect = [&](llvm::Instruction *Orig) {
847
- llvm::Value *Buffered = Orig->getOperand (0 );
848
- llvm::Value *Direct = getDirectCoroutineArgument (Buffered);
849
- if (Buffered == Direct)
850
- return Orig;
851
- llvm::Instruction *Cloned = Orig->clone ();
852
- Cloned->setOperand (0 , Direct);
853
- Cloned->insertBefore (Orig);
854
- return Cloned;
855
- };
856
- if (auto *LdInst = dyn_cast<llvm::LoadInst>(Addr))
857
- return getDirect (LdInst);
858
- if (auto *GEPInst = dyn_cast<llvm::GetElementPtrInst>(Addr))
859
- return getDirect (GEPInst);
860
- if (auto *BCInst = dyn_cast<llvm::BitCastInst>(Addr))
861
- return getDirect (BCInst);
862
- if (auto *CallInst = dyn_cast<llvm::CallInst>(Addr)) {
863
- llvm::Value *Buffered = CallInst->getArgOperand (0 );
864
- if (CallInst->getCalledFunction () != IGM.getProjectBoxFn ()) {
865
- assert (false && " unhandled projection" );
866
- return CallInst;
867
- }
868
- llvm::Value *Direct = getDirectCoroutineArgument (Buffered);
869
- if (Buffered == Direct)
870
- return CallInst;
871
- auto *Cloned = cast<llvm::CallInst>(CallInst->clone ());
872
- Cloned->setArgOperand (0 , Direct);
873
- Cloned->insertBefore (CallInst);
874
- return Cloned;
875
- }
876
- if (auto *AllocaInst = dyn_cast<llvm::AllocaInst>(Addr)) {
877
- llvm::Value *Direct = nullptr ;
878
- unsigned NumStores = 0 ;
879
- for (auto &AIUse : AllocaInst->uses ()) {
880
- llvm::User *U = AIUse.getUser ();
881
- if (llvm::StoreInst *StInst = llvm::dyn_cast<llvm::StoreInst>(U)) {
882
- ++NumStores;
883
- Direct = StInst->getOperand (0 );
884
- }
885
- }
886
- if (NumStores == 1 )
887
- return Direct;
888
- }
889
- return Addr;
890
- }
891
-
892
- // This returns shadow alloca when \p init is false or the shadowed value
893
- // derived from that alloca with \p init is true.
894
847
llvm::Value *emitTaskAllocShadowCopy (llvm::Value *Storage,
895
848
const SILDebugScope *Scope,
896
849
bool Init) {
@@ -933,10 +886,6 @@ class IRGenSILFunction :
933
886
llvm::Value *emitShadowCopy (llvm::Value *Storage, const SILDebugScope *Scope,
934
887
SILDebugVariable VarInfo,
935
888
llvm::Optional<Alignment> _Align, bool Init) {
936
- if (CurSILFn->isAsync ())
937
- if (isTaskAlloc (Storage))
938
- return emitTaskAllocShadowCopy (Storage, Scope, Init);
939
-
940
889
auto Align = _Align.getValueOr (IGM.getPointerAlignment ());
941
890
unsigned ArgNo = VarInfo.ArgNo ;
942
891
auto &Alloca = ShadowStackSlots[{ArgNo, {Scope, VarInfo.Name }}];
@@ -955,8 +904,7 @@ class IRGenSILFunction :
955
904
bool shouldShadowVariable (SILDebugVariable varInfo, bool isAnonymous) {
956
905
return !IGM.IRGen .Opts .DisableDebuggerShadowCopies
957
906
&& !IGM.IRGen .Opts .shouldOptimize ()
958
- && !isAnonymous
959
- && !CurSILFn->isAsync ();
907
+ && !isAnonymous;
960
908
}
961
909
962
910
bool shouldShadowStorage (llvm::Value *Storage) {
@@ -975,26 +923,40 @@ class IRGenSILFunction :
975
923
bool IsAnonymous,
976
924
llvm::Optional<Alignment> Align = None) {
977
925
// Never emit shadow copies when optimizing, or if already on the stack. No
978
- // debug info is emitted for refcounts either. Shadow copies are also
979
- // turned off for async functions, because they make it impossible to track
980
- // debug info during coroutine splitting. Instead we are relying on LLVM's
981
- // CoroSplit.cpp to emit shadow copies.
926
+ // debug info is emitted for refcounts either
982
927
983
- // Mark variables in async functions for lifetime extension, so they get
984
- // spilled into the async context.
928
+ // Mark variables in async functions that don't generate a shadow copy for
929
+ // lifetime extension, so they get spilled into the async context.
985
930
if (!IGM.IRGen .Opts .shouldOptimize () && CurSILFn->isAsync ())
986
- if (auto *Value = dyn_cast<llvm::Instruction>(Storage))
987
- if (emitLifetimeExtendingUse (Value))
988
- if (ValueVariables.insert (Value).second )
989
- ValueDomPoints.push_back ({Value, getActiveDominancePoint ()});
931
+ if (isa<llvm::AllocaInst>(Storage) || isa<llvm::Constant>(Storage)) {
932
+ if (emitLifetimeExtendingUse (Storage))
933
+ if (ValueVariables.insert (Storage).second )
934
+ ValueDomPoints.push_back ({Storage, getActiveDominancePoint ()});
935
+ }
936
+
990
937
// This condition must be consistent with emitPoisonDebugValueInst to avoid
991
938
// generating extra shadow copies for debug_value [poison].
992
939
if (!shouldShadowVariable (VarInfo, IsAnonymous)
993
940
|| !shouldShadowStorage (Storage)) {
994
941
return Storage;
995
942
}
943
+
996
944
// Emit a shadow copy.
997
- return emitShadowCopy (Storage, Scope, VarInfo, Align, true );
945
+ auto shadow = emitShadowCopy (Storage, Scope, VarInfo, Align, true );
946
+
947
+ // Mark variables in async functions for lifetime extension, so they get
948
+ // spilled into the async context.
949
+ if (!IGM.IRGen .Opts .shouldOptimize () && CurSILFn->isAsync ()) {
950
+ if (emitLifetimeExtendingUse (shadow)) {
951
+ if (ValueVariables.insert (shadow).second )
952
+ ValueDomPoints.push_back ({shadow, getActiveDominancePoint ()});
953
+ }
954
+ auto inst = cast<llvm::Instruction>(shadow);
955
+ llvm::IRBuilder<> builder (inst->getNextNode ());
956
+ shadow = builder.CreateLoad (shadow);
957
+ }
958
+
959
+ return shadow;
998
960
}
999
961
1000
962
// / Like \c emitShadowCopyIfNeeded() but takes an \c Address instead of an
@@ -1021,11 +983,13 @@ class IRGenSILFunction :
1021
983
// Mark variables in async functions for lifetime extension, so they get
1022
984
// spilled into the async context.
1023
985
if (!IGM.IRGen .Opts .shouldOptimize () && CurSILFn->isAsync ())
1024
- if (vals.begin () != vals.end ())
1025
- if (auto *Value = dyn_cast<llvm::Instruction>(vals.front ()))
986
+ if (vals.begin () != vals.end ()) {
987
+ auto Value = vals.front ();
988
+ if (isa<llvm::Instruction>(Value) || isa<llvm::Argument>(Value))
1026
989
if (emitLifetimeExtendingUse (Value))
1027
990
if (ValueVariables.insert (Value).second )
1028
991
ValueDomPoints.push_back ({Value, getActiveDominancePoint ()});
992
+ }
1029
993
return ;
1030
994
}
1031
995
@@ -1043,6 +1007,15 @@ class IRGenSILFunction :
1043
1007
auto &Alloca = ShadowStackSlots[{ArgNo, {Scope, VarInfo.Name }}];
1044
1008
if (Alloca.isValid ()) {
1045
1009
(void )e.claimAll ();
1010
+ // Async functions use the value of the artificial address.
1011
+ if (CurSILFn->isAsync ()) {
1012
+ auto shadow = Alloca.getAddress ();
1013
+ auto inst = cast<llvm::Instruction>(shadow);
1014
+ llvm::IRBuilder<> builder (inst->getNextNode ());
1015
+ shadow = builder.CreateLoad (shadow);
1016
+ copy.push_back (shadow);
1017
+ return ;
1018
+ }
1046
1019
} else {
1047
1020
SILType Type = SILVal->getType ();
1048
1021
auto <I = cast<LoadableTypeInfo>(IGM.getTypeInfo (Type));
@@ -1051,6 +1024,18 @@ class IRGenSILFunction :
1051
1024
zeroInit (cast<llvm::AllocaInst>(Alloca.getAddress ()));
1052
1025
ArtificialLocation AutoRestore (Scope, IGM.DebugInfo .get (), Builder);
1053
1026
LTI.initialize (*this , e, Alloca, false /* isOutlined */ );
1027
+ auto shadow = Alloca.getAddress ();
1028
+ // Async functions use the value of the artificial address.
1029
+ if (CurSILFn->isAsync () && emitLifetimeExtendingUse (shadow)) {
1030
+ if (ValueVariables.insert (shadow).second )
1031
+ ValueDomPoints.push_back ({shadow, getActiveDominancePoint ()});
1032
+ auto inst = cast<llvm::Instruction>(shadow);
1033
+ llvm::IRBuilder<> builder (inst->getNextNode ());
1034
+ shadow = builder.CreateLoad (shadow);
1035
+ copy.push_back (shadow);
1036
+ return ;
1037
+ }
1038
+
1054
1039
}
1055
1040
copy.push_back (Alloca.getAddress ());
1056
1041
}
@@ -4676,7 +4661,7 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
4676
4661
}
4677
4662
if (i->getDebugScope ()->getInlinedFunction ()->isTransparent ())
4678
4663
return ;
4679
-
4664
+
4680
4665
auto VarInfo = i->getVarInfo ();
4681
4666
assert (VarInfo && " debug_value without debug info" );
4682
4667
auto SILVal = i->getOperand ();
@@ -4716,12 +4701,6 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
4716
4701
IndirectionKind Indirection = DirectValue;
4717
4702
if (CurSILFn->isAsync () &&
4718
4703
!i->getDebugScope ()->InlinedCallSite ) {
4719
- if (VarInfo->ArgNo )
4720
- for (auto &Val : Copy) {
4721
- Val = getDirectCoroutineArgument (Val);
4722
- assert (IGM.DebugInfo ->verifyCoroutineArgument (Val) &&
4723
- " arg expected to be load from inside %swift.context" );
4724
- }
4725
4704
Indirection = CoroDirectValue;
4726
4705
}
4727
4706
@@ -4752,9 +4731,6 @@ void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) {
4752
4731
SILType SILTy = SILVal->getType ();
4753
4732
auto RealType = SILTy.getASTType ();
4754
4733
if (CurSILFn->isAsync () && !i->getDebugScope ()->InlinedCallSite ) {
4755
- if (IGM.DebugInfo && VarInfo->ArgNo )
4756
- assert (IGM.DebugInfo ->verifyCoroutineArgument (Addr) &&
4757
- " arg expected to be load from inside %swift.context" );
4758
4734
Indirection = CoroIndirectValue;
4759
4735
if (auto *PBI = dyn_cast<ProjectBoxInst>(i->getOperand ())) {
4760
4736
// Usually debug info only ever describes the *result* of a projectBox
@@ -5109,6 +5085,16 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i,
5109
5085
SILType SILTy = i->getType ();
5110
5086
auto RealType = SILTy.getASTType ();
5111
5087
auto DbgTy = DebugTypeInfo::getLocalVariable (Decl, RealType, type);
5088
+ // Async functions use the value of the artificial address.
5089
+ auto shadow = addr;
5090
+ if (CurSILFn->isAsync () && emitLifetimeExtendingUse (shadow) &&
5091
+ !isa<llvm::UndefValue>(shadow)) {
5092
+ if (ValueVariables.insert (shadow).second )
5093
+ ValueDomPoints.push_back ({shadow, getActiveDominancePoint ()});
5094
+ auto inst = cast<llvm::Instruction>(shadow);
5095
+ llvm::IRBuilder<> builder (inst->getNextNode ());
5096
+ addr = builder.CreateLoad (shadow);
5097
+ }
5112
5098
5113
5099
bindArchetypes (DbgTy.getType ());
5114
5100
if (IGM.DebugInfo )
0 commit comments