@@ -35,6 +35,8 @@ IN THE SOFTWARE.
3535#include " common/LLVMWarningsPop.hpp"
3636#include " Probe/Assertion.h"
3737
38+ #include < unordered_set>
39+
3840using namespace llvm ;
3941using namespace IGC ;
4042using namespace IGC ::IGCMD;
@@ -112,6 +114,8 @@ bool InlineLocalsResolution::runOnModule(Module& M)
112114{
113115 MetaDataUtils* pMdUtils = getAnalysis<MetaDataUtilsWrapper>().getMetaDataUtils ();
114116 ModuleMetaData* modMD = getAnalysis<MetaDataUtilsWrapper>().getModuleMetaData ();
117+ if (!modMD->compOpt .OptDisable )
118+ filterGlobals (M);
115119 // Compute the offset of each inline local in the kernel,
116120 // and their total size.
117121 std::map<Function*, unsigned int > sizeMap;
@@ -214,6 +218,100 @@ bool InlineLocalsResolution::runOnModule(Module& M)
214218 return true ;
215219}
216220
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+
217315void InlineLocalsResolution::collectInfoOnSharedLocalMem (Module& M)
218316{
219317
0 commit comments