@@ -51,33 +51,47 @@ class SILGlobalOpt {
51
51
DominanceAnalysis* DA;
52
52
bool HasChanged = false ;
53
53
54
- // Map each global initializer to a list of call sites.
55
54
typedef SmallVector<ApplyInst *, 4 > GlobalInitCalls;
56
55
typedef SmallVector<LoadInst *, 4 > GlobalLoads;
56
+
57
+ // / A map from each visited global initializer call to a list of call sites.
57
58
llvm::MapVector<SILFunction *, GlobalInitCalls> GlobalInitCallMap;
58
59
59
60
// The following mappings are used if this is a compilation
60
61
// in scripting mode and global variables are accessed without
61
62
// addressors.
62
63
63
- // Map each global let variable to a set of loads from it .
64
+ // / A map from each visited global let variable to its set of loads.
64
65
llvm::MapVector<SILGlobalVariable *, GlobalLoads> GlobalLoadMap;
65
- // Map each global let variable to the store instruction which initializes it.
66
+
67
+ // / A map from each visited global let variable to the store instructions
68
+ // / which initialize it.
66
69
llvm::MapVector<SILGlobalVariable *, StoreInst *> GlobalVarStore;
67
- // Variables in this set should not be processed by this pass
68
- // anymore.
70
+
71
+ // / A set of visited global variables that for some reason we have decided is
72
+ // / not able to be optimized safely or for which we do not know how to
73
+ // / optimize safely.
74
+ // /
75
+ // / Once a global variable is in this set, we no longer will process it.
69
76
llvm::SmallPtrSet<SILGlobalVariable *, 16 > GlobalVarSkipProcessing;
70
77
71
- // Mark any block that this pass has determined to be inside a loop.
78
+ // / The set of blocks that this pass has determined to be inside a loop.
79
+ // /
80
+ // / This is used to mark any block that this pass has determined to be inside
81
+ // / a loop.
72
82
llvm::DenseSet<SILBasicBlock *> LoopBlocks;
73
- // Mark any functions for which loops have been analyzed.
83
+
84
+ // / The set of functions that have had their loops analyzed.
74
85
llvm::DenseSet<SILFunction *> LoopCheckedFunctions;
75
- // Keep track of cold blocks.
86
+
87
+ // / Keep track of cold blocks.
76
88
ColdBlockInfo ColdBlocks;
77
89
78
- // Whether we see a "once" call to callees that we currently don't handle.
90
+ // / Whether we see a "once" call to callees that we currently don't handle.
79
91
bool UnhandledOnceCallee = false ;
80
- // Record number of times a globalinit_func is called by "once".
92
+
93
+ // / A map from a globalinit_func to the number of times "once" has called the
94
+ // / function.
81
95
llvm::DenseMap<SILFunction *, unsigned > InitializerCount;
82
96
public:
83
97
SILGlobalOpt (SILModule *M, DominanceAnalysis *DA)
@@ -86,23 +100,40 @@ class SILGlobalOpt {
86
100
bool run ();
87
101
88
102
protected:
103
+ // / If this is a call to a global initializer, map it.
89
104
void collectGlobalInitCall (ApplyInst *AI);
105
+
106
+ // / If this load is a read from a global let variable, add the load to
107
+ // / GlobalLoadMap[SILG].
90
108
void collectGlobalLoad (LoadInst *SI, SILGlobalVariable *SILG);
109
+
110
+ // / If this store is a write to a global let variable, add the store to
111
+ // / GlobalStoreMap[SILG].
91
112
void collectGlobalStore (StoreInst *SI, SILGlobalVariable *SILG);
113
+
114
+ // / This is the main entrypoint for collecting global accesses.
92
115
void collectGlobalAccess (GlobalAddrInst *GAI);
93
116
94
117
SILGlobalVariable *getVariableOfGlobalInit (SILFunction *AddrF);
118
+
119
+ // / Returns true if we think that \p CurBB is inside a loop.
95
120
bool isInLoop (SILBasicBlock *CurBB);
96
121
void placeInitializers (SILFunction *InitF, ArrayRef<ApplyInst *> Calls);
97
122
98
- // Update UnhandledOnceCallee and InitializerCount by going through all "once"
99
- // calls.
123
+ // / Update UnhandledOnceCallee and InitializerCount by going through all
124
+ // / "once" calls.
100
125
void collectOnceCall (BuiltinInst *AI);
101
- // Set the static initializer and remove "once" from addressor if a global can
102
- // be statically initialized.
126
+
127
+ // / Set the static initializer and remove "once" from addressor if a global
128
+ // / can be statically initialized.
103
129
void optimizeInitializer (SILFunction *AddrF, GlobalInitCalls &Calls);
130
+
131
+ // / Optimize access to the global variable, which is known to have a constant
132
+ // / value. Replace all loads from the global address by invocations of a
133
+ // / getter that returns the value of this variable.
104
134
void optimizeGlobalAccess (SILGlobalVariable *SILG, StoreInst *SI);
105
- // Replace loads from a global variable by the known value.
135
+
136
+ // / Replace loads from a global variable by the known value.
106
137
void replaceLoadsByKnownValue (BuiltinInst *CallToOnce,
107
138
SILFunction *AddrF,
108
139
SILFunction *InitF,
@@ -119,11 +150,11 @@ class InstructionsCloner : public SILClonerWithScopes<InstructionsCloner> {
119
150
120
151
ArrayRef<SILInstruction *> Insns;
121
152
122
- protected:
153
+ protected:
123
154
SILBasicBlock *FromBB, *DestBB;
124
155
125
- public:
126
- // A map of old to new available values.
156
+ public:
157
+ // / A map of old to new available values.
127
158
SmallVector<std::pair<ValueBase *, SILValue>, 16 > AvailVals;
128
159
129
160
InstructionsCloner (SILFunction &F,
@@ -148,7 +179,7 @@ class InstructionsCloner : public SILClonerWithScopes<InstructionsCloner> {
148
179
AvailVals.push_back (std::make_pair (origResults[i], clonedResults[i]));
149
180
}
150
181
151
- // Clone all instructions from Insns into DestBB
182
+ // / Clone all instructions from Insns into DestBB
152
183
void clone () {
153
184
for (auto I : Insns)
154
185
process (I);
@@ -157,7 +188,7 @@ class InstructionsCloner : public SILClonerWithScopes<InstructionsCloner> {
157
188
158
189
} // end anonymous namespace
159
190
160
- // / If this is a call to a global initializer, map it.
191
+ // If this is a call to a global initializer, map it.
161
192
void SILGlobalOpt::collectGlobalInitCall (ApplyInst *AI) {
162
193
SILFunction *F = AI->getReferencedFunction ();
163
194
if (!F || !F->isGlobalInit ())
@@ -166,7 +197,7 @@ void SILGlobalOpt::collectGlobalInitCall(ApplyInst *AI) {
166
197
GlobalInitCallMap[F].push_back (AI);
167
198
}
168
199
169
- // / If this is a read from a global let variable, map it.
200
+ // If this is a read from a global let variable, map it.
170
201
void SILGlobalOpt::collectGlobalLoad (LoadInst *LI, SILGlobalVariable *SILG) {
171
202
assert (SILG);
172
203
// assert(SILG->isLet());
@@ -238,8 +269,8 @@ static SILFunction *getGlobalGetterFunction(SILModule &M,
238
269
IsBare, IsNotTransparent, Serialized);
239
270
}
240
271
241
- // / Generate getter from the initialization code whose
242
- // / result is stored by a given store instruction.
272
+ // / Generate getter from the initialization code whose result is stored by a
273
+ // / given store instruction.
243
274
static SILFunction *genGetterFromInit (StoreInst *Store,
244
275
SILGlobalVariable *SILG) {
245
276
auto *varDecl = SILG->getDecl ();
@@ -300,7 +331,7 @@ static SILFunction *genGetterFromInit(StoreInst *Store,
300
331
return GetterF;
301
332
}
302
333
303
- // / If this is a read from a global let variable, map it.
334
+ // If this is a write to a global let variable, map it.
304
335
void SILGlobalOpt::collectGlobalStore (StoreInst *SI, SILGlobalVariable *SILG) {
305
336
306
337
if (GlobalVarStore.count (SILG)) {
@@ -328,8 +359,8 @@ static SILFunction *getCalleeOfOnceCall(BuiltinInst *BI) {
328
359
return nullptr ;
329
360
}
330
361
331
- // / Update UnhandledOnceCallee and InitializerCount by going through all "once"
332
- // / calls.
362
+ // Update UnhandledOnceCallee and InitializerCount by going through all "once"
363
+ // calls.
333
364
void SILGlobalOpt::collectOnceCall (BuiltinInst *BI) {
334
365
if (UnhandledOnceCallee)
335
366
return ;
@@ -902,10 +933,9 @@ void SILGlobalOpt::collectGlobalAccess(GlobalAddrInst *GAI) {
902
933
}
903
934
}
904
935
905
- // / Optimize access to the global variable, which is known
906
- // / to have a constant value. Replace all loads from the
907
- // / global address by invocations of a getter that returns
908
- // / the value of this variable.
936
+ // Optimize access to the global variable, which is known to have a constant
937
+ // value. Replace all loads from the global address by invocations of a getter
938
+ // that returns the value of this variable.
909
939
void SILGlobalOpt::optimizeGlobalAccess (SILGlobalVariable *SILG,
910
940
StoreInst *SI) {
911
941
DEBUG (llvm::dbgs () << " GlobalOpt: use static initializer for " <<
0 commit comments