[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