[llvm] [AMDGPU] Preserve resource requirements through call-graph cycles (PR #221625)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 13 11:33:27 PDT 2026
================
@@ -247,33 +252,167 @@ bool AMDGPUMCExpr::evaluateInstPrefSize(MCValue &Res,
bool AMDGPUMCExpr::isSymbolUsedInExpression(const MCSymbol *Sym,
const MCExpr *E) {
- switch (E->getKind()) {
- case MCExpr::Constant:
- return false;
- case MCExpr::Unary:
- return isSymbolUsedInExpression(
- Sym, static_cast<const MCUnaryExpr *>(E)->getSubExpr());
- case MCExpr::Binary: {
- const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(E);
- return isSymbolUsedInExpression(Sym, BE->getLHS()) ||
- isSymbolUsedInExpression(Sym, BE->getRHS());
- }
- case MCExpr::SymbolRef: {
- const MCSymbol &S = static_cast<const MCSymbolRefExpr *>(E)->getSymbol();
- if (S.isVariable())
- return isSymbolUsedInExpression(Sym, S.getVariableValue());
- return &S == Sym;
- }
- case MCExpr::Specifier:
- case MCExpr::Target: {
- auto *TE = static_cast<const AMDGPUMCExpr *>(E);
- for (const MCExpr *E : TE->getArgs())
- if (isSymbolUsedInExpression(Sym, E))
+ SmallVector<const MCExpr *, 16> WorkList{E};
+ SmallPtrSet<const MCExpr *, 16> Seen;
+ while (!WorkList.empty()) {
+ const MCExpr *Expr = WorkList.pop_back_val();
+ if (!Seen.insert(Expr).second)
+ continue;
+ switch (Expr->getKind()) {
+ case MCExpr::Constant:
+ break;
+ case MCExpr::Unary:
+ WorkList.push_back(cast<MCUnaryExpr>(Expr)->getSubExpr());
+ break;
+ case MCExpr::Binary: {
+ const auto *BE = cast<MCBinaryExpr>(Expr);
+ WorkList.push_back(BE->getRHS());
+ WorkList.push_back(BE->getLHS());
+ break;
+ }
+ case MCExpr::SymbolRef: {
+ const MCSymbol &S = cast<MCSymbolRefExpr>(Expr)->getSymbol();
+ if (&S == Sym)
return true;
- return false;
+ if (S.isVariable())
+ WorkList.push_back(S.getVariableValue());
+ break;
+ }
+ case MCExpr::Specifier:
+ WorkList.push_back(cast<MCSpecifierExpr>(Expr)->getSubExpr());
+ break;
+ case MCExpr::Target:
+ append_range(WorkList, reverse(cast<AMDGPUMCExpr>(Expr)->getArgs()));
+ break;
+ }
}
+ return false;
+}
+
+// Resource expressions form a DAG of maxima, boolean unions, and frame-size
+// additions. Evaluate shared subexpressions once per query, including additions
+// between maxima, instead of recursively expanding every path through the DAG.
+static bool evaluateResourceExpr(const AMDGPUMCExpr *Root, MCValue &Res,
+ const MCAssembler *Asm) {
+ enum class Phase { Visit, Complete, CheckAbsolute };
+ struct WorkItem {
+ const MCExpr *Expr;
+ Phase Step = Phase::Visit;
+ MCSymbol *ResolvingSymbol = nullptr;
+ };
+ SmallVector<WorkItem, 16> WorkList{{Root}};
----------------
arsenm wrote:
```suggestion
SmallVector<WorkItem, 16> WorkList = {Root};
```
https://github.com/llvm/llvm-project/pull/221625
More information about the llvm-commits
mailing list