[llvm] [DirectX] Propagate shader flags mask of callees to callers (PR #118306)
Justin Bogner via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 5 16:21:52 PST 2025
================
@@ -46,21 +49,63 @@ static void updateFunctionFlags(ComputedShaderFlags &CSF,
}
}
-void ModuleShaderFlags::initialize(const Module &M) {
- // Collect shader flags for each of the functions
- for (const auto &F : M.getFunctionList()) {
- if (F.isDeclaration())
- continue;
- ComputedShaderFlags CSF;
- for (const auto &BB : F)
- for (const auto &I : BB)
- updateFunctionFlags(CSF, I);
- // Insert shader flag mask for function F
- FunctionFlags.push_back({&F, CSF});
- // Update combined shader flags mask
- CombinedSFMask.merge(CSF);
+void ModuleShaderFlags::initialize(Module &M) {
+ CallGraph CG(M);
+
+ // Compute Shader Flags Mask for all functions using post-order visit of SCC
+ // of the call graph.
+ for (scc_iterator<CallGraph *> SCCI = scc_begin(&CG); !SCCI.isAtEnd();
+ ++SCCI) {
+ const std::vector<CallGraphNode *> &CurSCC = *SCCI;
+
+ // Union of shader masks of all functions in CurSCC
+ ComputedShaderFlags SCCSF;
+ for (CallGraphNode *CGN : CurSCC) {
+ Function *F = CGN->getFunction();
+ if (!F)
+ continue;
+
+ if (F->isDeclaration())
+ continue;
+
+ ComputedShaderFlags CSF;
+ for (const auto &BB : *F)
+ for (const auto &I : BB)
+ updateFunctionFlags(CSF, I);
+ // Update combined shader flags mask for all functions in this SCC
+ SCCSF.merge(CSF);
+ }
+
+ // Update combined shader flags mask for all functions of the module
+ CombinedSFMask.merge(SCCSF);
+
+ // Shader flags mask of each of the functions in an SCC of the call graph is
+ // the union of all functions in the SCC. Update shader flags masks of
+ // functions in SCC accordingly. This is trivially true if SCC contains one
+ // function.
+ for (CallGraphNode *CGN : CurSCC) {
+ Function *F = CGN->getFunction();
+ if (!F)
+ continue;
+ // If F already has a shader flag mask associated as result of
+ // any of its callee's flags being propagated, merge SCCSF with
+ // existing flags. Else set its mask to SCCSF.
+ if (FunctionFlags.contains(F))
+ FunctionFlags[F].merge(SCCSF);
+ else
+ FunctionFlags[F] = SCCSF;
+ // Propagate Shader Flag Masks to callers of F
+ for (const auto User : F->users()) {
+ if (const CallInst *CI = dyn_cast<CallInst>(User)) {
+ const Function *Caller = CI->getParent()->getParent();
+ if (FunctionFlags.contains(Caller))
+ FunctionFlags[Caller].merge(SCCSF);
+ else
+ FunctionFlags[Caller] = SCCSF;
+ }
+ }
----------------
bogner wrote:
We shouldn't need a loop to propagate flags to callers. Instead, we should handle this in `updateFunctionFlags` with something like:
```c++
if (auto *CI = dyn_cast<CallInst>(&I))
CSF.merge(FunctionFlags[CI->getCalledFunction()]);
```
https://github.com/llvm/llvm-project/pull/118306
More information about the llvm-commits
mailing list