20
20
#include " swift/SIL/SILCloner.h"
21
21
#include " swift/SIL/SILGlobalVariable.h"
22
22
#include " swift/SIL/SILInstruction.h"
23
+ #include " swift/SIL/SILInstructionWorklist.h"
23
24
#include " swift/SILOptimizer/Analysis/ColdBlockInfo.h"
24
25
#include " swift/SILOptimizer/Analysis/DominanceAnalysis.h"
25
26
#include " swift/SILOptimizer/PassManager/Passes.h"
@@ -110,7 +111,8 @@ class SILGlobalOpt {
110
111
// / function.
111
112
llvm::DenseMap<SILFunction *, unsigned > InitializerCount;
112
113
113
- llvm::SmallVector<SILInstruction *, 4 > InstToRemove;
114
+ SmallSILInstructionWorklist<4 > InstToRemove;
115
+ llvm::SmallVector<SILGlobalVariable *, 4 > GlobalsToRemove;
114
116
115
117
public:
116
118
SILGlobalOpt (SILOptFunctionBuilder &FunctionBuilder, SILModule *M, DominanceAnalysis *DA)
@@ -860,20 +862,21 @@ static bool isSafeToRemove(SILGlobalVariable *global) {
860
862
861
863
bool SILGlobalOpt::tryRemoveGlobalAlloc (SILGlobalVariable *global,
862
864
AllocGlobalInst *alloc) {
863
- if (!isSafeToRemove (global)) return false ;
864
-
865
- if (GlobalAddrMap[global].size ())
865
+ if (!isSafeToRemove (global))
866
866
return false ;
867
867
868
- InstToRemove.push_back (alloc);
868
+ if (GlobalAddrMap[global].size ())
869
+ return false ;
869
870
871
+ InstToRemove.add (alloc);
870
872
return true ;
871
873
}
872
874
873
875
// / If there are no loads or accesses of a given global, then remove its
874
876
// / associated global addr and all asssociated instructions.
875
877
bool SILGlobalOpt::tryRemoveGlobalAddr (SILGlobalVariable *global) {
876
- if (!isSafeToRemove (global)) return false ;
878
+ if (!isSafeToRemove (global))
879
+ return false ;
877
880
878
881
if (GlobalVarSkipProcessing.count (global) || GlobalLoadMap[global].size () ||
879
882
GlobalAccessMap[global].size ())
@@ -884,22 +887,23 @@ bool SILGlobalOpt::tryRemoveGlobalAddr(SILGlobalVariable *global) {
884
887
if (!isa<StoreInst>(use->getUser ()))
885
888
return false ;
886
889
}
887
- collectUsesOfInstructionForDeletion (addr);
888
- InstToRemove.push_back (addr);
890
+ InstToRemove. addUsersOfAllResultsToWorklist (addr);
891
+ InstToRemove.add (addr);
889
892
}
890
893
891
894
return true ;
892
895
}
893
896
894
897
bool SILGlobalOpt::tryRemoveUnusedGlobal (SILGlobalVariable *global) {
895
- if (!isSafeToRemove (global)) return false ;
898
+ if (!isSafeToRemove (global))
899
+ return false ;
896
900
897
901
if (GlobalVarSkipProcessing.count (global) || GlobalAddrMap[global].size () ||
898
902
GlobalAccessMap[global].size () || GlobalLoadMap[global].size () ||
899
903
AllocGlobalStore.count (global) || GlobalVarStore.count (global))
900
904
return false ;
901
905
902
- Module-> eraseGlobalVariable (global);
906
+ GlobalsToRemove. push_back (global);
903
907
return true ;
904
908
}
905
909
@@ -927,7 +931,6 @@ static LoadInst *getValidLoad(SILInstruction *I, SILValue V) {
927
931
928
932
// / If this is a read from a global let variable, map it.
929
933
void SILGlobalOpt::collectGlobalAccess (GlobalAddrInst *GAI) {
930
- GAI->dump ();
931
934
auto *SILG = GAI->getReferencedGlobal ();
932
935
if (!SILG)
933
936
return ;
@@ -957,7 +960,7 @@ void SILGlobalOpt::collectGlobalAccess(GlobalAddrInst *GAI) {
957
960
// We want to make sure that we still collect global addr instructions
958
961
// that are inside the addressors.
959
962
GlobalAddrMap[SILG].push_back (GAI);
960
-
963
+
961
964
// Ignore any accesses inside addressors for SILG
962
965
auto GlobalVar = getVariableOfGlobalInit (F);
963
966
if (GlobalVar == SILG)
@@ -1055,22 +1058,6 @@ void SILGlobalOpt::reset() {
1055
1058
GlobalInitCallMap.clear ();
1056
1059
}
1057
1060
1058
- void SILGlobalOpt::collectUsesOfInstructionForDeletion (SILInstruction *inst) {
1059
- for (auto result : inst->getResults ()) {
1060
- for (auto *use : result->getUses ()) {
1061
- auto *user = use->getUser ();
1062
- assert (user && " User should never be NULL!" );
1063
- assert (use->get ()->use_begin () == use->get ()->use_end ()
1064
- && " All collected uses must not be used themselves." );
1065
-
1066
- // If the instruction itself has any uses, recursively zap them so that
1067
- // nothing uses this instruction.
1068
- collectUsesOfInstructionForDeletion (user);
1069
- InstToRemove.push_back (user);
1070
- }
1071
- }
1072
- }
1073
-
1074
1061
void SILGlobalOpt::collect () {
1075
1062
for (auto &F : *Module) {
1076
1063
// TODO: Add support for ownership.
@@ -1173,22 +1160,20 @@ bool SILGlobalOpt::run() {
1173
1160
}
1174
1161
1175
1162
// Erase the instructions that we have marked for deletion.
1176
- for (auto *inst : InstToRemove) {
1163
+ while (auto *inst = InstToRemove. pop_back_val () ) {
1177
1164
inst->eraseFromParent ();
1178
1165
}
1179
1166
1180
1167
// After we erase some instructions, re-collect.
1181
1168
reset ();
1182
1169
collect ();
1183
1170
1184
- // Copy the globals so we don't get issues with modifying while iterating.
1185
- SmallVector<SILGlobalVariable *, 12 > globals;
1186
1171
for (auto &global : Module->getSILGlobals ()) {
1187
- globals. push_back (&global);
1172
+ HasChanged |= tryRemoveUnusedGlobal (&global);
1188
1173
}
1189
1174
1190
- for (auto *global : globals ) {
1191
- HasChanged |= tryRemoveUnusedGlobal (global);
1175
+ for (auto *global : GlobalsToRemove ) {
1176
+ Module-> eraseGlobalVariable (global);
1192
1177
}
1193
1178
1194
1179
// Reset incase we re-run this function (when HasChanged is true).
0 commit comments