[llvm-branch-commits] [llvm] a022be6 - [TableGen] Enhance !cast to handle bit and bits types.
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
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"
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
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.
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
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.
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.
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.
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
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
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"
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.
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
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
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
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
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.
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
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.
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().
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