[llvm-branch-commits] [llvm] a022be6 - [TableGen] Enhance !cast to handle bit and bits types.

2021-01-14 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2021-01-14T10:20:35-05:00
New Revision: a022be625387370cf67b26c6b99b05f16b2a8610

URL: 
https://github.com/llvm/llvm-project/commit/a022be625387370cf67b26c6b99b05f16b2a8610
DIFF: 
https://github.com/llvm/llvm-project/commit/a022be625387370cf67b26c6b99b05f16b2a8610.diff

LOG: [TableGen] Enhance !cast to handle bit and bits types.

Add a test for this.

Differential Revision: https://reviews.llvm.org/D94529

Added: 
llvm/test/TableGen/cast-string.td

Modified: 
llvm/lib/TableGen/Record.cpp

Removed: 




diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index d047b7bdf1cd..74786e040018 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -689,8 +689,10 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
   if (DefInit *LHSd = dyn_cast(LHS))
 return StringInit::get(LHSd->getAsString());
 
-  if (IntInit *LHSi = dyn_cast(LHS))
+  if (IntInit *LHSi =
+  
dyn_cast_or_null(LHS->convertInitializerTo(IntRecTy::get(
 return StringInit::get(LHSi->getAsString());
+
 } else if (isa(getType())) {
   if (StringInit *Name = dyn_cast(LHS)) {
 if (!CurRec && !IsFinal)

diff  --git a/llvm/test/TableGen/cast-string.td 
b/llvm/test/TableGen/cast-string.td
new file mode 100644
index ..be25d24a3b9f
--- /dev/null
+++ b/llvm/test/TableGen/cast-string.td
@@ -0,0 +1,59 @@
+// RUN: llvm-tblgen %s | FileCheck %s
+// RUN: not llvm-tblgen -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s
+
+// This file tests the !cast bang operator with the result type string.
+
+defvar IntList = [0, 1, 2, 3, 4, 5, 6];
+
+// CHECK: def Rec0
+// CHECK:   string str3 = "a string here"
+
+def Rec0 {
+  string str = "a string";
+  string str2 = !cast(str);
+  string str3 = !cast(str # " here");
+}
+
+// CHECK: def Rec1
+// CHECK:   string str = "42 -108"
+
+def Rec1 {
+  int int1 = 42;
+  int int2 = -108;
+  string str = !cast(int1) # " " # !cast(int2);
+}
+
+// CHECK: def Rec2
+// CHECK:   string str = "0, 1"
+
+def Rec2 {
+  bit bit1 = false;
+  bit bit2 = true;
+  string str = !cast(bit1) # ", " # !cast(bit2);
+}
+
+// CHECK: def Rec3
+// CHECK:   string str = "5 and 37"
+
+def Rec3 {
+  bits<4> bits1 = 0b0101;
+  bits<8> bits2 = 0b00100101;
+  string str = !cast(bits1) # " and " # !cast(bits2);
+}
+
+// CHECK: def Rec4
+// CHECK:   string str = "Rec1, Rec2"
+
+def Rec4 {
+  string str = !cast(Rec1) # ", " # !cast(Rec2);
+}
+
+#ifdef ERROR1
+
+// ERROR1: nitializer of 'str' in 'Rec5' could not be fully resolved
+
+def Rec5 {
+  string str = !cast(IntList);
+}
+
+#endif



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] c056f82 - [TableGen] Improve algorithm for inheriting class template args and fields

2021-01-20 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2021-01-20T09:31:43-05:00
New Revision: c056f824340ff0189f3ef7870b83e3730de401d1

URL: 
https://github.com/llvm/llvm-project/commit/c056f824340ff0189f3ef7870b83e3730de401d1
DIFF: 
https://github.com/llvm/llvm-project/commit/c056f824340ff0189f3ef7870b83e3730de401d1.diff

LOG: [TableGen] Improve algorithm for inheriting class template args and fields

Differential Revision: https://reviews.llvm.org/D94822

Added: 


Modified: 
llvm/include/llvm/TableGen/Record.h
llvm/lib/TableGen/Record.cpp
llvm/lib/TableGen/TGParser.cpp
llvm/test/TableGen/self-reference-typeerror.td

Removed: 




diff  --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index 2853a471b67f..b615385d3a05 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1996,6 +1996,12 @@ class MapResolver final : public Resolver {
 
   void set(Init *Key, Init *Value) { Map[Key] = {Value, false}; }
 
+  bool isComplete(Init *VarName) const {
+auto It = Map.find(VarName);
+assert(It != Map.end() && "key must be present in map");
+return It->second.V->isComplete();
+  }
+
   Init *resolve(Init *VarName) override;
 };
 

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 74786e040018..966599e29e82 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2316,7 +2316,7 @@ void Record::resolveReferences(Resolver &R, const 
RecordVal *SkipVal) {
   Type =
   (Twine("of type '") + VRT->getType()->getAsString() + "' 
").str();
 PrintFatalError(getLoc(), Twine("Invalid value ") + Type +
-  "is found when setting '" +
+  "found when setting field '" +
   Value.getNameInitAsString() +
   "' of type '" +
   Value.getType()->getAsString() +

diff  --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 24949f0b2b4d..63b304164d42 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -229,38 +229,33 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init 
*ValName,
 /// args as SubClass's template arguments.
 bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
   Record *SC = SubClass.Rec;
-  // Add all of the values in the subclass into the current class.
-  for (const RecordVal &Val : SC->getValues())
-if (AddValue(CurRec, SubClass.RefRange.Start, Val))
-  return true;
-
-  ArrayRef TArgs = SC->getTemplateArgs();
-
-  // Ensure that an appropriate number of template arguments are specified.
-  if (TArgs.size() < SubClass.TemplateArgs.size())
-return Error(SubClass.RefRange.Start,
- "More template args specified than expected");
-
-  // Loop over all of the template arguments, setting them to the specified
-  // value or leaving them as the default if necessary.
   MapResolver R(CurRec);
 
-  for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
-if (i < SubClass.TemplateArgs.size()) {
-  // If a value is specified for this template arg, set it now.
-  if (SetValue(CurRec, SubClass.RefRange.Start, TArgs[i],
-   None, SubClass.TemplateArgs[i]))
+  // Loop over all the subclass record's fields. Add template arguments
+  // to the resolver map. Add regular fields to the new record.
+  for (const RecordVal &Field : SC->getValues()) {
+if (Field.isTemplateArg()) {
+  R.set(Field.getNameInit(), Field.getValue());
+} else {
+  if (AddValue(CurRec, SubClass.RefRange.Start, Field))
 return true;
-} else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
-  return Error(SubClass.RefRange.Start,
-   "Value not specified for template argument #" +
-   Twine(i) + " (" + TArgs[i]->getAsUnquotedString() +
-   ") of subclass '" + SC->getNameInitAsString() + "'!");
 }
+  }
 
-R.set(TArgs[i], CurRec->getValue(TArgs[i])->getValue());
-
-CurRec->removeValue(TArgs[i]);
+  ArrayRef TArgs = SC->getTemplateArgs();
+  assert(SubClass.TemplateArgs.size() <= TArgs.size() &&
+ "Too many template arguments allowed");
+
+  // Loop over the template argument names. If a value was specified,
+  // reset the map value. If not and there was no default, complain.
+  for (unsigned I = 0, E = TArgs.size(); I != E; ++I) {
+if (I < SubClass.TemplateArgs.size())
+  R.set(TArgs[I], SubClass.TemplateArgs[I]);
+else if (!R.isComplete(TArgs[I]))
+  return Error(SubClass.RefRange.Start,
+   "Value not specified for template argument #" +
+   Twine(I) + " (" + TArgs[I]->getAsUnquotedString() +
+   ") of parent class '" + SC-

[llvm-branch-commits] [llvm] 4f5f29d - Revert "[TableGen] Improve algorithm for inheriting class template args and fields"

2021-01-20 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2021-01-20T09:47:13-05:00
New Revision: 4f5f29d40974b9ba6e89179dda738c1eb9794370

URL: 
https://github.com/llvm/llvm-project/commit/4f5f29d40974b9ba6e89179dda738c1eb9794370
DIFF: 
https://github.com/llvm/llvm-project/commit/4f5f29d40974b9ba6e89179dda738c1eb9794370.diff

LOG: Revert "[TableGen] Improve algorithm for inheriting class template args 
and fields"

This reverts commit c056f824340ff0189f3ef7870b83e3730de401d1.

That commit causes build failures.

Added: 


Modified: 
llvm/include/llvm/TableGen/Record.h
llvm/lib/TableGen/Record.cpp
llvm/lib/TableGen/TGParser.cpp
llvm/test/TableGen/self-reference-typeerror.td

Removed: 




diff  --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index b615385d3a05..2853a471b67f 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1996,12 +1996,6 @@ class MapResolver final : public Resolver {
 
   void set(Init *Key, Init *Value) { Map[Key] = {Value, false}; }
 
-  bool isComplete(Init *VarName) const {
-auto It = Map.find(VarName);
-assert(It != Map.end() && "key must be present in map");
-return It->second.V->isComplete();
-  }
-
   Init *resolve(Init *VarName) override;
 };
 

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 966599e29e82..74786e040018 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2316,7 +2316,7 @@ void Record::resolveReferences(Resolver &R, const 
RecordVal *SkipVal) {
   Type =
   (Twine("of type '") + VRT->getType()->getAsString() + "' 
").str();
 PrintFatalError(getLoc(), Twine("Invalid value ") + Type +
-  "found when setting field '" +
+  "is found when setting '" +
   Value.getNameInitAsString() +
   "' of type '" +
   Value.getType()->getAsString() +

diff  --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 63b304164d42..24949f0b2b4d 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -229,33 +229,38 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init 
*ValName,
 /// args as SubClass's template arguments.
 bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
   Record *SC = SubClass.Rec;
+  // Add all of the values in the subclass into the current class.
+  for (const RecordVal &Val : SC->getValues())
+if (AddValue(CurRec, SubClass.RefRange.Start, Val))
+  return true;
+
+  ArrayRef TArgs = SC->getTemplateArgs();
+
+  // Ensure that an appropriate number of template arguments are specified.
+  if (TArgs.size() < SubClass.TemplateArgs.size())
+return Error(SubClass.RefRange.Start,
+ "More template args specified than expected");
+
+  // Loop over all of the template arguments, setting them to the specified
+  // value or leaving them as the default if necessary.
   MapResolver R(CurRec);
 
-  // Loop over all the subclass record's fields. Add template arguments
-  // to the resolver map. Add regular fields to the new record.
-  for (const RecordVal &Field : SC->getValues()) {
-if (Field.isTemplateArg()) {
-  R.set(Field.getNameInit(), Field.getValue());
-} else {
-  if (AddValue(CurRec, SubClass.RefRange.Start, Field))
+  for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
+if (i < SubClass.TemplateArgs.size()) {
+  // If a value is specified for this template arg, set it now.
+  if (SetValue(CurRec, SubClass.RefRange.Start, TArgs[i],
+   None, SubClass.TemplateArgs[i]))
 return true;
-}
-  }
-
-  ArrayRef TArgs = SC->getTemplateArgs();
-  assert(SubClass.TemplateArgs.size() <= TArgs.size() &&
- "Too many template arguments allowed");
-
-  // Loop over the template argument names. If a value was specified,
-  // reset the map value. If not and there was no default, complain.
-  for (unsigned I = 0, E = TArgs.size(); I != E; ++I) {
-if (I < SubClass.TemplateArgs.size())
-  R.set(TArgs[I], SubClass.TemplateArgs[I]);
-else if (!R.isComplete(TArgs[I]))
+} else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
   return Error(SubClass.RefRange.Start,
"Value not specified for template argument #" +
-   Twine(I) + " (" + TArgs[I]->getAsUnquotedString() +
-   ") of parent class '" + SC->getNameInitAsString() + 
"'");
+   Twine(i) + " (" + TArgs[i]->getAsUnquotedString() +
+   ") of subclass '" + SC->getNameInitAsString() + "'!");
+}
+
+R.set(TArgs[i], CurRec->getValue(TArgs[i])->getValue());
+
+CurRec->removeValue(TArgs[i]);
   }
 
   Init *Nam

[llvm-branch-commits] [mlir] f4c39cc - [TableGen] Continue cleaning up .td files

2021-01-01 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2021-01-01T10:21:02-05:00
New Revision: f4c39ccd2214800958d9dbd44d023d63f9891cba

URL: 
https://github.com/llvm/llvm-project/commit/f4c39ccd2214800958d9dbd44d023d63f9891cba
DIFF: 
https://github.com/llvm/llvm-project/commit/f4c39ccd2214800958d9dbd44d023d63f9891cba.diff

LOG: [TableGen] Continue cleaning up .td files

This pass includes LLVM and MLIR files.

Differential Revision: https://reviews.llvm.org/D93864

Added: 


Modified: 
llvm/include/llvm/IR/IntrinsicsARM.td
llvm/include/llvm/IR/IntrinsicsNVVM.td
llvm/include/llvm/Option/OptParser.td
llvm/lib/Target/NVPTX/NVPTXIntrinsics.td
mlir/include/mlir/Dialect/ArmSVE/ArmSVE.td
mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
mlir/include/mlir/Dialect/Tosa/IR/TosaTypesBase.td
mlir/include/mlir/IR/OpBase.td

Removed: 




diff  --git a/llvm/include/llvm/IR/IntrinsicsARM.td 
b/llvm/include/llvm/IR/IntrinsicsARM.td
index edc84a54ccc2..0eb27cc34462 100644
--- a/llvm/include/llvm/IR/IntrinsicsARM.td
+++ b/llvm/include/llvm/IR/IntrinsicsARM.td
@@ -922,7 +922,7 @@ multiclass MVEPredicatedM rets, 
list params,
   list props = [IntrNoMem]> {
   def "": Intrinsic;
   def _predicated: Intrinsic(rets[0]), "llvm_anyvector_ty"),
+  !if(!eq(rets[0], llvm_anyvector_ty),
   LLVMMatchType<0>, rets[0])], props>;
 }
 

diff  --git a/llvm/include/llvm/IR/IntrinsicsNVVM.td 
b/llvm/include/llvm/IR/IntrinsicsNVVM.td
index 37a9aceaa61e..2ab48cfc4bb7 100644
--- a/llvm/include/llvm/IR/IntrinsicsNVVM.td
+++ b/llvm/include/llvm/IR/IntrinsicsNVVM.td
@@ -231,11 +231,11 @@ class NVVM_MMA_OPS {
 
 def NVVM_MMA_OPS : NVVM_MMA_OPS;
 
-// Returns [1] if this combination of layout/satf is supported, [] otherwise.
+// Returns true if this combination of layout/satf is supported; false 
otherwise.
 // MMA ops must provide all parameters. Loads and stores -- only frags and 
layout_a.
 // The class is used to prevent generation of records for the unsupported 
variants.
 // E.g.
-// foreach _ = NVVM_MMA_SUPPORTED<...>.ret in =
+// if NVVM_MMA_SUPPORTED<...>.ret then
 //   def : FOO<>; // The record will only be defined for supported ops.
 //
 class NVVM_MMA_SUPPORTED frags, string layout_a, string 
layout_b="-", int satf=-1> {
@@ -261,20 +261,20 @@ class NVVM_MMA_SUPPORTED frags, string 
layout_a, string layout_b
# !if(!eq(!size(frags), 4),
  frags[2].ptx_elt_type # frags[3].ptx_elt_type,
  "?");
-  list ret = !cond(
+  bit ret = !cond(
 // Sub-int MMA only supports fixed A/B layout.
 // b1 does not support .satf.
-!eq(mma#":"#satf, "b1:row:col:0") : [1],
+!eq(mma#":"#satf, "b1:row:col:0") : true,
 // mma.m8n8k4 has no .satf modifier.
 !and(!eq(frags[0].geom, "m8n8k4"),
- !ne(satf, 0)): [],
+ !ne(satf, 0)): false,
 
 // mma.m8n8k4 has no C=f32 D=f16 variant.
-!eq(gcd, "m8n8k4:f32f16"): [],
-!eq(mma, "s4:row:col") : [1],
-!eq(mma, "u4:row:col") : [1],
-!eq(mma, "s4:row:col") : [1],
-!eq(mma, "u4:row:col") : [1],
+!eq(gcd, "m8n8k4:f32f16"): false,
+!eq(mma, "s4:row:col") : true,
+!eq(mma, "u4:row:col") : true,
+!eq(mma, "s4:row:col") : true,
+!eq(mma, "u4:row:col") : true,
 // Sub-int load/stores have fixed layout for A and B.
 !and(!eq(layout_b, "-"), // It's a Load or Store op
  !or(!eq(ld,  "b1:a:row"),
@@ -288,13 +288,13 @@ class NVVM_MMA_SUPPORTED frags, string 
layout_a, string layout_b
  !eq(ld, "u4:a:row"),
  !eq(ld, "u4:b:col"),
  !eq(ldf, "u4:c"),
- !eq(ldf, "u4:d"))) : [1],
+ !eq(ldf, "u4:d"))) : true,
 // All other sub-int ops are not supported.
-!eq(t, "b1") : [],
-!eq(t, "s4") : [],
-!eq(t, "u4") : [],
+!eq(t, "b1") : false,
+!eq(t, "s4") : false,
+!eq(t, "u4") : false,
 // All other (non sub-int) are OK.
-true: [1]
+true: true
   );
 }
 
@@ -4120,11 +4120,11 @@ class NVVM_WMMA_ST
 foreach layout = ["row", "col"] in {
   foreach stride = [0, 1] in {
 foreach frag = NVVM_MMA_OPS.all_ld_ops in
-  foreach _ = NVVM_MMA_SUPPORTED<[frag], layout>.ret in
+  if NVVM_MMA_SUPPORTED<[frag], layout>.ret then
 def WMMA_NAME_LDST<"load", frag, layout, stride>.record
  : NVVM_WMMA_LD;
 foreach frag = NVVM_MMA_OPS.all_st_ops in
-  foreach _ = NVVM_MMA_SUPPORTED<[frag], layout>.ret in
+  if NVVM_MMA_SUPPORTED<[frag], layout>.ret then
 def WMMA_NAME_LDST<"store", frag, layout, stride>.record
  : NVVM_WMMA_ST;
   }
@@ -4143,7 +4143,7 @@ foreach layout_a = ["row", "col"] in {
   foreach layout_b = ["row", "col"] in {
 foreach satf = [0, 1] in {
   foreach op = NVVM_MMA_OPS.all_mma_ops in {
-foreach _ = NVVM_MMA_SUPPORTED.ret in {
+

[llvm-branch-commits] [llvm] aa7968a - [TableGen] Add field kind to the RecordVal class.

2021-01-07 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2021-01-07T09:31:27-05:00
New Revision: aa7968a87b65f97c1245348f6c2a75fc9e420bb5

URL: 
https://github.com/llvm/llvm-project/commit/aa7968a87b65f97c1245348f6c2a75fc9e420bb5
DIFF: 
https://github.com/llvm/llvm-project/commit/aa7968a87b65f97c1245348f6c2a75fc9e420bb5.diff

LOG: [TableGen] Add field kind to the RecordVal class.

Differential Revision: https://reviews.llvm.org/D93969

Added: 


Modified: 
llvm/include/llvm/TableGen/Record.h
llvm/lib/TableGen/JSONBackend.cpp
llvm/lib/TableGen/Record.cpp
llvm/lib/TableGen/TGParser.cpp
llvm/utils/TableGen/CodeEmitterGen.cpp
llvm/utils/TableGen/FixedLenDecoderEmitter.cpp

Removed: 




diff  --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index a0c5b2778547..8dea76fb64a2 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1369,14 +1369,22 @@ class DagInit final : public TypedInit, public 
FoldingSetNode,
 class RecordVal {
   friend class Record;
 
+public:
+  enum FieldKind {
+FK_Normal,// A normal record field.
+FK_NonconcreteOK, // A field that can be nonconcrete ('field' keyword).
+FK_TemplateArg,   // A template argument.
+  };
+
+private:
   Init *Name;
   SMLoc Loc; // Source location of definition of name.
-  PointerIntPair TyAndPrefix;
+  PointerIntPair TyAndKind;
   Init *Value;
 
 public:
-  RecordVal(Init *N, RecTy *T, bool P);
-  RecordVal(Init *N, SMLoc Loc, RecTy *T, bool P);
+  RecordVal(Init *N, RecTy *T, FieldKind K);
+  RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K);
 
   /// Get the name of the field as a StringRef.
   StringRef getName() const;
@@ -1392,10 +1400,18 @@ class RecordVal {
   /// Get the source location of the point where the field was defined.
   const SMLoc &getLoc() const { return Loc; }
 
-  bool getPrefix() const { return TyAndPrefix.getInt(); }
+  /// Is this a field where nonconcrete values are okay?
+  bool isNonconcreteOK() const {
+return TyAndKind.getInt() == FK_NonconcreteOK;
+  }
+
+  /// Is this a template argument?
+  bool isTemplateArg() const {
+return TyAndKind.getInt() == FK_TemplateArg;
+  }
 
   /// Get the type of the field value as a RecTy.
-  RecTy *getType() const { return TyAndPrefix.getPointer(); }
+  RecTy *getType() const { return TyAndKind.getPointer(); }
 
   /// Get the type of the field for printing purposes.
   std::string getPrintType() const;

diff  --git a/llvm/lib/TableGen/JSONBackend.cpp 
b/llvm/lib/TableGen/JSONBackend.cpp
index 131650f987fb..8ddfd9f04524 100644
--- a/llvm/lib/TableGen/JSONBackend.cpp
+++ b/llvm/lib/TableGen/JSONBackend.cpp
@@ -144,7 +144,7 @@ void JSONEmitter::run(raw_ostream &OS) {
 for (const RecordVal &RV : Def.getValues()) {
   if (!Def.isTemplateArg(RV.getNameInit())) {
 auto Name = RV.getNameInitAsString();
-if (RV.getPrefix())
+if (RV.isNonconcreteOK())
   fields.push_back(Name);
 obj[Name] = translateInit(*RV.getValue());
   }

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 6b19454e95d9..d047b7bdf1cd 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2141,16 +2141,16 @@ std::string DagInit::getAsString() const {
 //Other implementations
 
//===--===//
 
-RecordVal::RecordVal(Init *N, RecTy *T, bool P)
-  : Name(N), TyAndPrefix(T, P) {
+RecordVal::RecordVal(Init *N, RecTy *T, FieldKind K)
+: Name(N), TyAndKind(T, K) {
   setValue(UnsetInit::get());
   assert(Value && "Cannot create unset value for current type!");
 }
 
 // This constructor accepts the same arguments as the above, but also
 // a source location.
-RecordVal::RecordVal(Init *N, SMLoc Loc, RecTy *T, bool P)
-: Name(N), Loc(Loc), TyAndPrefix(T, P) {
+RecordVal::RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K)
+: Name(N), Loc(Loc), TyAndKind(T, K) {
   setValue(UnsetInit::get());
   assert(Value && "Cannot create unset value for current type!");
 }
@@ -2170,7 +2170,7 @@ std::string RecordVal::getPrintType() const {
   return "string";
 }
   } else {
-return TyAndPrefix.getPointer()->getAsString();
+return TyAndKind.getPointer()->getAsString();
   }
 }
 
@@ -2227,7 +2227,7 @@ LLVM_DUMP_METHOD void RecordVal::dump() const { errs() << 
*this; }
 #endif
 
 void RecordVal::print(raw_ostream &OS, bool PrintSem) const {
-  if (getPrefix()) OS << "field ";
+  if (isNonconcreteOK()) OS << "field ";
   OS << getPrintType() << " " << getNameInitAsString();
 
   if (getValue())
@@ -2368,10 +2368,10 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const 
Record &R) {
   OS << "\n";
 
   for (const RecordVal &Val : R.getValues())
-if (Val.getPrefix() && !R.isTemplateArg(Val.getNameInit()))
+if (Val.isNonconcreteOK() && !R.isTemplateArg(Val

[llvm-branch-commits] [llvm] 6e2b635 - [TableGen] Add the assert statement, step 1

2021-01-08 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2021-01-08T09:47:51-05:00
New Revision: 6e2b6351d2cb1feaa88e6c92ba844ab48b4758f9

URL: 
https://github.com/llvm/llvm-project/commit/6e2b6351d2cb1feaa88e6c92ba844ab48b4758f9
DIFF: 
https://github.com/llvm/llvm-project/commit/6e2b6351d2cb1feaa88e6c92ba844ab48b4758f9.diff

LOG: [TableGen] Add the assert statement, step 1

Differential Revision: https://reviews.llvm.org/D93911

This first step adds the assert statement and supports it at top level
and in record definitions. Later steps will support it in class
definitions and multiclasses.

Added: 
llvm/test/TableGen/assert.td

Modified: 
llvm/docs/TableGen/ProgRef.rst
llvm/include/llvm/TableGen/Record.h
llvm/lib/TableGen/TGLexer.cpp
llvm/lib/TableGen/TGLexer.h
llvm/lib/TableGen/TGParser.cpp
llvm/lib/TableGen/TGParser.h

Removed: 




diff  --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst
index f2ee7a7e549a..f5a7760b2885 100644
--- a/llvm/docs/TableGen/ProgRef.rst
+++ b/llvm/docs/TableGen/ProgRef.rst
@@ -194,11 +194,11 @@ numeric literal rather than an identifier.
 TableGen has the following reserved keywords, which cannot be used as
 identifiers::
 
-   bitbits  class code  dag
-   defelse  false foreach   defm
-   defset defvarfield ifin
-   includeint   let   list  multiclass
-   string then  true
+   assert bit   bits  class code
+   dagdef   else  false foreach
+   defm   defsetdefvarfield if
+   in include   int   let   list
+   multiclass stringthen  true
 
 .. warning::
   The ``field`` reserved word is deprecated.
@@ -536,8 +536,8 @@ files.
 
 .. productionlist::
TableGenFile: `Statement`*
-   Statement: `Class` | `Def` | `Defm` | `Defset` | `Defvar` | `Foreach`
-:| `If` | `Let` | `MultiClass`
+   Statement: `Assert` | `Class` | `Def` | `Defm` | `Defset` | `Defvar`
+:| `Foreach` | `If` | `Let` | `MultiClass`
 
 The following sections describe each of these top-level statements. 
 
@@ -616,6 +616,7 @@ name of a multiclass.
BodyItem: (`Type` | "code") `TokIdentifier` ["=" `Value`] ";"
:| "let" `TokIdentifier` ["{" `RangeList` "}"] "=" `Value` ";"
:| "defvar" `TokIdentifier` "=" `Value` ";"
+   :| `Assert`
 
 A field definition in the body specifies a field to be included in the class
 or record. If no initial value is specified, then the field's value is
@@ -1247,6 +1248,34 @@ when the bodies are finished (see `Defvar in a Record 
Body`_ for more details).
 The ``if`` statement can also be used in a record :token:`Body`.
 
 
+``assert`` --- check that a condition is true
+-
+
+The ``assert`` statement checks a boolean condition to be sure that it is true
+and prints an error message if it is not.
+
+.. productionlist::
+   Assert: "assert" `condition` "," `message` ";"
+
+If the boolean condition is true, the statement does nothing. If the
+condition is false, it prints a nonfatal error message. The **message**, which
+can be an arbitrary string expression, is included in the error message as a
+note. The exact behavior of the ``assert`` statement depends on its
+placement.
+
+* At top level, the assertion is checked immediately.
+
+* In a record definition, the statement is saved and all assertions are
+  checked after the record is completely built.
+
+* In a class definition, the assertions are saved and inherited by all
+  the record definitions that inherit from the class. The assertions are
+  then checked when the records are completely built. [this placement is not
+  yet available]
+
+* In a multiclass definition, ... [this placement is not yet available]
+
+
 Additional Details
 ==
 

diff  --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index 8dea76fb64a2..2853a471b67f 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1445,6 +1445,8 @@ class Record {
   SmallVector Locs;
   SmallVector TemplateArgs;
   SmallVector Values;
+  // Vector of [source location, condition Init, message Init].
+  SmallVector, 0> Assertions;
 
   // All superclasses in the inheritance forest in post-order (yes, it
   // must be a forest; diamond-shaped inheritance is not allowed).
@@ -1519,6 +1521,10 @@ class Record {
 
   ArrayRef getValues() const { return Values; }
 
+  ArrayRef> getAssertions() const {
+return Assertions;
+  }
+
   ArrayRef>  getSuperClasses() const {
 return SuperClasses;
   }
@@ -1576,6 +1582,10 @@ class Record {
 removeValue(StringInit::get(Name));
   }
 
+  void addAssertion(SMLoc Loc, Init *Condition,

[llvm-branch-commits] [llvm] d4f2fef - [TableGen] Remove unused declaration that caused build failures.

2021-01-08 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2021-01-08T10:10:54-05:00
New Revision: d4f2fef7464eb2b8c2126c5b733eeb76ed9820f6

URL: 
https://github.com/llvm/llvm-project/commit/d4f2fef7464eb2b8c2126c5b733eeb76ed9820f6
DIFF: 
https://github.com/llvm/llvm-project/commit/d4f2fef7464eb2b8c2126c5b733eeb76ed9820f6.diff

LOG: [TableGen] Remove unused declaration that caused build failures.

Added: 


Modified: 
llvm/lib/TableGen/TGParser.cpp

Removed: 




diff  --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 9f3c69bab89e0..b0eecd5abdf5d 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -3184,7 +3184,6 @@ bool TGParser::ParseIfBody(MultiClass *CurMultiClass, 
StringRef Kind) {
 ///
 ///   Assert ::= ASSERT condition , message ;
 bool TGParser::ParseAssert(MultiClass *CurMultiClass, Record *CurRec) {
-  SMLoc Loc = Lex.getLoc();
   assert(Lex.getCode() == tgtok::Assert && "Unknown tok");
   Lex.Lex(); // Eat the 'assert' token.
 



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] fe50b73 - [TableGen] Fix use of *CurRec when CurRec is null.

2021-01-08 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2021-01-08T13:21:57-05:00
New Revision: fe50b7363a1fbf974107d75a7d0a4be8b9481b56

URL: 
https://github.com/llvm/llvm-project/commit/fe50b7363a1fbf974107d75a7d0a4be8b9481b56
DIFF: 
https://github.com/llvm/llvm-project/commit/fe50b7363a1fbf974107d75a7d0a4be8b9481b56.diff

LOG: [TableGen] Fix use of *CurRec when CurRec is null.

I cannot build with the undefined sanitizer on Visual Studio.

Added: 


Modified: 
llvm/lib/TableGen/TGParser.cpp

Removed: 




diff  --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index b0eecd5abdf5..7918e2ac98f6 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -3209,10 +3209,7 @@ bool TGParser::ParseAssert(MultiClass *CurMultiClass, 
Record *CurRec) {
   } else if (CurRec) {
 CurRec->addAssertion(ConditionLoc, Condition, Message);
   } else { // at top level
-RecordResolver R(*CurRec);
-Init *Value = Condition->resolveReferences(R);
-Init *Text = Message->resolveReferences(R);
-CheckAssert(ConditionLoc, Value, Text);
+CheckAssert(ConditionLoc, Condition, Message);
   }
  
   return false;



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] a675947 - [TableGen] Improve error message for semicolon after braced body.

2021-01-12 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2021-01-12T09:38:05-05:00
New Revision: a6759477129c98820a56231d2f3fd27e5fe31ab3

URL: 
https://github.com/llvm/llvm-project/commit/a6759477129c98820a56231d2f3fd27e5fe31ab3
DIFF: 
https://github.com/llvm/llvm-project/commit/a6759477129c98820a56231d2f3fd27e5fe31ab3.diff

LOG: [TableGen] Improve error message for semicolon after braced body.

Add a test for this message.

Differential Revision: https://reviews.llvm.org/D94412

Added: 
llvm/test/TableGen/spurious-semi.td

Modified: 
llvm/lib/TableGen/TGParser.cpp

Removed: 




diff  --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 7918e2ac98f6..24949f0b2b4d 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -2836,7 +2836,7 @@ bool TGParser::ParseBody(Record *CurRec) {
 return false;
 
   if (!consume(tgtok::l_brace))
-return TokError("Expected ';' or '{' to start body");
+return TokError("Expected '{' to start body or ';' for declaration only");
 
   // An object body introduces a new scope for local variables.
   TGLocalVarScope *BodyScope = PushLocalScope();
@@ -2849,6 +2849,14 @@ bool TGParser::ParseBody(Record *CurRec) {
 
   // Eat the '}'.
   Lex.Lex();
+
+  // If we have a semicolon, print a gentle error.
+  SMLoc SemiLoc = Lex.getLoc();
+  if (consume(tgtok::semi)) {
+PrintError(SemiLoc, "A class or def body should not end with a semicolon");
+PrintNote("Semicolon ignored; remove to eliminate this error");
+  }
+
   return false;
 }
 
@@ -3432,6 +3440,13 @@ bool TGParser::ParseMultiClass() {
 }
 Lex.Lex();  // eat the '}'.
 
+// If we have a semicolon, print a gentle error.
+SMLoc SemiLoc = Lex.getLoc();
+if (consume(tgtok::semi)) {
+  PrintError(SemiLoc, "A multiclass body should not end with a semicolon");
+  PrintNote("Semicolon ignored; remove to eliminate this error");
+}
+
 PopLocalScope(MulticlassScope);
   }
 
@@ -3623,7 +3638,7 @@ bool TGParser::ParseFile() {
   if (Lex.getCode() == tgtok::Eof)
 return false;
 
-  return TokError("Unexpected input at top level");
+  return TokError("Unexpected token at top level");
 }
 
 // Check an assertion: Obtain the condition value and be sure it is true.

diff  --git a/llvm/test/TableGen/spurious-semi.td 
b/llvm/test/TableGen/spurious-semi.td
new file mode 100644
index ..9e3b7ada02de
--- /dev/null
+++ b/llvm/test/TableGen/spurious-semi.td
@@ -0,0 +1,39 @@
+// RUN: llvm-tblgen %s | FileCheck %s
+// RUN: not llvm-tblgen -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s
+
+// This file tests the error message that is printed when a body is
+// terminated with a semicolon in addition to the close brace.
+
+// CHECK: class Class0
+// CHECK: def Rec0
+
+class Class0 {
+}
+
+def Rec0 {
+}
+
+multiclass MC0 {
+  def R;
+}
+
+#ifdef ERROR1
+
+// ERROR1: error: A class or def body should not end with a semicolon
+// ERROR1: Semicolon ignored
+// ERROR1: error: A class or def body should not end with a semicolon
+// ERROR1: Semicolon ignored
+// ERROR1: error: A multiclass body should not end with a semicolon
+// ERROR1: Semicolon ignored
+
+class Class1 {
+};
+
+def Rec1 {
+};
+
+multiclass MC1 {
+  def R;
+};
+
+#endif



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] d61ccda - [TableGen] Slim down the data structures in xxxGenInstrInfo.inc, step 1

2020-12-16 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2020-12-16T09:57:43-05:00
New Revision: d61ccda76965ebb9f4aa24e87899a8b0e65b2d54

URL: 
https://github.com/llvm/llvm-project/commit/d61ccda76965ebb9f4aa24e87899a8b0e65b2d54
DIFF: 
https://github.com/llvm/llvm-project/commit/d61ccda76965ebb9f4aa24e87899a8b0e65b2d54.diff

LOG: [TableGen] Slim down the data structures in xxxGenInstrInfo.inc, step 1

Added: 


Modified: 
llvm/utils/TableGen/InstrInfoEmitter.cpp

Removed: 




diff  --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp 
b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index 025c5354514c..156fa6d18d2e 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -371,7 +371,7 @@ void InstrInfoEmitter::emitOperandTypeMappings(
   OS << "namespace " << Namespace << " {\n";
   OS << "LLVM_READONLY\n";
   OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n";
-  // TODO: Factor out instructions with same operands to compress the tables.
+  // TODO: Factor out duplicate operand lists to compress the tables.
   if (!NumberedInstructions.empty()) {
 std::vector OperandOffsets;
 std::vector OperandRecords;
@@ -393,16 +393,26 @@ void InstrInfoEmitter::emitOperandTypeMappings(
   }
 }
 
-// Emit the table of offsets for the opcode lookup.
-OS << "  const int Offsets[] = {\n";
+// Emit the table of offsets (indexes) into the operand type table.
+// Size the unsigned integer offset to save space.
+assert(OperandRecords.size() <= UINT32_MAX &&
+   "Too many operands for offset table");
+OS << ((OperandRecords.size() <= UINT16_MAX) ? "  const uint16_t"
+ : "  const uint32_t");
+OS << " Offsets[] = {\n";
 for (int I = 0, E = OperandOffsets.size(); I != E; ++I)
   OS << "" << OperandOffsets[I] << ",\n";
 OS << "  };\n";
 
 // Add an entry for the end so that we don't need to special case it below.
 OperandOffsets.push_back(OperandRecords.size());
+
 // Emit the actual operand types in a flat table.
-OS << "  const int OpcodeOperandTypes[] = {\n";
+// Size the signed integer operand type to save space.
+assert(EnumVal <= INT16_MAX &&
+   "Too many operand types for operand types table");
+OS << ((EnumVal <= INT8_MAX) ? "  const int8_t" : "  const int16_t");
+OS << " OpcodeOperandTypes[] = {\n";
 for (int I = 0, E = OperandRecords.size(), CurOffset = 1; I != E; ++I) {
   // We print each Opcode's operands in its own row.
   if (I == OperandOffsets[CurOffset]) {



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] 3a675c7 - [TableGen] Add the !substr() bang operator

2020-12-21 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2020-12-21T09:41:59-05:00
New Revision: 3a675c777dd5788e2313cb06fb27b01f8a2e7573

URL: 
https://github.com/llvm/llvm-project/commit/3a675c777dd5788e2313cb06fb27b01f8a2e7573
DIFF: 
https://github.com/llvm/llvm-project/commit/3a675c777dd5788e2313cb06fb27b01f8a2e7573.diff

LOG: [TableGen] Add the !substr() bang operator

Update the documentation and add a test.

Differential Revision: https://reviews.llvm.org/D93419

Added: 
llvm/test/TableGen/substr.td

Modified: 
llvm/docs/TableGen/ProgRef.rst
llvm/include/llvm/TableGen/Record.h
llvm/lib/TableGen/Record.cpp
llvm/lib/TableGen/TGLexer.cpp
llvm/lib/TableGen/TGLexer.h
llvm/lib/TableGen/TGParser.cpp
llvm/lib/TableGen/TGParser.h

Removed: 




diff  --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst
index 342b91a0c437..f2ee7a7e549a 100644
--- a/llvm/docs/TableGen/ProgRef.rst
+++ b/llvm/docs/TableGen/ProgRef.rst
@@ -216,7 +216,8 @@ TableGen provides "bang operators" that have a wide variety 
of uses:
: !interleave !isa !le  !listconcat  !listsplat
: !lt !mul !ne  !not !or
: !setdagop   !shl !size!sra !srl
-   : !strconcat  !sub !subst   !tail!xor
+   : !strconcat  !sub !subst   !substr  !tail
+   : !xor
 
 The ``!cond`` operator has a slightly 
diff erent
 syntax compared to other bang operators, so it is defined separately:
@@ -1723,6 +1724,13 @@ and non-0 as true.
 record if the *target* record name equals the *value* record name; 
otherwise it
 produces the *value*.
 
+``!substr(``\ *string*\ ``,`` *start*\ [``,`` *length*]\ ``)``
+This operator extracts a substring of the given *string*. The starting
+position of the substring is specified by *start*, which can range
+between 0 and the length of the string. The length of the substring
+is specified by *length*; if not specified, the rest of the string is
+extracted. The *start* and *length* arguments must be integers.
+
 ``!tail(``\ *a*\ ``)``
 This operator produces a new list with all the elements
 of the list *a* except for the zeroth one. (See also ``!head``.)

diff  --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index 3010b4dad09a..a0c5b2778547 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -829,7 +829,7 @@ class BinOpInit : public OpInit, public FoldingSetNode {
 /// !op (X, Y, Z) - Combine two inits.
 class TernOpInit : public OpInit, public FoldingSetNode {
 public:
-  enum TernaryOp : uint8_t { SUBST, FOREACH, FILTER, IF, DAG };
+  enum TernaryOp : uint8_t { SUBST, FOREACH, FILTER, IF, DAG, SUBSTR };
 
 private:
   Init *LHS, *MHS, *RHS;

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index cbdce04494f3..9c0464d4e1bf 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -1325,6 +1325,27 @@ Init *TernOpInit::Fold(Record *CurRec) const {
 }
 break;
   }
+
+  case SUBSTR: {
+StringInit *LHSs = dyn_cast(LHS);
+IntInit *MHSi = dyn_cast(MHS);
+IntInit *RHSi = dyn_cast(RHS);
+if (LHSs && MHSi && RHSi) {
+  int64_t StringSize = LHSs->getValue().size();
+  int64_t Start = MHSi->getValue();
+  int64_t Length = RHSi->getValue();
+  if (Start < 0 || Start > StringSize)
+PrintError(CurRec->getLoc(),
+   Twine("!substr start position is out of range 0...") +
+   std::to_string(StringSize) + ": " +
+   std::to_string(Start));
+  if (Length < 0)
+PrintError(CurRec->getLoc(), "!substr length must be nonnegative");
+  return StringInit::get(LHSs->getValue().substr(Start, Length),
+ LHSs->getFormat());
+}
+break;
+  }
   }
 
   return const_cast(this);
@@ -1364,11 +1385,12 @@ std::string TernOpInit::getAsString() const {
   std::string Result;
   bool UnquotedLHS = false;
   switch (getOpcode()) {
-  case SUBST: Result = "!subst"; break;
-  case FOREACH: Result = "!foreach"; UnquotedLHS = true; break;
+  case DAG: Result = "!dag"; break;
   case FILTER: Result = "!filter"; UnquotedLHS = true; break;
+  case FOREACH: Result = "!foreach"; UnquotedLHS = true; break;
   case IF: Result = "!if"; break;
-  case DAG: Result = "!dag"; break;
+  case SUBST: Result = "!subst"; break;
+  case SUBSTR: Result = "!substr"; break;
   }
   return (Result + "(" +
   (UnquotedLHS ? LHS->getAsUnquotedString() : LHS->getAsString()) +

diff  --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp
index df0df96f40eb..a45ef6dc10c1 100644
--- a/llvm/lib/TableGen/TGLexer.cpp
+++ b/llvm/lib/TableGen/TGLexer.cpp
@@ -589,6 +589,7 @@ tgtok::Tok

[llvm-branch-commits] [llvm] 554eb1f - Revert "[TableGen] Add the !substr() bang operator"

2020-12-21 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2020-12-21T10:46:25-05:00
New Revision: 554eb1f6dc49e616b70254a7976699b3eff84366

URL: 
https://github.com/llvm/llvm-project/commit/554eb1f6dc49e616b70254a7976699b3eff84366
DIFF: 
https://github.com/llvm/llvm-project/commit/554eb1f6dc49e616b70254a7976699b3eff84366.diff

LOG: Revert "[TableGen] Add the !substr() bang operator"

This reverts commit 3a675c777dd5788e2313cb06fb27b01f8a2e7573.

Added: 


Modified: 
llvm/docs/TableGen/ProgRef.rst
llvm/include/llvm/TableGen/Record.h
llvm/lib/TableGen/Record.cpp
llvm/lib/TableGen/TGLexer.cpp
llvm/lib/TableGen/TGLexer.h
llvm/lib/TableGen/TGParser.cpp
llvm/lib/TableGen/TGParser.h

Removed: 
llvm/test/TableGen/substr.td



diff  --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst
index f2ee7a7e549a..342b91a0c437 100644
--- a/llvm/docs/TableGen/ProgRef.rst
+++ b/llvm/docs/TableGen/ProgRef.rst
@@ -216,8 +216,7 @@ TableGen provides "bang operators" that have a wide variety 
of uses:
: !interleave !isa !le  !listconcat  !listsplat
: !lt !mul !ne  !not !or
: !setdagop   !shl !size!sra !srl
-   : !strconcat  !sub !subst   !substr  !tail
-   : !xor
+   : !strconcat  !sub !subst   !tail!xor
 
 The ``!cond`` operator has a slightly 
diff erent
 syntax compared to other bang operators, so it is defined separately:
@@ -1724,13 +1723,6 @@ and non-0 as true.
 record if the *target* record name equals the *value* record name; 
otherwise it
 produces the *value*.
 
-``!substr(``\ *string*\ ``,`` *start*\ [``,`` *length*]\ ``)``
-This operator extracts a substring of the given *string*. The starting
-position of the substring is specified by *start*, which can range
-between 0 and the length of the string. The length of the substring
-is specified by *length*; if not specified, the rest of the string is
-extracted. The *start* and *length* arguments must be integers.
-
 ``!tail(``\ *a*\ ``)``
 This operator produces a new list with all the elements
 of the list *a* except for the zeroth one. (See also ``!head``.)

diff  --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index a0c5b2778547..3010b4dad09a 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -829,7 +829,7 @@ class BinOpInit : public OpInit, public FoldingSetNode {
 /// !op (X, Y, Z) - Combine two inits.
 class TernOpInit : public OpInit, public FoldingSetNode {
 public:
-  enum TernaryOp : uint8_t { SUBST, FOREACH, FILTER, IF, DAG, SUBSTR };
+  enum TernaryOp : uint8_t { SUBST, FOREACH, FILTER, IF, DAG };
 
 private:
   Init *LHS, *MHS, *RHS;

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 9c0464d4e1bf..cbdce04494f3 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -1325,27 +1325,6 @@ Init *TernOpInit::Fold(Record *CurRec) const {
 }
 break;
   }
-
-  case SUBSTR: {
-StringInit *LHSs = dyn_cast(LHS);
-IntInit *MHSi = dyn_cast(MHS);
-IntInit *RHSi = dyn_cast(RHS);
-if (LHSs && MHSi && RHSi) {
-  int64_t StringSize = LHSs->getValue().size();
-  int64_t Start = MHSi->getValue();
-  int64_t Length = RHSi->getValue();
-  if (Start < 0 || Start > StringSize)
-PrintError(CurRec->getLoc(),
-   Twine("!substr start position is out of range 0...") +
-   std::to_string(StringSize) + ": " +
-   std::to_string(Start));
-  if (Length < 0)
-PrintError(CurRec->getLoc(), "!substr length must be nonnegative");
-  return StringInit::get(LHSs->getValue().substr(Start, Length),
- LHSs->getFormat());
-}
-break;
-  }
   }
 
   return const_cast(this);
@@ -1385,12 +1364,11 @@ std::string TernOpInit::getAsString() const {
   std::string Result;
   bool UnquotedLHS = false;
   switch (getOpcode()) {
-  case DAG: Result = "!dag"; break;
-  case FILTER: Result = "!filter"; UnquotedLHS = true; break;
+  case SUBST: Result = "!subst"; break;
   case FOREACH: Result = "!foreach"; UnquotedLHS = true; break;
+  case FILTER: Result = "!filter"; UnquotedLHS = true; break;
   case IF: Result = "!if"; break;
-  case SUBST: Result = "!subst"; break;
-  case SUBSTR: Result = "!substr"; break;
+  case DAG: Result = "!dag"; break;
   }
   return (Result + "(" +
   (UnquotedLHS ? LHS->getAsUnquotedString() : LHS->getAsString()) +

diff  --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp
index a45ef6dc10c1..df0df96f40eb 100644
--- a/llvm/lib/TableGen/TGLexer.cpp
+++ b/llvm/lib/TableGen/TGLexer.cpp
@@ -589,7 +589,6 @@ tgtok::TokKind TGLexer::LexExclaim() {

[llvm-branch-commits] [llvm] 5b37f0d - [MCInstrDesc] [TableGen] Reduce size of MCOperandInfo instances.

2020-12-22 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2020-12-22T09:44:30-05:00
New Revision: 5b37f0d97087c39ef635b3f7574ace9aa173d417

URL: 
https://github.com/llvm/llvm-project/commit/5b37f0d97087c39ef635b3f7574ace9aa173d417
DIFF: 
https://github.com/llvm/llvm-project/commit/5b37f0d97087c39ef635b3f7574ace9aa173d417.diff

LOG: [MCInstrDesc] [TableGen] Reduce size of MCOperandInfo instances.

Differential Revision: https://reviews.llvm.org/D93326

Added: 


Modified: 
llvm/include/llvm/MC/MCInstrDesc.h
llvm/utils/TableGen/InstrInfoEmitter.cpp

Removed: 




diff  --git a/llvm/include/llvm/MC/MCInstrDesc.h 
b/llvm/include/llvm/MC/MCInstrDesc.h
index 17454e3134a2..cbb061fc6456 100644
--- a/llvm/include/llvm/MC/MCInstrDesc.h
+++ b/llvm/include/llvm/MC/MCInstrDesc.h
@@ -27,12 +27,22 @@ class MCInst;
 
//===--===//
 
 namespace MCOI {
-// Operand constraints
+/// Operand constraints. These are encoded in 16 bits with one of the
+/// low-order 3 bits specifying that a constraint is present and the
+/// corresponding high-order hex digit specifying the constraint value.
+/// This allows for a maximum of 3 constraints.
 enum OperandConstraint {
-  TIED_TO = 0,  // Must be allocated the same register as.
-  EARLY_CLOBBER // Operand is an early clobber register operand
+  TIED_TO = 0,  // Must be allocated the same register as specified value.
+  EARLY_CLOBBER // If present, operand is an early clobber register.
 };
 
+// Define a macro to produce each constraint value.
+#define MCOI_TIED_TO(op) \
+  ((1 << MCOI::TIED_TO) | ((op) << (4 + MCOI::TIED_TO * 4)))
+
+#define MCOI_EARLY_CLOBBER \
+  (1 << MCOI::EARLY_CLOBBER)
+
 /// These are flags set on operands, but should be considered
 /// private, all access should go through the MCOperandInfo accessors.
 /// See the accessors for a description of what these are.
@@ -84,10 +94,9 @@ class MCOperandInfo {
 
   /// Information about the type of the operand.
   uint8_t OperandType;
-  /// The lower 16 bits are used to specify which constraints are set.
-  /// The higher 16 bits are used to specify the value of constraints (4 bits
-  /// each).
-  uint32_t Constraints;
+
+  /// Operand constraints (see OperandConstraint enum).
+  uint16_t Constraints;
 
   /// Set if this operand is a pointer value and it requires a callback
   /// to look up its register class.
@@ -197,14 +206,14 @@ class MCInstrDesc {
   const MCPhysReg *ImplicitDefs; // Registers implicitly defined by this instr
   const MCOperandInfo *OpInfo;   // 'NumOperands' entries about operands
 
-  /// Returns the value of the specific constraint if
-  /// it is set. Returns -1 if it is not set.
+  /// Returns the value of the specified operand constraint if
+  /// it is present. Returns -1 if it is not present.
   int getOperandConstraint(unsigned OpNum,
MCOI::OperandConstraint Constraint) const {
 if (OpNum < NumOperands &&
 (OpInfo[OpNum].Constraints & (1 << Constraint))) {
-  unsigned Pos = 16 + Constraint * 4;
-  return (int)(OpInfo[OpNum].Constraints >> Pos) & 0xf;
+  unsigned ValuePos = 4 + Constraint * 4;
+  return (int)(OpInfo[OpNum].Constraints >> ValuePos) & 0x0f;
 }
 return -1;
   }

diff  --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp 
b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index 156fa6d18d2e..71d8eadaa61e 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -182,11 +182,10 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction 
&Inst) {
   if (Constraint.isNone())
 Res += "0";
   else if (Constraint.isEarlyClobber())
-Res += "(1 << MCOI::EARLY_CLOBBER)";
+Res += "MCOI_EARLY_CLOBBER";
   else {
 assert(Constraint.isTied());
-Res += "((" + utostr(Constraint.getTiedOperand()) +
-" << 16) | (1 << MCOI::TIED_TO))";
+Res += "MCOI_TIED_TO(" + utostr(Constraint.getTiedOperand()) + ")";
   }
 
   Result.push_back(Res);



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] e122a71 - [TableGen] Add the !substr() bang operator

2020-12-23 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2020-12-23T10:59:33-05:00
New Revision: e122a71a0a284e669c970e80214c6b3082aa2534

URL: 
https://github.com/llvm/llvm-project/commit/e122a71a0a284e669c970e80214c6b3082aa2534
DIFF: 
https://github.com/llvm/llvm-project/commit/e122a71a0a284e669c970e80214c6b3082aa2534.diff

LOG: [TableGen] Add the !substr() bang operator

Update the documentation and add a test.

Build failed: Change SIZE_MAX to std::numeric_limits::max().

Differential Revision: https://reviews.llvm.org/D93419

Added: 
llvm/test/TableGen/substr.td

Modified: 
llvm/docs/TableGen/ProgRef.rst
llvm/include/llvm/TableGen/Record.h
llvm/lib/TableGen/Record.cpp
llvm/lib/TableGen/TGLexer.cpp
llvm/lib/TableGen/TGLexer.h
llvm/lib/TableGen/TGParser.cpp
llvm/lib/TableGen/TGParser.h

Removed: 




diff  --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst
index 342b91a0c437..f2ee7a7e549a 100644
--- a/llvm/docs/TableGen/ProgRef.rst
+++ b/llvm/docs/TableGen/ProgRef.rst
@@ -216,7 +216,8 @@ TableGen provides "bang operators" that have a wide variety 
of uses:
: !interleave !isa !le  !listconcat  !listsplat
: !lt !mul !ne  !not !or
: !setdagop   !shl !size!sra !srl
-   : !strconcat  !sub !subst   !tail!xor
+   : !strconcat  !sub !subst   !substr  !tail
+   : !xor
 
 The ``!cond`` operator has a slightly 
diff erent
 syntax compared to other bang operators, so it is defined separately:
@@ -1723,6 +1724,13 @@ and non-0 as true.
 record if the *target* record name equals the *value* record name; 
otherwise it
 produces the *value*.
 
+``!substr(``\ *string*\ ``,`` *start*\ [``,`` *length*]\ ``)``
+This operator extracts a substring of the given *string*. The starting
+position of the substring is specified by *start*, which can range
+between 0 and the length of the string. The length of the substring
+is specified by *length*; if not specified, the rest of the string is
+extracted. The *start* and *length* arguments must be integers.
+
 ``!tail(``\ *a*\ ``)``
 This operator produces a new list with all the elements
 of the list *a* except for the zeroth one. (See also ``!head``.)

diff  --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index 3010b4dad09a..a0c5b2778547 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -829,7 +829,7 @@ class BinOpInit : public OpInit, public FoldingSetNode {
 /// !op (X, Y, Z) - Combine two inits.
 class TernOpInit : public OpInit, public FoldingSetNode {
 public:
-  enum TernaryOp : uint8_t { SUBST, FOREACH, FILTER, IF, DAG };
+  enum TernaryOp : uint8_t { SUBST, FOREACH, FILTER, IF, DAG, SUBSTR };
 
 private:
   Init *LHS, *MHS, *RHS;

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index cbdce04494f3..9c0464d4e1bf 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -1325,6 +1325,27 @@ Init *TernOpInit::Fold(Record *CurRec) const {
 }
 break;
   }
+
+  case SUBSTR: {
+StringInit *LHSs = dyn_cast(LHS);
+IntInit *MHSi = dyn_cast(MHS);
+IntInit *RHSi = dyn_cast(RHS);
+if (LHSs && MHSi && RHSi) {
+  int64_t StringSize = LHSs->getValue().size();
+  int64_t Start = MHSi->getValue();
+  int64_t Length = RHSi->getValue();
+  if (Start < 0 || Start > StringSize)
+PrintError(CurRec->getLoc(),
+   Twine("!substr start position is out of range 0...") +
+   std::to_string(StringSize) + ": " +
+   std::to_string(Start));
+  if (Length < 0)
+PrintError(CurRec->getLoc(), "!substr length must be nonnegative");
+  return StringInit::get(LHSs->getValue().substr(Start, Length),
+ LHSs->getFormat());
+}
+break;
+  }
   }
 
   return const_cast(this);
@@ -1364,11 +1385,12 @@ std::string TernOpInit::getAsString() const {
   std::string Result;
   bool UnquotedLHS = false;
   switch (getOpcode()) {
-  case SUBST: Result = "!subst"; break;
-  case FOREACH: Result = "!foreach"; UnquotedLHS = true; break;
+  case DAG: Result = "!dag"; break;
   case FILTER: Result = "!filter"; UnquotedLHS = true; break;
+  case FOREACH: Result = "!foreach"; UnquotedLHS = true; break;
   case IF: Result = "!if"; break;
-  case DAG: Result = "!dag"; break;
+  case SUBST: Result = "!subst"; break;
+  case SUBSTR: Result = "!substr"; break;
   }
   return (Result + "(" +
   (UnquotedLHS ? LHS->getAsUnquotedString() : LHS->getAsString()) +

diff  --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp
index df0df96f40eb..a45ef6dc10c1 100644
--- a/llvm/lib/TableGen/TGLexer.cpp
+++ 

[llvm-branch-commits] [llvm] 4820af9 - [TableGen] Fix bug in !interleave operator

2020-12-28 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2020-12-28T12:17:24-05:00
New Revision: 4820af99ddc3271198ee4fdd867dc65b11f5

URL: 
https://github.com/llvm/llvm-project/commit/4820af99ddc3271198ee4fdd867dc65b11f5
DIFF: 
https://github.com/llvm/llvm-project/commit/4820af99ddc3271198ee4fdd867dc65b11f5.diff

LOG: [TableGen] Fix bug in !interleave operator

I forgot to account for unresolved elements of the list.

Differential Revision: https://reviews.llvm.org/D93814

Added: 


Modified: 
llvm/lib/TableGen/Record.cpp
llvm/test/TableGen/interleave.td

Removed: 




diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 9c0464d4e1bf..3e6daeb4d238 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -856,14 +856,19 @@ static StringInit *interleaveStringList(const ListInit 
*List,
 const StringInit *Delim) {
   if (List->size() == 0)
 return StringInit::get("");
-  SmallString<80> Result(cast(List->getElement(0))->getValue());
+  StringInit *Element = dyn_cast(List->getElement(0));
+  if (!Element)
+return nullptr;
+  SmallString<80> Result(Element->getValue());
   StringInit::StringFormat Fmt = StringInit::SF_String;
 
   for (unsigned I = 1, E = List->size(); I < E; ++I) {
 Result.append(Delim->getValue());
-auto *StrInit = cast(List->getElement(I));
-Result.append(StrInit->getValue());
-Fmt = StringInit::determineFormat(Fmt, StrInit->getFormat());
+StringInit *Element = dyn_cast(List->getElement(I));
+if (!Element)
+  return nullptr;
+Result.append(Element->getValue());
+Fmt = StringInit::determineFormat(Fmt, Element->getFormat());
   }
   return StringInit::get(Result, Fmt);
 }
@@ -872,14 +877,21 @@ static StringInit *interleaveIntList(const ListInit *List,
  const StringInit *Delim) {
   if (List->size() == 0)
 return StringInit::get("");
-  SmallString<80> Result(
-  cast(List->getElement(0)->getCastTo(IntRecTy::get()))
-  ->getAsString());
+  IntInit *Element =
+  dyn_cast_or_null(List->getElement(0)
+->convertInitializerTo(IntRecTy::get()));
+  if (!Element)
+return nullptr;
+  SmallString<80> Result(Element->getAsString());
 
   for (unsigned I = 1, E = List->size(); I < E; ++I) {
 Result.append(Delim->getValue());
-
Result.append(cast(List->getElement(I)->getCastTo(IntRecTy::get()))
-  ->getAsString());
+IntInit *Element =
+dyn_cast_or_null(List->getElement(I)
+  ->convertInitializerTo(IntRecTy::get()));
+if (!Element)
+  return nullptr;
+Result.append(Element->getAsString());
   }
   return StringInit::get(Result);
 }
@@ -975,10 +987,13 @@ Init *BinOpInit::Fold(Record *CurRec) const {
 ListInit *List = dyn_cast(LHS);
 StringInit *Delim = dyn_cast(RHS);
 if (List && Delim) {
+  StringInit *Result;
   if (isa(List->getElementType()))
-return interleaveStringList(List, Delim);
+Result = interleaveStringList(List, Delim);
   else
-return interleaveIntList(List, Delim);
+Result = interleaveIntList(List, Delim);
+  if (Result)
+return Result;
 }
 break;
   }

diff  --git a/llvm/test/TableGen/interleave.td 
b/llvm/test/TableGen/interleave.td
index 098542ab29a1..c4d5c825d0fc 100644
--- a/llvm/test/TableGen/interleave.td
+++ b/llvm/test/TableGen/interleave.td
@@ -77,6 +77,15 @@ def Rec6 {
   code OperatorList = !interleave(!listconcat(Operators, [[{;}]]), ", ");
 }
 
+// CHECK: def Rec7
+// CHECK:   str = "foo/bar/zoo";
+
+def Rec7 {
+  string foo = "foo";
+  string zoo = "oops, not zoo";
+  string str = !interleave([foo, "bar", zoo], "/");
+  let zoo = "zoo";
+}
 
 #ifdef ERROR1
 def op;



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] 9b7b8de - [TableGen] [ISel Matcher Emitter] Rework with two passes: one to size, one to emit

2020-11-21 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2020-11-21T10:59:13-05:00
New Revision: 9b7b8de6d12ff2e0bb7aa813f83a8053d302bc2b

URL: 
https://github.com/llvm/llvm-project/commit/9b7b8de6d12ff2e0bb7aa813f83a8053d302bc2b
DIFF: 
https://github.com/llvm/llvm-project/commit/9b7b8de6d12ff2e0bb7aa813f83a8053d302bc2b.diff

LOG: [TableGen] [ISel Matcher Emitter] Rework with two passes: one to size, one 
to emit

Differential Revision: https://reviews.llvm.org/D91632

Added: 


Modified: 
llvm/utils/TableGen/DAGISelMatcher.h
llvm/utils/TableGen/DAGISelMatcherEmitter.cpp

Removed: 




diff  --git a/llvm/utils/TableGen/DAGISelMatcher.h 
b/llvm/utils/TableGen/DAGISelMatcher.h
index 223513fc8d38..dca1865b22e0 100644
--- a/llvm/utils/TableGen/DAGISelMatcher.h
+++ b/llvm/utils/TableGen/DAGISelMatcher.h
@@ -31,7 +31,7 @@ Matcher *ConvertPatternToMatcher(const PatternToMatch 
&Pattern,unsigned Variant,
  const CodeGenDAGPatterns &CGP);
 void OptimizeMatcher(std::unique_ptr &Matcher,
  const CodeGenDAGPatterns &CGP);
-void EmitMatcherTable(const Matcher *Matcher, const CodeGenDAGPatterns &CGP,
+void EmitMatcherTable(Matcher *Matcher, const CodeGenDAGPatterns &CGP,
   raw_ostream &OS);
 
 
@@ -41,6 +41,7 @@ class Matcher {
   // The next matcher node that is executed after this one.  Null if this is 
the
   // last stage of a match.
   std::unique_ptr Next;
+  size_t Size; // Size in bytes of matcher and all its children (if any).
   virtual void anchor();
 public:
   enum KindTy {
@@ -85,7 +86,10 @@ class Matcher {
 EmitNode, // Create a DAG node
 EmitNodeXForm,// Run a SDNodeXForm
 CompleteMatch,// Finish a match and update the results.
-MorphNodeTo   // Build a node, finish a match and update results.
+MorphNodeTo,  // Build a node, finish a match and update results.
+
+// Highest enum value; watch out when adding more.
+HighestKind = MorphNodeTo
   };
   const KindTy Kind;
 
@@ -94,6 +98,8 @@ class Matcher {
 public:
   virtual ~Matcher() {}
 
+  unsigned getSize() const { return Size; }
+  void setSize(unsigned sz) { Size = sz; }
   KindTy getKind() const { return Kind; }
 
   Matcher *getNext() { return Next.get(); }

diff  --git a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp 
b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
index cf92391f30c4..03528a46aea7 100644
--- a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -23,6 +23,7 @@
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/TableGen/Error.h"
 #include "llvm/TableGen/Record.h"
+
 using namespace llvm;
 
 enum {
@@ -47,6 +48,8 @@ namespace {
 class MatcherTableEmitter {
   const CodeGenDAGPatterns &CGP;
 
+  SmallVector OpcodeCounts;
+
   DenseMap NodePredicateMap;
   std::vector NodePredicates;
   std::vector NodePredicatesWithOperands;
@@ -79,12 +82,15 @@ class MatcherTableEmitter {
   }
 
 public:
-  MatcherTableEmitter(const CodeGenDAGPatterns &cgp)
-: CGP(cgp) {}
+  MatcherTableEmitter(const CodeGenDAGPatterns &cgp) : CGP(cgp) {
+OpcodeCounts.assign(Matcher::HighestKind+1, 0);
+  }
 
-  unsigned EmitMatcherList(const Matcher *N, unsigned Indent,
+  unsigned EmitMatcherList(const Matcher *N, const unsigned Indent,
unsigned StartIdx, raw_ostream &OS);
 
+  unsigned SizeMatcherList(Matcher *N, raw_ostream &OS);
+
   void EmitPredicateFunctions(raw_ostream &OS);
 
   void EmitHistogram(const Matcher *N, raw_ostream &OS);
@@ -95,7 +101,9 @@ class MatcherTableEmitter {
   void EmitNodePredicatesFunction(const std::vector &Preds,
   StringRef Decl, raw_ostream &OS);
 
-  unsigned EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
+  unsigned SizeMatcher(Matcher *N, raw_ostream &OS);
+
+  unsigned EmitMatcher(const Matcher *N, const unsigned Indent, unsigned 
CurrentIdx,
raw_ostream &OS);
 
   unsigned getNodePredicate(TreePredicateFn Pred) {
@@ -165,7 +173,7 @@ static std::string GetPatFromTreePatternNode(const 
TreePatternNode *N) {
   return str;
 }
 
-static unsigned GetVBRSize(unsigned Val) {
+static size_t GetVBRSize(unsigned Val) {
   if (Val <= 127) return 1;
 
   unsigned NumBytes = 0;
@@ -219,6 +227,78 @@ static std::string getIncludePath(const Record *R) {
   return str;
 }
 
+/// This function traverses the matcher tree and sizes all the nodes
+/// that are children of the three kinds of nodes that have them.
+unsigned MatcherTableEmitter::
+SizeMatcherList(Matcher *N, raw_ostream &OS) {
+  unsigned Size = 0;
+  while (N) {
+Size += SizeMatcher(N, OS);
+N = N->getNext();
+  }
+  return Size;
+}
+
+/// This function sizes the children of the three kinds of nodes that
+/// have them. It does so by using special cases for those three
+/// nodes, but sharing th

[llvm-branch-commits] [llvm] b23e84f - [TableGen] Eliminte source location from CodeInit

2020-11-23 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2020-11-23T11:30:13-05:00
New Revision: b23e84ffcff8957e095599a6b7fd3f24ecf1f18c

URL: 
https://github.com/llvm/llvm-project/commit/b23e84ffcff8957e095599a6b7fd3f24ecf1f18c
DIFF: 
https://github.com/llvm/llvm-project/commit/b23e84ffcff8957e095599a6b7fd3f24ecf1f18c.diff

LOG: [TableGen] Eliminte source location from CodeInit

Step 1 in eliminating the 'code' type.

Differential Revision: https://reviews.llvm.org/D91932

Added: 


Modified: 
llvm/docs/TableGen/BackGuide.rst
llvm/include/llvm/TableGen/Record.h
llvm/lib/TableGen/Record.cpp
llvm/lib/TableGen/TGParser.cpp
llvm/unittests/TableGen/CodeExpanderTest.cpp
llvm/utils/TableGen/GICombinerEmitter.cpp
llvm/utils/TableGen/GlobalISel/CodeExpander.cpp

Removed: 




diff  --git a/llvm/docs/TableGen/BackGuide.rst 
b/llvm/docs/TableGen/BackGuide.rst
index 59a1ed1450f1..515eeab2403a 100644
--- a/llvm/docs/TableGen/BackGuide.rst
+++ b/llvm/docs/TableGen/BackGuide.rst
@@ -336,14 +336,11 @@ The class provides the following additional functions.
 The ``CodeInit`` class is a subclass of ``TypedInit``. Its instances
 represent arbitrary-length strings produced from ``code`` literals in the
 TableGen files. It includes a data member that contains a ``StringRef`` of
-the value. It also includes a data member specifying the source code
-location of the code string.
+the value.
 
 The class provides the usual ``get()`` and ``getValue()`` functions. The
 latter function returns the ``StringRef``.
 
-The ``getLoc()`` function returns the source code location.
-
 
 ``DagInit``
 ~~~

diff  --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index 2ff4df462b04..567908f93e55 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -597,7 +597,13 @@ class IntInit : public TypedInit {
 
 /// "foo" - Represent an initialization by a string value.
 class StringInit : public TypedInit {
+  enum StringFormat {
+SF_String,  // Format as "text"
+SF_Code,// Format as [{text}]
+  };
+
   StringRef Value;
+  StringFormat Format;
 
   explicit StringInit(StringRef V)
   : TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
@@ -630,11 +636,10 @@ class StringInit : public TypedInit {
 
 class CodeInit : public TypedInit {
   StringRef Value;
-  SMLoc Loc;
 
-  explicit CodeInit(StringRef V, const SMLoc &Loc)
+  explicit CodeInit(StringRef V)
   : TypedInit(IK_CodeInit, static_cast(CodeRecTy::get())),
-Value(V), Loc(Loc) {}
+Value(V) {}
 
 public:
   CodeInit(const StringInit &) = delete;
@@ -644,10 +649,9 @@ class CodeInit : public TypedInit {
 return I->getKind() == IK_CodeInit;
   }
 
-  static CodeInit *get(StringRef, const SMLoc &Loc);
+  static CodeInit *get(StringRef);
 
   StringRef getValue() const { return Value; }
-  const SMLoc &getLoc() const { return Loc; }
 
   Init *convertInitializerTo(RecTy *Ty) const override;
 
@@ -1649,6 +1653,9 @@ class Record {
   // High-level methods useful to tablegen back-ends
   //
 
+  ///Return the source location for the named field.
+  SMLoc getFieldLoc(StringRef FieldName) const;
+
   /// Return the initializer for a value with the specified name,
   /// or throw an exception if the field does not exist.
   Init *getValueInit(StringRef FieldName) const;

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 43b906ea2248..a8f0e19a2bbd 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -514,20 +514,13 @@ IntInit::convertInitializerBitRange(ArrayRef 
Bits) const {
   return BitsInit::get(NewBits);
 }
 
-CodeInit *CodeInit::get(StringRef V, const SMLoc &Loc) {
-  static StringSet ThePool(Allocator);
+CodeInit *CodeInit::get(StringRef V) {
+  static StringMap ThePool(Allocator);
 
-  CodeInitsConstructed++;
-
-  // Unlike StringMap, StringSet doesn't accept empty keys.
-  if (V.empty())
-return new (Allocator) CodeInit("", Loc);
-
-  // Location tracking prevents us from de-duping CodeInits as we're never
-  // called with the same string and same location twice. However, we can at
-  // least de-dupe the strings for a modest saving.
-  auto &Entry = *ThePool.insert(V).first;
-  return new(Allocator) CodeInit(Entry.getKey(), Loc);
+  auto &Entry = *ThePool.insert(std::make_pair(V, nullptr)).first;
+  if (!Entry.second)
+Entry.second = new(Allocator) CodeInit(Entry.getKey());
+  return Entry.second;
 }
 
 StringInit *StringInit::get(StringRef V) {
@@ -543,7 +536,7 @@ Init *StringInit::convertInitializerTo(RecTy *Ty) const {
   if (isa(Ty))
 return const_cast(this);
   if (isa(Ty))
-return CodeInit::get(getValue(), SMLoc());
+return CodeInit::get(getValue());
 
   return nullptr;
 }
@@ -1046,8 +1039,6 @@ Init *BinOpInit::Fold(Record *CurRec) const {
   default: llvm_unreachable("un

[llvm-branch-commits] [llvm] 0aeaec1 - [Timer] Add a command option to enable/disable timer sorting.

2020-11-28 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2020-11-28T11:43:38-05:00
New Revision: 0aeaec13e76a9b268cafd9b3cd3f24eb922777b0

URL: 
https://github.com/llvm/llvm-project/commit/0aeaec13e76a9b268cafd9b3cd3f24eb922777b0
DIFF: 
https://github.com/llvm/llvm-project/commit/0aeaec13e76a9b268cafd9b3cd3f24eb922777b0.diff

LOG: [Timer] Add a command option to enable/disable timer sorting.

Add one more timer to DAGISelEmitter to test the option.

Differential Revision: https://reviews.llvm.org/D92146

Added: 


Modified: 
llvm/include/llvm/TableGen/Record.h
llvm/lib/Support/Timer.cpp
llvm/utils/TableGen/DAGISelEmitter.cpp

Removed: 




diff  --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index 567908f93e55..a26367a6fcc6 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1829,7 +1829,7 @@ class RecordKeeper {
   /// Stop timing a phase.
   void stopTimer();
 
-  /// Start timing the overall backend. If the backend starts a timer,
+  /// Start timing the overall backend. If the backend itself starts a timer,
   /// then this timer is cleared.
   void startBackendTimer(StringRef Name);
 

diff  --git a/llvm/lib/Support/Timer.cpp b/llvm/lib/Support/Timer.cpp
index c97538cb560a..a3b86cfa6811 100644
--- a/llvm/lib/Support/Timer.cpp
+++ b/llvm/lib/Support/Timer.cpp
@@ -53,6 +53,11 @@ namespace {
   InfoOutputFilename("info-output-file", cl::value_desc("filename"),
  cl::desc("File to append -stats and -timer output to"),
cl::Hidden, 
cl::location(getLibSupportInfoOutputFilename()));
+
+  static cl::opt
+  SortTimers("sort-timers", cl::desc("In the report, sort the timers in each 
group "
+ "in wall clock time order"),
+ cl::init(true), cl::Hidden);
 }
 
 std::unique_ptr llvm::CreateInfoOutputFile() {
@@ -301,8 +306,9 @@ void TimerGroup::addTimer(Timer &T) {
 }
 
 void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
-  // Sort the timers in descending order by amount of time taken.
-  llvm::sort(TimersToPrint);
+  // Perhaps sort the timers in descending order by amount of time taken.
+  if (SortTimers)
+llvm::sort(TimersToPrint);
 
   TimeRecord Total;
   for (const PrintRecord &Record : TimersToPrint)

diff  --git a/llvm/utils/TableGen/DAGISelEmitter.cpp 
b/llvm/utils/TableGen/DAGISelEmitter.cpp
index 85a62855c19b..1652281b5193 100644
--- a/llvm/utils/TableGen/DAGISelEmitter.cpp
+++ b/llvm/utils/TableGen/DAGISelEmitter.cpp
@@ -189,6 +189,7 @@ void DAGISelEmitter::run(raw_ostream &OS) {
 namespace llvm {
 
 void EmitDAGISel(RecordKeeper &RK, raw_ostream &OS) {
+  RK.startTimer("Parse patterns");
   DAGISelEmitter(RK).run(OS);
 }
 



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] 415fab6 - [TableGen] Eliminate the 'code' type

2020-12-03 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2020-12-03T10:19:11-05:00
New Revision: 415fab6f67b4db59abe533130272d55b4efbf0cb

URL: 
https://github.com/llvm/llvm-project/commit/415fab6f67b4db59abe533130272d55b4efbf0cb
DIFF: 
https://github.com/llvm/llvm-project/commit/415fab6f67b4db59abe533130272d55b4efbf0cb.diff

LOG: [TableGen] Eliminate the 'code' type

Update the documentation.

Rework various backends that relied on the code type.

Differential Revision: https://reviews.llvm.org/D92269

Added: 


Modified: 
clang/utils/TableGen/ClangOptionDocEmitter.cpp
llvm/docs/TableGen/BackEnds.rst
llvm/docs/TableGen/BackGuide.rst
llvm/docs/TableGen/ProgRef.rst
llvm/include/llvm/TableGen/Error.h
llvm/include/llvm/TableGen/Record.h
llvm/include/llvm/TableGen/SearchableTable.td
llvm/lib/TableGen/Error.cpp
llvm/lib/TableGen/JSONBackend.cpp
llvm/lib/TableGen/Record.cpp
llvm/lib/TableGen/TGLexer.cpp
llvm/lib/TableGen/TGLexer.h
llvm/lib/TableGen/TGParser.cpp
llvm/lib/Target/AMDGPU/MIMGInstructions.td
llvm/test/TableGen/code.td
llvm/test/TableGen/generic-tables.td
llvm/test/TableGen/interleave.td
llvm/test/TableGen/unterminated-code-block.td
llvm/utils/TableGen/AsmWriterEmitter.cpp
llvm/utils/TableGen/DFAEmitter.cpp
llvm/utils/TableGen/GICombinerEmitter.cpp
llvm/utils/TableGen/RISCVCompressInstEmitter.cpp
llvm/utils/TableGen/SearchableTableEmitter.cpp
mlir/include/mlir/TableGen/Operator.h
mlir/lib/TableGen/Attribute.cpp
mlir/lib/TableGen/Dialect.cpp
mlir/lib/TableGen/Operator.cpp
mlir/lib/TableGen/Pattern.cpp
mlir/lib/TableGen/Type.cpp
mlir/lib/TableGen/TypeDef.cpp
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp

Removed: 




diff  --git a/clang/utils/TableGen/ClangOptionDocEmitter.cpp 
b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
index 23aa31cc732f..0e079b6b505a 100644
--- a/clang/utils/TableGen/ClangOptionDocEmitter.cpp
+++ b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
@@ -217,8 +217,6 @@ std::string getRSTStringWithTextFallback(const Record *R, 
StringRef Primary,
   StringRef Value;
   if (auto *SV = dyn_cast_or_null(V->getValue()))
 Value = SV->getValue();
-  else if (auto *CV = dyn_cast_or_null(V->getValue()))
-Value = CV->getValue();
   if (!Value.empty())
 return Field == Primary ? Value.str() : escapeRST(Value);
 }

diff  --git a/llvm/docs/TableGen/BackEnds.rst b/llvm/docs/TableGen/BackEnds.rst
index b4ccdf95485e..1e1a4e71a1fd 100644
--- a/llvm/docs/TableGen/BackEnds.rst
+++ b/llvm/docs/TableGen/BackEnds.rst
@@ -693,8 +693,8 @@ This class provides six fields.
   table that holds the entries. If unspecified, the ``FilterClass`` name is
   used.
 
-* ``list Fields``. A list of the names of the fields in the
-  collected records that contain the data for the table entries. The order of
+* ``list Fields``. A list of the names of the fields *in the
+  collected records* that contain the data for the table entries. The order of
   this list determines the order of the values in the C++ initializers. See
   below for information about the types of these fields.
 
@@ -706,13 +706,26 @@ This class provides six fields.
 
 * ``bit PrimaryKeyEarlyOut``. See the third example below.
 
-TableGen attempts to deduce the type of each of the table fields. It can
-deduce ``bit``, ``bits``, ``string``, ``Intrinsic``, and ``Instruction``.
-These can be used in the primary key. TableGen also deduces ``code``, but it
-cannot be used in the primary key. Any other field types must be specified
+TableGen attempts to deduce the type of each of the table fields so that it
+can format the C++ initializers in the emitted table. It can deduce ``bit``,
+``bits``, ``string``, ``Intrinsic``, and ``Instruction``.  These can be
+used in the primary key. Any other field types must be specified
 explicitly; this is done as shown in the second example below. Such fields
 cannot be used in the primary key.
 
+One special case of the field type has to do with code. Arbitrary code is
+represented by a string, but has to be emitted as a C++ initializer without
+quotes. If the code field was defined using a code literal (``[{...}]``),
+then TableGen will know to emit it without quotes. However, if it was
+defined using a string literal or complex string expression, then TableGen
+will not know. In this case, you can force TableGen to treat the field as
+code by including the following line in the ``GenericTable`` record, where
+*xxx* is the code field name.
+
+.. code-block:: text
+
+  string TypeOf_xxx = "code";
+
 Here is an example where TableGen can deduce the field types. Note that the
 table entry records are anonymous; the names of entry records are
 irrelevant.
@@ -793,7 +806,7 @@ pointer if no entry is found.
 
 This example includes a field whose type TableGen cannot deduce. The ``Kind``
 field us

[llvm-branch-commits] [llvm] 0b3e393 - [TableGen] [CodeGenTarget] Cache the target's instruction namespace.

2020-12-06 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2020-12-06T11:08:30-05:00
New Revision: 0b3e393d6c8b0f6bb8a13b1a71aba796c87ed239

URL: 
https://github.com/llvm/llvm-project/commit/0b3e393d6c8b0f6bb8a13b1a71aba796c87ed239
DIFF: 
https://github.com/llvm/llvm-project/commit/0b3e393d6c8b0f6bb8a13b1a71aba796c87ed239.diff

LOG: [TableGen] [CodeGenTarget] Cache the target's instruction namespace.

Differential Revision: https://reviews.llvm.org/D92722

Added: 


Modified: 
llvm/utils/TableGen/CodeGenTarget.cpp
llvm/utils/TableGen/CodeGenTarget.h

Removed: 




diff  --git a/llvm/utils/TableGen/CodeGenTarget.cpp 
b/llvm/utils/TableGen/CodeGenTarget.cpp
index 794bb622dc99..d8e1d7f8cf0d 100644
--- a/llvm/utils/TableGen/CodeGenTarget.cpp
+++ b/llvm/utils/TableGen/CodeGenTarget.cpp
@@ -264,15 +264,20 @@ const StringRef CodeGenTarget::getName() const {
   return TargetRec->getName();
 }
 
+/// getInstNamespace - Find and return the target machine's instruction
+/// namespace. The namespace is cached because it is requested multiple times.
 StringRef CodeGenTarget::getInstNamespace() const {
-  for (const CodeGenInstruction *Inst : getInstructionsByEnumValue()) {
-// Make sure not to pick up "TargetOpcode" by accidentally getting
-// the namespace off the PHI instruction or something.
-if (Inst->Namespace != "TargetOpcode")
-  return Inst->Namespace;
+  if (InstNamespace.empty()) {
+for (const CodeGenInstruction *Inst : getInstructionsByEnumValue()) {
+  // We are not interested in the "TargetOpcode" namespace.
+  if (Inst->Namespace != "TargetOpcode") {
+InstNamespace = Inst->Namespace;
+break;
+  }
+}
   }
 
-  return "";
+  return InstNamespace;
 }
 
 StringRef CodeGenTarget::getRegNamespace() const {

diff  --git a/llvm/utils/TableGen/CodeGenTarget.h 
b/llvm/utils/TableGen/CodeGenTarget.h
index 44bc46a0a421..cc5bbe7a8bfe 100644
--- a/llvm/utils/TableGen/CodeGenTarget.h
+++ b/llvm/utils/TableGen/CodeGenTarget.h
@@ -60,6 +60,7 @@ class CodeGenTarget {
 
   mutable std::unique_ptr SchedModels;
 
+  mutable StringRef InstNamespace;
   mutable std::vector InstrsByEnum;
   mutable unsigned NumPseudoInstructions = 0;
 public:



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] 6266f36 - [TableGen] Cache the vectors of records returned by getAllDerivedDefinitions().

2020-12-09 Thread Paul C. Anagnostopoulos via llvm-branch-commits

Author: Paul C. Anagnostopoulos
Date: 2020-12-09T10:54:04-05:00
New Revision: 6266f36226bb96e42015411048f3ed5afb751510

URL: 
https://github.com/llvm/llvm-project/commit/6266f36226bb96e42015411048f3ed5afb751510
DIFF: 
https://github.com/llvm/llvm-project/commit/6266f36226bb96e42015411048f3ed5afb751510.diff

LOG: [TableGen] Cache the vectors of records returned by 
getAllDerivedDefinitions().

Differential Revision: https://reviews.llvm.org/D92674

Added: 


Modified: 
llvm/include/llvm/TableGen/Record.h
llvm/lib/TableGen/Record.cpp
llvm/utils/TableGen/InstrInfoEmitter.cpp

Removed: 




diff  --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index fe552331b385..3010b4dad09a 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1703,6 +1703,7 @@ class RecordKeeper {
 
   std::string InputFilename;
   RecordMap Classes, Defs;
+  mutable StringMap> ClassRecordsMap;
   FoldingSet RecordTypePool;
   std::map> ExtraGlobals;
   unsigned AnonCounter = 0;
@@ -1801,17 +1802,14 @@ class RecordKeeper {
   
//======//
   // High-level helper methods, useful for tablegen backends.
 
-  /// Get all the concrete records that inherit from all the specified
-  /// classes. The classes must be defined.
-  std::vector getAllDerivedDefinitions(
-  const ArrayRef ClassNames) const;
-
   /// Get all the concrete records that inherit from the one specified
   /// class. The class must be defined.
-  std::vector getAllDerivedDefinitions(StringRef ClassName) const {
+  std::vector getAllDerivedDefinitions(StringRef ClassName) const;
 
-return getAllDerivedDefinitions(makeArrayRef(ClassName));
-  }
+  /// Get all the concrete records that inherit from all the specified
+  /// classes. The classes must be defined.
+  std::vector getAllDerivedDefinitions(
+  ArrayRef ClassNames) const;
 
   void dump() const;
 };

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 1e2d75f3fe8d..367c5590ea87 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2595,8 +2595,20 @@ void RecordKeeper::stopBackendTimer() {
   }
 }
 
+// We cache the record vectors for single classes. Many backends request
+// the same vectors multiple times.
 std::vector RecordKeeper::getAllDerivedDefinitions(
-const ArrayRef ClassNames) const {
+StringRef ClassName) const {
+
+  auto Pair = ClassRecordsMap.try_emplace(ClassName);
+  if (Pair.second)
+Pair.first->second = getAllDerivedDefinitions(makeArrayRef(ClassName));
+
+  return Pair.first->second;
+}
+
+std::vector RecordKeeper::getAllDerivedDefinitions(
+ArrayRef ClassNames) const {
   SmallVector ClassRecs;
   std::vector Defs;
 

diff  --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp 
b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index ac1a8e09f1cb..025c5354514c 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -532,6 +532,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
   unsigned ListNumber = 0;
 
   // Emit all of the instruction's implicit uses and defs.
+  Records.startTimer("Emit uses/defs");
   for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) {
 Record *Inst = II->TheDef;
 std::vector Uses = Inst->getValueAsListOfDefs("Uses");
@@ -549,10 +550,12 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
   OperandInfoMapTy OperandInfoIDs;
 
   // Emit all of the operand info records.
+  Records.startTimer("Emit operand info");
   EmitOperandInfo(OS, OperandInfoIDs);
 
   // Emit all of the MCInstrDesc records in their ENUM ordering.
   //
+  Records.startTimer("Emit InstrDesc records");
   OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n";
   ArrayRef NumberedInstructions =
 Target.getInstructionsByEnumValue();
@@ -568,6 +571,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
   OS << "};\n\n";
 
   // Emit the array of instruction names.
+  Records.startTimer("Emit instruction names");
   InstrNames.layout();
   InstrNames.emitStringLiteralDef(OS, Twine("extern const char ") + TargetName 
+
   "InstrNameData[]");
@@ -628,6 +632,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
   }
 
   // MCInstrInfo initialization routine.
+  Records.startTimer("Emit initialization routine");
   OS << "static inline void Init" << TargetName
  << "MCInstrInfo(MCInstrInfo *II) {\n";
   OS << "  II->InitMCInstrInfo(" << TargetName << "Insts, " << TargetName
@@ -706,10 +711,13 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
 
   OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n";
 
+  Records.startTimer("Emit operand name mappings");
   emitOperandNameMappings(OS, Target, NumberedInstructions);
 
+  Records.startTimer("Emit operand type mappings");
   emitOperandType