@@ -35,6 +35,8 @@ IN THE SOFTWARE.
35
35
#include " common/LLVMWarningsPop.hpp"
36
36
#include " Probe/Assertion.h"
37
37
38
+ #include < unordered_set>
39
+
38
40
using namespace llvm ;
39
41
using namespace IGC ;
40
42
using namespace IGC ::IGCMD;
@@ -112,6 +114,8 @@ bool InlineLocalsResolution::runOnModule(Module& M)
112
114
{
113
115
MetaDataUtils* pMdUtils = getAnalysis<MetaDataUtilsWrapper>().getMetaDataUtils ();
114
116
ModuleMetaData* modMD = getAnalysis<MetaDataUtilsWrapper>().getModuleMetaData ();
117
+ if (!modMD->compOpt .OptDisable )
118
+ filterGlobals (M);
115
119
// Compute the offset of each inline local in the kernel,
116
120
// and their total size.
117
121
std::map<Function*, unsigned int > sizeMap;
@@ -214,6 +218,100 @@ bool InlineLocalsResolution::runOnModule(Module& M)
214
218
return true ;
215
219
}
216
220
221
+ void InlineLocalsResolution::filterGlobals (Module& M)
222
+ {
223
+ // This data structure saves all the unused nodes,
224
+ // including the global variable definition itself, as well as all successive recursive user nodes,
225
+ // in all the def-use trees corresponding to all the global variables in the entire Module.
226
+ std::unordered_set<Value*> unusedNodes_forModule;
227
+
228
+ // let's loop all global variables
229
+ for (Module::global_iterator I = M.global_begin (), E = M.global_end (); I != E; ++I)
230
+ {
231
+ // We only care about global variables, not other globals.
232
+ GlobalVariable* globalVar = dyn_cast<GlobalVariable>(&*I);
233
+ if (!globalVar)
234
+ {
235
+ continue ;
236
+ }
237
+
238
+ PointerType* ptrType = cast<PointerType>(globalVar->getType ());
239
+ // We only care about local address space here.
240
+ if (ptrType->getAddressSpace () != ADDRESS_SPACE_LOCAL)
241
+ {
242
+ continue ;
243
+ }
244
+
245
+ // If the globalVar is determined to be unused,
246
+ // this data structure saves the globalVar,
247
+ // as well as all successive recursive user nodes in that def-use tree.
248
+ std::unordered_set<Value*> unusedNodes_forOne;
249
+ if (unusedGlobal (globalVar, unusedNodes_forOne))
250
+ unusedNodes_forModule.insert (unusedNodes_forOne.begin (), unusedNodes_forOne.end ());
251
+ }
252
+
253
+ // We only remove all the unused nodes for this Module,
254
+ // after we are done processing all the global variables for the entire Module,
255
+ // to prevent iterators becoming invalidated when elements get removed from the ilist.
256
+ for (auto & element : unusedNodes_forModule) {
257
+ // for all unused Values,
258
+ // replace all uses with undefs
259
+ // delete the values
260
+ if (Instruction* node = dyn_cast<Instruction>(element)) {
261
+ Type* Ty = node->getType ();
262
+ if (!Ty->isVoidTy ())
263
+ node->replaceAllUsesWith (UndefValue::get (Ty));
264
+ node->eraseFromParent ();
265
+ }
266
+ else if (GlobalVariable* node = dyn_cast<GlobalVariable>(element)) {
267
+ Type* Ty = node->getType ();
268
+ if (!Ty->isVoidTy ())
269
+ node->replaceAllUsesWith (UndefValue::get (Ty));
270
+ node->eraseFromParent ();
271
+ }
272
+ // All other types of nodes are ignored.
273
+ }
274
+ }
275
+
276
+ bool InlineLocalsResolution::unusedGlobal (Value* V, std::unordered_set<Value*>& unusedNodes)
277
+ {
278
+ for (Value::user_iterator U = V->user_begin (), UE = V->user_end (); U != UE; ++U)
279
+ {
280
+ if (GlobalVariable* globalVar = dyn_cast<GlobalVariable>(*U)) {
281
+ if (!unusedGlobal (*U, unusedNodes))
282
+ return false ;
283
+ }
284
+ else if (GetElementPtrInst* gep = dyn_cast<GetElementPtrInst>(*U)) {
285
+ if (!unusedGlobal (*U, unusedNodes))
286
+ return false ;
287
+ }
288
+ else if (BitCastInst* bitcast = dyn_cast<BitCastInst>(*U)) {
289
+ if (!unusedGlobal (*U, unusedNodes))
290
+ return false ;
291
+ }
292
+ else if (StoreInst* store = dyn_cast<StoreInst>(*U)) {
293
+ if (store->isUnordered ()) {
294
+ if (store->getPointerOperand () == V) {
295
+ if (!unusedGlobal (*U, unusedNodes))
296
+ return false ;
297
+ }
298
+ else if (store->getValueOperand () == V) {
299
+ return false ;
300
+ }
301
+ }
302
+ else {
303
+ return false ;
304
+ }
305
+ }
306
+ else { // some other instruction
307
+ return false ;
308
+ }
309
+ }
310
+ // add an unused node to the data structure
311
+ unusedNodes.insert (V);
312
+ return true ;
313
+ }
314
+
217
315
void InlineLocalsResolution::collectInfoOnSharedLocalMem (Module& M)
218
316
{
219
317
0 commit comments