[llvm] [AMDGPU] Flatten recursive register resource info propagation (PR #142766)
Scott Linder via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 4 15:03:44 PDT 2025
================
@@ -97,6 +97,87 @@ MCSymbol *MCResourceInfo::getMaxSGPRSymbol(MCContext &OutContext) {
return OutContext.getOrCreateSymbol("amdgpu.max_num_sgpr");
}
+// Tries to flatten recursive call register resource gathering. Simple cycle
+// avoiding dfs to find the constants in the propagated symbols.
+// Assumes:
+// - RecSym has been confirmed to recurse (this means the callee symbols should
+// all be populated, started at RecSym).
+// - Shape of the resource symbol's MCExpr (`max` args are order agnostic):
+// RecSym.MCExpr := max(<constant>+, <callee_symbol>*)
+const MCExpr *MCResourceInfo::flattenedCycleMax(MCSymbol *RecSym,
+ ResourceInfoKind RIK,
+ MCContext &OutContext) {
+ SmallPtrSet<const MCExpr *, 8> Seen;
+ SmallVector<const MCExpr *, 8> WorkList;
+ int64_t Maximum = 0;
+
+ const MCExpr *RecExpr = RecSym->getVariableValue();
+ WorkList.push_back(RecExpr);
+
+ while (!WorkList.empty()) {
+ const MCExpr *CurExpr = WorkList.pop_back_val();
+ switch (CurExpr->getKind()) {
+ default: {
+ // Assuming the recursion is of shape `max(<constant>, <callee_symbol>)`
+ // where <callee_symbol> will eventually recurse. If this condition holds,
+ // the recursion occurs within some other (possibly unresolvable) MCExpr,
+ // thus using the worst case value then.
+ if (CurExpr->isSymbolUsedInExpression(RecSym)) {
+ LLVM_DEBUG(dbgs() << "MCResUse: " << RecSym->getName()
+ << ": Recursion in unexpected sub-expression, using "
+ "module maximum\n");
+ switch (RIK) {
+ default:
+ break;
+ case RIK_NumVGPR:
+ return MCSymbolRefExpr::create(getMaxVGPRSymbol(OutContext),
+ OutContext);
+ break;
+ case RIK_NumSGPR:
+ return MCSymbolRefExpr::create(getMaxSGPRSymbol(OutContext),
+ OutContext);
+ break;
+ case RIK_NumAGPR:
+ return MCSymbolRefExpr::create(getMaxAGPRSymbol(OutContext),
+ OutContext);
+ break;
+ }
+ }
+ break;
+ }
+ case MCExpr::ExprKind::Constant: {
+ int64_t Val = cast<MCConstantExpr>(CurExpr)->getValue();
+ Maximum = std::max(Maximum, Val);
+ break;
+ }
+ case MCExpr::ExprKind::SymbolRef: {
+ const MCSymbolRefExpr *SymExpr = cast<MCSymbolRefExpr>(CurExpr);
+ const MCSymbol &SymRef = SymExpr->getSymbol();
+ if (SymRef.isVariable()) {
+ const MCExpr *SymVal = SymRef.getVariableValue();
+ auto [_, IsSeen] = Seen.insert(SymVal);
----------------
slinder1 wrote:
Nit: The name `IsSeen` sounds like it could also be used for the inverse (i.e. "this is already in Seen")
Maybe just fold into the condition:
`if (Seen.insert(SymVal).second)`
https://github.com/llvm/llvm-project/pull/142766
More information about the llvm-commits
mailing list