@@ -394,7 +394,7 @@ namespace {
394
394
395
395
// / This is a map of uses that are not loads (i.e., they are Stores,
396
396
// / InOutUses, and Escapes), to their entry in Uses.
397
- llvm::SmallDenseMap<SILInstruction*, unsigned , 16 > NonLoadUses;
397
+ llvm::SmallDenseMap<SILInstruction*, SmallVector< unsigned , 1 > , 16 > NonLoadUses;
398
398
399
399
// / This is true when there is an ambiguous store, which may be an init or
400
400
// / assign, depending on the CFG path.
@@ -472,7 +472,7 @@ namespace {
472
472
473
473
void handleSelfInitUse (unsigned UseID);
474
474
475
- void updateInstructionForInitState (DIMemoryUse &Use );
475
+ void updateInstructionForInitState (unsigned UseID );
476
476
477
477
478
478
void processUninitializedRelease (SILInstruction *Release,
@@ -544,7 +544,7 @@ LifetimeChecker::LifetimeChecker(const DIMemoryObjectInfo &TheMemory,
544
544
break ;
545
545
}
546
546
547
- NonLoadUses[Use.Inst ] = ui ;
547
+ NonLoadUses[Use.Inst ]. push_back (ui) ;
548
548
549
549
auto &BBInfo = getBlockInfo (Use.Inst ->getParent ());
550
550
BBInfo.HasNonLoadUse = true ;
@@ -562,9 +562,8 @@ LifetimeChecker::LifetimeChecker(const DIMemoryObjectInfo &TheMemory,
562
562
getBlockInfo (bb).markStoreToSelf ();
563
563
}
564
564
565
- // If isn't really a use, but we account for the mark_uninitialized or
565
+ // It isn't really a use, but we account for the mark_uninitialized or
566
566
// project_box as a use so we see it in our dataflow walks.
567
- NonLoadUses[TheMemory.getUninitializedValue ()] = ~0U ;
568
567
auto &MemBBInfo = getBlockInfo (TheMemory.getParentBlock ());
569
568
MemBBInfo.HasNonLoadUse = true ;
570
569
@@ -826,7 +825,7 @@ void LifetimeChecker::doIt() {
826
825
// postpone lowering of assignment instructions to avoid deleting
827
826
// instructions that still appear in the Uses list.
828
827
for (unsigned UseID : NeedsUpdateForInitState)
829
- updateInstructionForInitState (Uses[ UseID] );
828
+ updateInstructionForInitState (UseID);
830
829
}
831
830
832
831
void LifetimeChecker::handleLoadUse (const DIMemoryUse &Use) {
@@ -1911,7 +1910,8 @@ void LifetimeChecker::handleSelfInitUse(unsigned UseID) {
1911
1910
// / from being InitOrAssign to some concrete state, update it for that state.
1912
1911
// / This includes rewriting them from assign instructions into their composite
1913
1912
// / operations.
1914
- void LifetimeChecker::updateInstructionForInitState (DIMemoryUse &Use) {
1913
+ void LifetimeChecker::updateInstructionForInitState (unsigned UseID) {
1914
+ DIMemoryUse &Use = Uses[UseID];
1915
1915
SILInstruction *Inst = Use.Inst ;
1916
1916
1917
1917
IsInitialization_t InitKind;
@@ -1945,10 +1945,11 @@ void LifetimeChecker::updateInstructionForInitState(DIMemoryUse &Use) {
1945
1945
// If this is an assign, rewrite it based on whether it is an initialization
1946
1946
// or not.
1947
1947
if (auto *AI = dyn_cast<AssignInst>(Inst)) {
1948
+
1948
1949
// Remove this instruction from our data structures, since we will be
1949
1950
// removing it.
1950
1951
Use.Inst = nullptr ;
1951
- NonLoadUses. erase ( Inst);
1952
+ llvm::erase_if (NonLoadUses[ Inst], [&]( unsigned id) { return id == UseID; } );
1952
1953
1953
1954
if (TheMemory.isClassInitSelf () &&
1954
1955
Use.Kind == DIUseKind::SelfInit) {
@@ -1966,7 +1967,7 @@ void LifetimeChecker::updateInstructionForInitState(DIMemoryUse &Use) {
1966
1967
// Remove this instruction from our data structures, since we will be
1967
1968
// removing it.
1968
1969
Use.Inst = nullptr ;
1969
- NonLoadUses. erase ( Inst);
1970
+ llvm::erase_if (NonLoadUses[ Inst], [&]( unsigned id) { return id == UseID; } );
1970
1971
1971
1972
switch (Use.Kind ) {
1972
1973
case DIUseKind::Initialization:
@@ -2819,17 +2820,17 @@ LifetimeChecker::getLivenessAtNonTupleInst(swift::SILInstruction *Inst,
2819
2820
--BBI;
2820
2821
SILInstruction *TheInst = &*BBI;
2821
2822
2822
- // If this instruction is unrelated to the memory, ignore it.
2823
- if (!NonLoadUses.count (TheInst))
2824
- continue ;
2823
+ if (TheInst == TheMemory.getUninitializedValue ()) {
2824
+ Result.set (0 , DIKind::No);
2825
+ return Result;
2826
+ }
2825
2827
2826
- // If we found the allocation itself, then we are loading something that
2827
- // is not defined at all yet. Otherwise, we've found a definition, or
2828
- // something else that will require that the memory is initialized at
2829
- // this point.
2830
- Result.set (0 , TheInst == TheMemory.getUninitializedValue () ? DIKind::No
2831
- : DIKind::Yes);
2832
- return Result;
2828
+ if (NonLoadUses.count (TheInst)) {
2829
+ // We've found a definition, or something else that will require that
2830
+ // the memory is initialized at this point.
2831
+ Result.set (0 , DIKind::Yes);
2832
+ return Result;
2833
+ }
2833
2834
}
2834
2835
}
2835
2836
@@ -2882,11 +2883,6 @@ AvailabilitySet LifetimeChecker::getLivenessAtInst(SILInstruction *Inst,
2882
2883
--BBI;
2883
2884
SILInstruction *TheInst = &*BBI;
2884
2885
2885
- // If this instruction is unrelated to the memory, ignore it.
2886
- auto It = NonLoadUses.find (TheInst);
2887
- if (It == NonLoadUses.end ())
2888
- continue ;
2889
-
2890
2886
// If we found the allocation itself, then we are loading something that
2891
2887
// is not defined at all yet. Scan no further.
2892
2888
if (TheInst == TheMemory.getUninitializedValue ()) {
@@ -2896,11 +2892,19 @@ AvailabilitySet LifetimeChecker::getLivenessAtInst(SILInstruction *Inst,
2896
2892
return Result;
2897
2893
}
2898
2894
2895
+ // If this instruction is unrelated to the memory, ignore it.
2896
+ auto It = NonLoadUses.find (TheInst);
2897
+ if (It == NonLoadUses.end ())
2898
+ continue ;
2899
+
2899
2900
// Check to see which tuple elements this instruction defines. Clear them
2900
2901
// from the set we're scanning from.
2901
- auto &TheInstUse = Uses[It->second ];
2902
- NeededElements.reset (TheInstUse.FirstElement ,
2903
- TheInstUse.FirstElement +TheInstUse.NumElements );
2902
+ for (unsigned TheUse : It->second ) {
2903
+ auto &TheInstUse = Uses[TheUse];
2904
+ NeededElements.reset (TheInstUse.FirstElement ,
2905
+ TheInstUse.FirstElement +TheInstUse.NumElements );
2906
+ }
2907
+
2904
2908
// If that satisfied all of the elements we're looking for, then we're
2905
2909
// done. Otherwise, keep going.
2906
2910
if (NeededElements.none ()) {
0 commit comments