@@ -241,6 +241,49 @@ LDSUsesInfoTy getTransitiveUsesOfLDS(CallGraph const &CG, Module &M) {
241
241
return {std::move (direct_map_kernel), std::move (indirect_map_kernel)};
242
242
}
243
243
244
+ void removeFnAttrFromReachable (CallGraph &CG, Function *KernelRoot,
245
+ StringRef FnAttr) {
246
+ KernelRoot->removeFnAttr (FnAttr);
247
+
248
+ SmallVector<Function *> Tmp ({CG[KernelRoot]->getFunction ()});
249
+ if (!Tmp.back ())
250
+ return ;
251
+
252
+ SmallPtrSet<Function *, 8 > Visited;
253
+ bool SeenUnknownCall = false ;
254
+
255
+ do {
256
+ Function *F = Tmp.pop_back_val ();
257
+
258
+ for (auto &N : *CG[F]) {
259
+ if (!N.second )
260
+ continue ;
261
+
262
+ Function *Callee = N.second ->getFunction ();
263
+ if (!Callee) {
264
+ if (!SeenUnknownCall) {
265
+ SeenUnknownCall = true ;
266
+
267
+ // If we see any indirect calls, assume nothing about potential
268
+ // targets.
269
+ // TODO: This could be refined to possible LDS global users.
270
+ for (auto &N : *CG.getExternalCallingNode ()) {
271
+ Function *PotentialCallee = N.second ->getFunction ();
272
+ if (!isKernelLDS (PotentialCallee))
273
+ PotentialCallee->removeFnAttr (FnAttr);
274
+ }
275
+
276
+ continue ;
277
+ }
278
+ }
279
+
280
+ Callee->removeFnAttr (FnAttr);
281
+ if (Visited.insert (Callee).second )
282
+ Tmp.push_back (Callee);
283
+ }
284
+ } while (!Tmp.empty ());
285
+ }
286
+
244
287
bool isReallyAClobber (const Value *Ptr, MemoryDef *Def, AAResults *AA) {
245
288
Instruction *DefInst = Def->getMemoryInst ();
246
289
0 commit comments