[llvm] [TableGen] Resolve arguments with fields in records (PR #107829)

Akshat Oke via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 9 02:26:45 PDT 2024


https://github.com/Akshat-Oke created https://github.com/llvm/llvm-project/pull/107829

Previously, instantiating an anonymous record happened in two steps: 
1. Resolve the arguments with a `MapResolver`
2. Resolve the fields with a `RecordResolver`.

In 1, the `MapResolver` cannot resolve references to fields and in 2 the `RecordResolver` cannot resolve references to arguments. This was leading to incomplete resolution in `llvm/test/TableGen/record-recursion.td` (simplified test-case from #91050 ) like so:

1. `MapResolver` fails to resolve the `if` condition since it references the field `v`.
2. Resolving `SumTillN<!sub(n, 1)>.ret)` fails as it references the argument `n` and the `RecordResolver` doesn't know about it.

This patch merges the two steps into one where arguments and fields are resolved by the `RecordResolver` itself. 

>From eb0123c5a4945015926f18b78f885746f67204aa Mon Sep 17 00:00:00 2001
From: Akshat Oke <Akshat.Oke at amd.com>
Date: Mon, 9 Sep 2024 06:16:35 +0000
Subject: [PATCH] [TableGen] Resolve arguments with fields in records

---
 llvm/include/llvm/TableGen/Record.h    |  5 ++++-
 llvm/lib/TableGen/Record.cpp           | 12 +++++++++---
 llvm/test/TableGen/record-recursion.td | 11 +++++++++++
 3 files changed, 24 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/TableGen/record-recursion.td

diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index 98c8fd0ca051f9..287f457b8efd31 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -2289,9 +2289,12 @@ class RecordResolver final : public Resolver {
   DenseMap<Init *, Init *> Cache;
   SmallVector<Init *, 4> Stack;
   Init *Name = nullptr;
+  // Cache is for fields, ArgumentResolver is for arguments.
+  MapResolver *ArgumentResolver;
 
 public:
-  explicit RecordResolver(Record &R) : Resolver(&R) {}
+  explicit RecordResolver(Record &R, MapResolver *ArgumentResolver = nullptr)
+      : Resolver(&R), ArgumentResolver(ArgumentResolver) {}
 
   void setName(Init *NewName) { Name = NewName; }
 
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 85516b7b9f20aa..4c1b9902a9b238 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2321,8 +2321,6 @@ DefInit *VarDefInit::instantiate() {
       R.set(Arg->getName(), Arg->getValue());
   }
 
-  NewRec->resolveReferences(R);
-
   // Add superclasses.
   ArrayRef<std::pair<Record *, SMRange>> SCs = Class->getSuperClasses();
   for (const auto &SCPair : SCs)
@@ -2332,7 +2330,10 @@ DefInit *VarDefInit::instantiate() {
       Class, SMRange(Class->getLoc().back(), Class->getLoc().back()));
 
   // Resolve internal references and store in record keeper
-  NewRec->resolveReferences();
+  RecordResolver RR(*NewRec, &R);
+  RR.setFinal(true);
+  NewRec->resolveReferences(RR);
+
   Records.addDef(std::move(NewRecOwner));
 
   // Check the assertions.
@@ -3348,6 +3349,11 @@ Init *RecordResolver::resolve(Init *VarName) {
   if (Val)
     return Val;
 
+  if (ArgumentResolver && (Val = ArgumentResolver->resolve(VarName))) {
+    Cache[VarName] = Val;
+    return Val;
+  }
+
   if (llvm::is_contained(Stack, VarName))
     return nullptr; // prevent infinite recursion
 
diff --git a/llvm/test/TableGen/record-recursion.td b/llvm/test/TableGen/record-recursion.td
new file mode 100644
index 00000000000000..96ca9df62105a1
--- /dev/null
+++ b/llvm/test/TableGen/record-recursion.td
@@ -0,0 +1,11 @@
+// RUN: llvm-tblgen %s | FileCheck %s
+
+class SumTillN<int n> {
+    int v = !add(n, 0);
+    int ret = !if(!gt(v, 0), !add(v, SumTillN<!sub(n, 1)>.ret), v);
+}
+
+// CHECK: def SumTill4
+// CHECK-NEXT:  int v = 3;
+// CHECK-NEXT:  int ret = 6;
+def SumTill4 : SumTillN<3>;



More information about the llvm-commits mailing list