[PATCH] D43150: [tablegen] Recursively evaluate values of variable initializers.

Artem Belevich via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 9 16:28:54 PST 2018


tra created this revision.
tra added a reviewer: arsenm.
Herald added subscribers: hiraditya, jlebar, wdng, sanjoy.

Otherwise we often end up with partially evaluated fields even when 
their (evaluated) values are known at the time of the record instantiation.


https://reviews.llvm.org/D43150

Files:
  llvm/lib/TableGen/Record.cpp
  llvm/test/TableGen/var-eval.td


Index: llvm/test/TableGen/var-eval.td
===================================================================
--- /dev/null
+++ llvm/test/TableGen/var-eval.td
@@ -0,0 +1,41 @@
+// RUN: llvm-tblgen %s | FileCheck %s
+
+// Make sure that tablegen evaluates all values of the record fields.
+def r0;
+def r1;
+class A {
+  dag a = (r0 r1);
+}
+
+class B<int i> : A {
+  dag b0 = (r0 );
+  dag b1 = (r1 );
+  dag b2 = !if(i, b1, b0);
+
+  let a = b2;
+  dag b = b2;
+}
+
+// CHECK-LABEL: def b
+def b : B<1>;
+// both a and b should be evaluated.
+// CHECK: dag a = (r1);
+// CHECK: dag b = (r1);
+
+// NAME is a special case for the field evaluation. Make sure we don't recurse
+// infinitely and that NAME has the right value.
+multiclass M {
+  def NAME : B<0>;
+  def NAME # "a" : B<1>;
+}
+
+defm m : M;
+// CHECK-LABEL: def m
+// CHECK: dag a = (r0);
+// CHECK: dag b = (r0);
+// CHECK: string NAME = "m"
+
+// CHECK-LABEL: def ma
+// CHECK: dag a = (r1);
+// CHECK: dag b = (r1);
+// CHECK: string NAME = "m"
Index: llvm/lib/TableGen/Record.cpp
===================================================================
--- llvm/lib/TableGen/Record.cpp
+++ llvm/lib/TableGen/Record.cpp
@@ -1304,8 +1304,14 @@
 
 Init *VarInit::resolveReferences(Record &R, const RecordVal *RV) const {
   if (RecordVal *Val = R.getValue(VarName))
-    if (RV == Val || (!RV && !isa<UnsetInit>(Val->getValue())))
-      return Val->getValue();
+    if (RV == Val || (!RV && !isa<UnsetInit>(Val->getValue()))) {
+      Init *TheInit = Val->getValue();
+      // Prevent recursion if this variable refers to itself.
+      if (TheInit == this || VarName->getAsUnquotedString() == "NAME")
+        return TheInit;
+      // Otherwise resolve all downstream references.
+      return TheInit->resolveReferences(R, RV);
+    }
   return const_cast<VarInit *>(this);
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D43150.133716.patch
Type: text/x-patch
Size: 1840 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180210/dbca1986/attachment.bin>


More information about the llvm-commits mailing list