diff options
Diffstat (limited to 'lib/TableGen')
-rw-r--r-- | lib/TableGen/Main.cpp | 44 | ||||
-rw-r--r-- | lib/TableGen/Record.cpp | 443 | ||||
-rw-r--r-- | lib/TableGen/TGLexer.cpp | 16 | ||||
-rw-r--r-- | lib/TableGen/TGLexer.h | 4 | ||||
-rw-r--r-- | lib/TableGen/TGParser.cpp | 240 | ||||
-rw-r--r-- | lib/TableGen/TGParser.h | 38 |
6 files changed, 385 insertions, 400 deletions
diff --git a/lib/TableGen/Main.cpp b/lib/TableGen/Main.cpp index bb590c7d87f2..278b567fb220 100644 --- a/lib/TableGen/Main.cpp +++ b/lib/TableGen/Main.cpp @@ -17,6 +17,7 @@ #include "llvm/TableGen/Main.h" #include "TGParser.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" @@ -45,22 +46,25 @@ static cl::list<std::string> IncludeDirs("I", cl::desc("Directory of include files"), cl::value_desc("directory"), cl::Prefix); +static int reportError(const char *ProgName, Twine Msg) { + errs() << ProgName << ": " << Msg; + errs().flush(); + return 1; +} + /// \brief Create a dependency file for `-d` option. /// /// This functionality is really only for the benefit of the build system. /// It is similar to GCC's `-M*` family of options. static int createDependencyFile(const TGParser &Parser, const char *argv0) { - if (OutputFilename == "-") { - errs() << argv0 << ": the option -d must be used together with -o\n"; - return 1; - } + if (OutputFilename == "-") + return reportError(argv0, "the option -d must be used together with -o\n"); + std::error_code EC; tool_output_file DepOut(DependFilename, EC, sys::fs::F_Text); - if (EC) { - errs() << argv0 << ": error opening " << DependFilename << ":" - << EC.message() << "\n"; - return 1; - } + if (EC) + return reportError(argv0, "error opening " + DependFilename + ":" + + EC.message() + "\n"); DepOut.os() << OutputFilename << ":"; for (const auto &Dep : Parser.getDependencies()) { DepOut.os() << ' ' << Dep.first; @@ -76,11 +80,9 @@ int llvm::TableGenMain(char *argv0, TableGenMainFn *MainFn) { // Parse the input file. ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = MemoryBuffer::getFileOrSTDIN(InputFilename); - if (std::error_code EC = FileOrErr.getError()) { - errs() << "Could not open input file '" << InputFilename - << "': " << EC.message() << "\n"; - return 1; - } + if (std::error_code EC = FileOrErr.getError()) + return reportError(argv0, "Could not open input file '" + InputFilename + + "': " + EC.message() + "\n"); // Tell SrcMgr about this buffer, which is what TGParser will pick up. SrcMgr.AddNewSourceBuffer(std::move(*FileOrErr), SMLoc()); @@ -96,11 +98,9 @@ int llvm::TableGenMain(char *argv0, TableGenMainFn *MainFn) { std::error_code EC; tool_output_file Out(OutputFilename, EC, sys::fs::F_Text); - if (EC) { - errs() << argv0 << ": error opening " << OutputFilename << ":" - << EC.message() << "\n"; - return 1; - } + if (EC) + return reportError(argv0, "error opening " + OutputFilename + ":" + + EC.message() + "\n"); if (!DependFilename.empty()) { if (int Ret = createDependencyFile(Parser, argv0)) return Ret; @@ -109,10 +109,8 @@ int llvm::TableGenMain(char *argv0, TableGenMainFn *MainFn) { if (MainFn(Out.os(), Records)) return 1; - if (ErrorsPrinted > 0) { - errs() << argv0 << ": " << ErrorsPrinted << " errors.\n"; - return 1; - } + if (ErrorsPrinted > 0) + return reportError(argv0, utostr(ErrorsPrinted) + " errors.\n"); // Declare success. Out.keep(); diff --git a/lib/TableGen/Record.cpp b/lib/TableGen/Record.cpp index 66fbc9a8c96b..ea9c9a19904e 100644 --- a/lib/TableGen/Record.cpp +++ b/lib/TableGen/Record.cpp @@ -15,67 +15,20 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/Hashing.h" -#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/Format.h" #include "llvm/TableGen/Error.h" +#include <cassert> +#include <cstdint> +#include <new> using namespace llvm; -//===----------------------------------------------------------------------===// -// std::string wrapper for DenseMap purposes -//===----------------------------------------------------------------------===// - -namespace llvm { - -/// This is a wrapper for std::string suitable for using as a key to a DenseMap. -/// Because there isn't a particularly -/// good way to indicate tombstone or empty keys for strings, we want -/// to wrap std::string to indicate that this is a "special" string -/// not expected to take on certain values (those of the tombstone and -/// empty keys). This makes things a little safer as it clarifies -/// that DenseMap is really not appropriate for general strings. - -class TableGenStringKey { -public: - TableGenStringKey(const std::string &str) : data(str) {} - TableGenStringKey(const char *str) : data(str) {} - - const std::string &str() const { return data; } - - friend hash_code hash_value(const TableGenStringKey &Value) { - using llvm::hash_value; - return hash_value(Value.str()); - } -private: - std::string data; -}; - -/// Specialize DenseMapInfo for TableGenStringKey. -template<> struct DenseMapInfo<TableGenStringKey> { - static inline TableGenStringKey getEmptyKey() { - TableGenStringKey Empty("<<<EMPTY KEY>>>"); - return Empty; - } - static inline TableGenStringKey getTombstoneKey() { - TableGenStringKey Tombstone("<<<TOMBSTONE KEY>>>"); - return Tombstone; - } - static unsigned getHashValue(const TableGenStringKey& Val) { - using llvm::hash_value; - return hash_value(Val); - } - static bool isEqual(const TableGenStringKey& LHS, - const TableGenStringKey& RHS) { - return LHS.str() == RHS.str(); - } -}; - -} // namespace llvm +static BumpPtrAllocator Allocator; //===----------------------------------------------------------------------===// // Type implementations @@ -91,8 +44,8 @@ LLVM_DUMP_METHOD void RecTy::dump() const { print(errs()); } ListRecTy *RecTy::getListTy() { if (!ListTy) - ListTy.reset(new ListRecTy(this)); - return ListTy.get(); + ListTy = new(Allocator) ListRecTy(this); + return ListTy; } bool RecTy::typeIsConvertibleTo(const RecTy *RHS) const { @@ -109,13 +62,13 @@ bool BitRecTy::typeIsConvertibleTo(const RecTy *RHS) const{ } BitsRecTy *BitsRecTy::get(unsigned Sz) { - static std::vector<std::unique_ptr<BitsRecTy>> Shared; + static std::vector<BitsRecTy*> Shared; if (Sz >= Shared.size()) Shared.resize(Sz + 1); - std::unique_ptr<BitsRecTy> &Ty = Shared[Sz]; + BitsRecTy *&Ty = Shared[Sz]; if (!Ty) - Ty.reset(new BitsRecTy(Sz)); - return Ty.get(); + Ty = new(Allocator) BitsRecTy(Sz); + return Ty; } std::string BitsRecTy::getAsString() const { @@ -203,7 +156,6 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) { return nullptr; } - //===----------------------------------------------------------------------===// // Initializer implementations //===----------------------------------------------------------------------===// @@ -263,7 +215,7 @@ ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef<Init *> Range) { BitsInit *BitsInit::get(ArrayRef<Init *> Range) { static FoldingSet<BitsInit> ThePool; - static std::vector<std::unique_ptr<BitsInit>> TheActualPool; + static std::vector<BitsInit*> TheActualPool; FoldingSetNodeID ID; ProfileBitsInit(ID, Range); @@ -272,12 +224,13 @@ BitsInit *BitsInit::get(ArrayRef<Init *> Range) { if (BitsInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) return I; - void *Mem = ::operator new (totalSizeToAlloc<Init *>(Range.size())); - BitsInit *I = new (Mem) BitsInit(Range.size()); + void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()), + alignof(BitsInit)); + BitsInit *I = new(Mem) BitsInit(Range.size()); std::uninitialized_copy(Range.begin(), Range.end(), I->getTrailingObjects<Init *>()); ThePool.InsertNode(I, IP); - TheActualPool.push_back(std::unique_ptr<BitsInit>(I)); + TheActualPool.push_back(I); return I; } @@ -312,7 +265,7 @@ Init *BitsInit::convertInitializerTo(RecTy *Ty) const { } Init * -BitsInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const { +BitsInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const { SmallVector<Init *, 16> NewBits(Bits.size()); for (unsigned i = 0, e = Bits.size(); i != e; ++i) { @@ -393,11 +346,11 @@ Init *BitsInit::resolveReferences(Record &R, const RecordVal *RV) const { } IntInit *IntInit::get(int64_t V) { - static DenseMap<int64_t, std::unique_ptr<IntInit>> ThePool; + static DenseMap<int64_t, IntInit*> ThePool; - std::unique_ptr<IntInit> &I = ThePool[V]; - if (!I) I.reset(new IntInit(V)); - return I.get(); + IntInit *&I = ThePool[V]; + if (!I) I = new(Allocator) IntInit(V); + return I; } std::string IntInit::getAsString() const { @@ -437,7 +390,7 @@ Init *IntInit::convertInitializerTo(RecTy *Ty) const { } Init * -IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const { +IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const { SmallVector<Init *, 16> NewBits(Bits.size()); for (unsigned i = 0, e = Bits.size(); i != e; ++i) { @@ -450,19 +403,27 @@ IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const { } CodeInit *CodeInit::get(StringRef V) { - static StringMap<std::unique_ptr<CodeInit>> ThePool; + static DenseMap<StringRef, CodeInit*> ThePool; - std::unique_ptr<CodeInit> &I = ThePool[V]; - if (!I) I.reset(new CodeInit(V)); - return I.get(); + auto I = ThePool.insert(std::make_pair(V, nullptr)); + if (I.second) { + StringRef VCopy = V.copy(Allocator); + I.first->first = VCopy; + I.first->second = new(Allocator) CodeInit(VCopy); + } + return I.first->second; } StringInit *StringInit::get(StringRef V) { - static StringMap<std::unique_ptr<StringInit>> ThePool; + static DenseMap<StringRef, StringInit*> ThePool; - std::unique_ptr<StringInit> &I = ThePool[V]; - if (!I) I.reset(new StringInit(V)); - return I.get(); + auto I = ThePool.insert(std::make_pair(V, nullptr)); + if (I.second) { + StringRef VCopy = V.copy(Allocator); + I.first->first = VCopy; + I.first->second = new(Allocator) StringInit(VCopy); + } + return I.first->second; } Init *StringInit::convertInitializerTo(RecTy *Ty) const { @@ -491,7 +452,7 @@ static void ProfileListInit(FoldingSetNodeID &ID, ListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) { static FoldingSet<ListInit> ThePool; - static std::vector<std::unique_ptr<ListInit>> TheActualPool; + static std::vector<ListInit*> TheActualPool; FoldingSetNodeID ID; ProfileListInit(ID, Range, EltTy); @@ -500,12 +461,13 @@ ListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) { if (ListInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) return I; - void *Mem = ::operator new (totalSizeToAlloc<Init *>(Range.size())); - ListInit *I = new (Mem) ListInit(Range.size(), EltTy); + void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()), + alignof(ListInit)); + ListInit *I = new(Mem) ListInit(Range.size(), EltTy); std::uninitialized_copy(Range.begin(), Range.end(), I->getTrailingObjects<Init *>()); ThePool.InsertNode(I, IP); - TheActualPool.push_back(std::unique_ptr<ListInit>(I)); + TheActualPool.push_back(I); return I; } @@ -516,31 +478,40 @@ void ListInit::Profile(FoldingSetNodeID &ID) const { } Init *ListInit::convertInitializerTo(RecTy *Ty) const { + if (getType() == Ty) + return const_cast<ListInit*>(this); + if (auto *LRT = dyn_cast<ListRecTy>(Ty)) { - std::vector<Init*> Elements; + SmallVector<Init*, 8> Elements; + Elements.reserve(getValues().size()); // Verify that all of the elements of the list are subclasses of the // appropriate class! + bool Changed = false; + RecTy *ElementType = LRT->getElementType(); for (Init *I : getValues()) - if (Init *CI = I->convertInitializerTo(LRT->getElementType())) + if (Init *CI = I->convertInitializerTo(ElementType)) { Elements.push_back(CI); - else + if (CI != I) + Changed = true; + } else return nullptr; - if (isa<ListRecTy>(getType())) - return ListInit::get(Elements, Ty); + if (!Changed) + return const_cast<ListInit*>(this); + return ListInit::get(Elements, Ty); } return nullptr; } -Init * -ListInit::convertInitListSlice(const std::vector<unsigned> &Elements) const { - std::vector<Init*> Vals; - for (unsigned i = 0, e = Elements.size(); i != e; ++i) { - if (Elements[i] >= size()) +Init *ListInit::convertInitListSlice(ArrayRef<unsigned> Elements) const { + SmallVector<Init*, 8> Vals; + Vals.reserve(Elements.size()); + for (unsigned Element : Elements) { + if (Element >= size()) return nullptr; - Vals.push_back(getElement(Elements[i])); + Vals.push_back(getElement(Element)); } return ListInit::get(Vals, getType()); } @@ -554,7 +525,7 @@ Record *ListInit::getElementAsRecord(unsigned i) const { } Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) const { - std::vector<Init*> Resolved; + SmallVector<Init*, 8> Resolved; Resolved.reserve(size()); bool Changed = false; @@ -589,9 +560,11 @@ Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV, std::string ListInit::getAsString() const { std::string Result = "["; - for (unsigned i = 0, e = NumValues; i != e; ++i) { - if (i) Result += ", "; - Result += getElement(i)->getAsString(); + const char *sep = ""; + for (Init *Element : *this) { + Result += sep; + sep = ", "; + Result += Element->getAsString(); } return Result + "]"; } @@ -629,7 +602,7 @@ ProfileUnOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *Op, RecTy *Type) { UnOpInit *UnOpInit::get(UnaryOp Opc, Init *LHS, RecTy *Type) { static FoldingSet<UnOpInit> ThePool; - static std::vector<std::unique_ptr<UnOpInit>> TheActualPool; + static std::vector<UnOpInit*> TheActualPool; FoldingSetNodeID ID; ProfileUnOpInit(ID, Opc, LHS, Type); @@ -638,9 +611,9 @@ UnOpInit *UnOpInit::get(UnaryOp Opc, Init *LHS, RecTy *Type) { if (UnOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) return I; - UnOpInit *I = new UnOpInit(Opc, LHS, Type); + UnOpInit *I = new(Allocator) UnOpInit(Opc, LHS, Type); ThePool.InsertNode(I, IP); - TheActualPool.push_back(std::unique_ptr<UnOpInit>(I)); + TheActualPool.push_back(I); return I; } @@ -661,9 +634,7 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { if (IntInit *LHSi = dyn_cast<IntInit>(LHS)) return StringInit::get(LHSi->getAsString()); } else { - if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) { - const std::string &Name = LHSs->getValue(); - + if (StringInit *Name = dyn_cast<StringInit>(LHS)) { // From TGParser::ParseIDValue if (CurRec) { if (const RecordVal *RV = CurRec->getValue(Name)) { @@ -701,11 +672,11 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { } } assert(CurRec && "NULL pointer"); - if (Record *D = (CurRec->getRecords()).getDef(Name)) + if (Record *D = (CurRec->getRecords()).getDef(Name->getValue())) return DefInit::get(D); PrintFatalError(CurRec->getLoc(), - "Undefined reference:'" + Name + "'\n"); + "Undefined reference:'" + Name->getValue() + "'\n"); } if (isa<IntRecTy>(getType())) { @@ -777,7 +748,7 @@ ProfileBinOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *RHS, BinOpInit *BinOpInit::get(BinaryOp Opc, Init *LHS, Init *RHS, RecTy *Type) { static FoldingSet<BinOpInit> ThePool; - static std::vector<std::unique_ptr<BinOpInit>> TheActualPool; + static std::vector<BinOpInit*> TheActualPool; FoldingSetNodeID ID; ProfileBinOpInit(ID, Opc, LHS, RHS, Type); @@ -786,9 +757,9 @@ BinOpInit *BinOpInit::get(BinaryOp Opc, Init *LHS, if (BinOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) return I; - BinOpInit *I = new BinOpInit(Opc, LHS, RHS, Type); + BinOpInit *I = new(Allocator) BinOpInit(Opc, LHS, RHS, Type); ThePool.InsertNode(I, IP); - TheActualPool.push_back(std::unique_ptr<BinOpInit>(I)); + TheActualPool.push_back(I); return I; } @@ -796,6 +767,13 @@ void BinOpInit::Profile(FoldingSetNodeID &ID) const { ProfileBinOpInit(ID, getOpcode(), getLHS(), getRHS(), getType()); } +static StringInit *ConcatStringInits(const StringInit *I0, + const StringInit *I1) { + SmallString<80> Concat(I0->getValue()); + Concat.append(I1->getValue()); + return StringInit::get(Concat); +} + Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { switch (getOpcode()) { case CONCAT: { @@ -806,8 +784,8 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { DefInit *ROp = dyn_cast<DefInit>(RHSs->getOperator()); if (!LOp || !ROp || LOp->getDef() != ROp->getDef()) PrintFatalError("Concated Dag operators do not match!"); - std::vector<Init*> Args; - std::vector<std::string> ArgNames; + SmallVector<Init*, 8> Args; + SmallVector<StringInit*, 8> ArgNames; for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) { Args.push_back(LHSs->getArg(i)); ArgNames.push_back(LHSs->getArgName(i)); @@ -816,7 +794,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { Args.push_back(RHSs->getArg(i)); ArgNames.push_back(RHSs->getArgName(i)); } - return DagInit::get(LHSs->getOperator(), "", Args, ArgNames); + return DagInit::get(LHSs->getOperator(), nullptr, Args, ArgNames); } break; } @@ -824,7 +802,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { ListInit *LHSs = dyn_cast<ListInit>(LHS); ListInit *RHSs = dyn_cast<ListInit>(RHS); if (LHSs && RHSs) { - std::vector<Init *> Args; + SmallVector<Init *, 8> Args; Args.insert(Args.end(), LHSs->begin(), LHSs->end()); Args.insert(Args.end(), RHSs->begin(), RHSs->end()); return ListInit::get( @@ -836,7 +814,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { StringInit *LHSs = dyn_cast<StringInit>(LHS); StringInit *RHSs = dyn_cast<StringInit>(RHS); if (LHSs && RHSs) - return StringInit::get(LHSs->getValue() + RHSs->getValue()); + return ConcatStringInits(LHSs, RHSs); break; } case EQ: { @@ -861,6 +839,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { } case ADD: case AND: + case OR: case SHL: case SRA: case SRL: { @@ -875,6 +854,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { default: llvm_unreachable("Bad opcode!"); case ADD: Result = LHSv + RHSv; break; case AND: Result = LHSv & RHSv; break; + case OR: Result = LHSv | RHSv; break; case SHL: Result = LHSv << RHSv; break; case SRA: Result = LHSv >> RHSv; break; case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break; @@ -902,6 +882,7 @@ std::string BinOpInit::getAsString() const { case CONCAT: Result = "!con"; break; case ADD: Result = "!add"; break; case AND: Result = "!and"; break; + case OR: Result = "!or"; break; case SHL: Result = "!shl"; break; case SRA: Result = "!sra"; break; case SRL: Result = "!srl"; break; @@ -925,7 +906,7 @@ ProfileTernOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *MHS, TernOpInit *TernOpInit::get(TernaryOp Opc, Init *LHS, Init *MHS, Init *RHS, RecTy *Type) { static FoldingSet<TernOpInit> ThePool; - static std::vector<std::unique_ptr<TernOpInit>> TheActualPool; + static std::vector<TernOpInit*> TheActualPool; FoldingSetNodeID ID; ProfileTernOpInit(ID, Opc, LHS, MHS, RHS, Type); @@ -934,9 +915,9 @@ TernOpInit *TernOpInit::get(TernaryOp Opc, Init *LHS, Init *MHS, Init *RHS, if (TernOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) return I; - TernOpInit *I = new TernOpInit(Opc, LHS, MHS, RHS, Type); + TernOpInit *I = new(Allocator) TernOpInit(Opc, LHS, MHS, RHS, Type); ThePool.InsertNode(I, IP); - TheActualPool.push_back(std::unique_ptr<TernOpInit>(I)); + TheActualPool.push_back(I); return I; } @@ -955,8 +936,9 @@ static Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg, if (isa<DagRecTy>(TArg->getType())) return ForeachHelper(LHS, Arg, RHSo, Type, CurRec, CurMultiClass); - std::vector<Init *> NewOperands; - for (unsigned i = 0; i < RHSo->getNumOperands(); ++i) { + SmallVector<Init *, 8> NewOperands; + NewOperands.reserve(RHSo->getNumOperands()); + for (unsigned i = 0, e = RHSo->getNumOperands(); i < e; ++i) { if (auto *RHSoo = dyn_cast<OpInit>(RHSo->getOperand(i))) { if (Init *Result = EvaluateOperation(RHSoo, LHS, Arg, Type, CurRec, CurMultiClass)) @@ -996,10 +978,10 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, Type, CurRec, CurMultiClass)) Val = Result; - std::vector<std::pair<Init *, std::string> > args; + SmallVector<std::pair<Init *, StringInit*>, 8> args; for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) { Init *Arg = MHSd->getArg(i); - std::string ArgName = MHSd->getArgName(i); + StringInit *ArgName = MHSd->getArgName(i); // Process args if (Init *Result = EvaluateOperation(RHSo, LHS, Arg, Type, @@ -1010,13 +992,13 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, args.push_back(std::make_pair(Arg, ArgName)); } - return DagInit::get(Val, "", args); + return DagInit::get(Val, nullptr, args); } ListInit *MHSl = dyn_cast<ListInit>(MHS); if (MHSl && isa<ListRecTy>(Type)) { - std::vector<Init *> NewOperands; - std::vector<Init *> NewList(MHSl->begin(), MHSl->end()); + SmallVector<Init *, 8> NewOperands; + SmallVector<Init *, 8> NewList(MHSl->begin(), MHSl->end()); for (Init *&Item : NewList) { NewOperands.clear(); @@ -1148,7 +1130,7 @@ std::string TernOpInit::getAsString() const { RHS->getAsString() + ")"; } -RecTy *TypedInit::getFieldType(const std::string &FieldName) const { +RecTy *TypedInit::getFieldType(StringInit *FieldName) const { if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType())) if (RecordVal *Field = RecordType->getRecord()->getValue(FieldName)) return Field->getType(); @@ -1237,56 +1219,56 @@ TypedInit::convertInitializerTo(RecTy *Ty) const { return nullptr; } -Init * -TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) const { +Init *TypedInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const { BitsRecTy *T = dyn_cast<BitsRecTy>(getType()); if (!T) return nullptr; // Cannot subscript a non-bits variable. unsigned NumBits = T->getNumBits(); - SmallVector<Init *, 16> NewBits(Bits.size()); - for (unsigned i = 0, e = Bits.size(); i != e; ++i) { - if (Bits[i] >= NumBits) + SmallVector<Init *, 16> NewBits; + NewBits.reserve(Bits.size()); + for (unsigned Bit : Bits) { + if (Bit >= NumBits) return nullptr; - NewBits[i] = VarBitInit::get(const_cast<TypedInit *>(this), Bits[i]); + NewBits.push_back(VarBitInit::get(const_cast<TypedInit *>(this), Bit)); } return BitsInit::get(NewBits); } -Init * -TypedInit::convertInitListSlice(const std::vector<unsigned> &Elements) const { +Init *TypedInit::convertInitListSlice(ArrayRef<unsigned> Elements) const { ListRecTy *T = dyn_cast<ListRecTy>(getType()); if (!T) return nullptr; // Cannot subscript a non-list variable. if (Elements.size() == 1) return VarListElementInit::get(const_cast<TypedInit *>(this), Elements[0]); - std::vector<Init*> ListInits; + SmallVector<Init*, 8> ListInits; ListInits.reserve(Elements.size()); - for (unsigned i = 0, e = Elements.size(); i != e; ++i) + for (unsigned Element : Elements) ListInits.push_back(VarListElementInit::get(const_cast<TypedInit *>(this), - Elements[i])); + Element)); return ListInit::get(ListInits, T); } -VarInit *VarInit::get(const std::string &VN, RecTy *T) { +VarInit *VarInit::get(StringRef VN, RecTy *T) { Init *Value = StringInit::get(VN); return VarInit::get(Value, T); } VarInit *VarInit::get(Init *VN, RecTy *T) { typedef std::pair<RecTy *, Init *> Key; - static DenseMap<Key, std::unique_ptr<VarInit>> ThePool; + static DenseMap<Key, VarInit*> ThePool; Key TheKey(std::make_pair(T, VN)); - std::unique_ptr<VarInit> &I = ThePool[TheKey]; - if (!I) I.reset(new VarInit(VN, T)); - return I.get(); + VarInit *&I = ThePool[TheKey]; + if (!I) + I = new(Allocator) VarInit(VN, T); + return I; } -const std::string &VarInit::getName() const { +StringRef VarInit::getName() const { StringInit *NameString = cast<StringInit>(getNameInit()); return NameString->getValue(); } @@ -1320,8 +1302,7 @@ Init *VarInit::resolveListElementReference(Record &R, return nullptr; } - -RecTy *VarInit::getFieldType(const std::string &FieldName) const { +RecTy *VarInit::getFieldType(StringInit *FieldName) const { if (RecordRecTy *RTy = dyn_cast<RecordRecTy>(getType())) if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName)) return RV->getType(); @@ -1329,7 +1310,7 @@ RecTy *VarInit::getFieldType(const std::string &FieldName) const { } Init *VarInit::getFieldInit(Record &R, const RecordVal *RV, - const std::string &FieldName) const { + StringInit *FieldName) const { if (isa<RecordRecTy>(getType())) if (const RecordVal *Val = R.getValue(VarName)) { if (RV != Val && (RV || isa<UnsetInit>(Val->getValue()))) @@ -1352,13 +1333,14 @@ Init *VarInit::resolveReferences(Record &R, const RecordVal *RV) const { VarBitInit *VarBitInit::get(TypedInit *T, unsigned B) { typedef std::pair<TypedInit *, unsigned> Key; - static DenseMap<Key, std::unique_ptr<VarBitInit>> ThePool; + static DenseMap<Key, VarBitInit*> ThePool; Key TheKey(std::make_pair(T, B)); - std::unique_ptr<VarBitInit> &I = ThePool[TheKey]; - if (!I) I.reset(new VarBitInit(T, B)); - return I.get(); + VarBitInit *&I = ThePool[TheKey]; + if (!I) + I = new(Allocator) VarBitInit(T, B); + return I; } Init *VarBitInit::convertInitializerTo(RecTy *Ty) const { @@ -1383,13 +1365,13 @@ Init *VarBitInit::resolveReferences(Record &R, const RecordVal *RV) const { VarListElementInit *VarListElementInit::get(TypedInit *T, unsigned E) { typedef std::pair<TypedInit *, unsigned> Key; - static DenseMap<Key, std::unique_ptr<VarListElementInit>> ThePool; + static DenseMap<Key, VarListElementInit*> ThePool; Key TheKey(std::make_pair(T, E)); - std::unique_ptr<VarListElementInit> &I = ThePool[TheKey]; - if (!I) I.reset(new VarListElementInit(T, E)); - return I.get(); + VarListElementInit *&I = ThePool[TheKey]; + if (!I) I = new(Allocator) VarListElementInit(T, E); + return I; } std::string VarListElementInit::getAsString() const { @@ -1436,31 +1418,30 @@ Init *DefInit::convertInitializerTo(RecTy *Ty) const { return nullptr; } -RecTy *DefInit::getFieldType(const std::string &FieldName) const { +RecTy *DefInit::getFieldType(StringInit *FieldName) const { if (const RecordVal *RV = Def->getValue(FieldName)) return RV->getType(); return nullptr; } Init *DefInit::getFieldInit(Record &R, const RecordVal *RV, - const std::string &FieldName) const { + StringInit *FieldName) const { return Def->getValue(FieldName)->getValue(); } - std::string DefInit::getAsString() const { return Def->getName(); } -FieldInit *FieldInit::get(Init *R, const std::string &FN) { - typedef std::pair<Init *, TableGenStringKey> Key; - static DenseMap<Key, std::unique_ptr<FieldInit>> ThePool; +FieldInit *FieldInit::get(Init *R, StringInit *FN) { + typedef std::pair<Init *, StringInit *> Key; + static DenseMap<Key, FieldInit*> ThePool; Key TheKey(std::make_pair(R, FN)); - std::unique_ptr<FieldInit> &I = ThePool[TheKey]; - if (!I) I.reset(new FieldInit(R, FN)); - return I.get(); + FieldInit *&I = ThePool[TheKey]; + if (!I) I = new(Allocator) FieldInit(R, FN); + return I; } Init *FieldInit::getBit(unsigned Bit) const { @@ -1498,28 +1479,27 @@ Init *FieldInit::resolveReferences(Record &R, const RecordVal *RV) const { return const_cast<FieldInit *>(this); } -static void ProfileDagInit(FoldingSetNodeID &ID, Init *V, const std::string &VN, +static void ProfileDagInit(FoldingSetNodeID &ID, Init *V, StringInit *VN, ArrayRef<Init *> ArgRange, - ArrayRef<std::string> NameRange) { + ArrayRef<StringInit *> NameRange) { ID.AddPointer(V); - ID.AddString(VN); + ID.AddPointer(VN); - ArrayRef<Init *>::iterator Arg = ArgRange.begin(); - ArrayRef<std::string>::iterator Name = NameRange.begin(); + ArrayRef<Init *>::iterator Arg = ArgRange.begin(); + ArrayRef<StringInit *>::iterator Name = NameRange.begin(); while (Arg != ArgRange.end()) { assert(Name != NameRange.end() && "Arg name underflow!"); ID.AddPointer(*Arg++); - ID.AddString(*Name++); + ID.AddPointer(*Name++); } assert(Name == NameRange.end() && "Arg name overflow!"); } DagInit * -DagInit::get(Init *V, const std::string &VN, - ArrayRef<Init *> ArgRange, - ArrayRef<std::string> NameRange) { +DagInit::get(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange, + ArrayRef<StringInit *> NameRange) { static FoldingSet<DagInit> ThePool; - static std::vector<std::unique_ptr<DagInit>> TheActualPool; + static std::vector<DagInit*> TheActualPool; FoldingSetNodeID ID; ProfileDagInit(ID, V, VN, ArgRange, NameRange); @@ -1528,17 +1508,17 @@ DagInit::get(Init *V, const std::string &VN, if (DagInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) return I; - DagInit *I = new DagInit(V, VN, ArgRange, NameRange); + DagInit *I = new(Allocator) DagInit(V, VN, ArgRange, NameRange); ThePool.InsertNode(I, IP); - TheActualPool.push_back(std::unique_ptr<DagInit>(I)); + TheActualPool.push_back(I); return I; } DagInit * -DagInit::get(Init *V, const std::string &VN, - const std::vector<std::pair<Init*, std::string> > &args) { - std::vector<Init *> Args; - std::vector<std::string> Names; +DagInit::get(Init *V, StringInit *VN, + ArrayRef<std::pair<Init*, StringInit*>> args) { + SmallVector<Init *, 8> Args; + SmallVector<StringInit *, 8> Names; for (const auto &Arg : args) { Args.push_back(Arg.first); @@ -1560,52 +1540,54 @@ Init *DagInit::convertInitializerTo(RecTy *Ty) const { } Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) const { - std::vector<Init*> NewArgs; - for (unsigned i = 0, e = Args.size(); i != e; ++i) - NewArgs.push_back(Args[i]->resolveReferences(R, RV)); + SmallVector<Init*, 8> NewArgs; + NewArgs.reserve(Args.size()); + bool ArgsChanged = false; + for (const Init *Arg : Args) { + Init *NewArg = Arg->resolveReferences(R, RV); + NewArgs.push_back(NewArg); + ArgsChanged |= NewArg != Arg; + } Init *Op = Val->resolveReferences(R, RV); - - if (Args != NewArgs || Op != Val) + if (Op != Val || ArgsChanged) return DagInit::get(Op, ValName, NewArgs, ArgNames); return const_cast<DagInit *>(this); } - std::string DagInit::getAsString() const { std::string Result = "(" + Val->getAsString(); - if (!ValName.empty()) - Result += ":" + ValName; + if (ValName) + Result += ":" + ValName->getAsUnquotedString(); if (!Args.empty()) { Result += " " + Args[0]->getAsString(); - if (!ArgNames[0].empty()) Result += ":$" + ArgNames[0]; + if (ArgNames[0]) Result += ":$" + ArgNames[0]->getAsUnquotedString(); for (unsigned i = 1, e = Args.size(); i != e; ++i) { Result += ", " + Args[i]->getAsString(); - if (!ArgNames[i].empty()) Result += ":$" + ArgNames[i]; + if (ArgNames[i]) Result += ":$" + ArgNames[i]->getAsUnquotedString(); } } return Result + ")"; } - //===----------------------------------------------------------------------===// // Other implementations //===----------------------------------------------------------------------===// RecordVal::RecordVal(Init *N, RecTy *T, bool P) - : NameAndPrefix(N, P), Ty(T) { - Value = UnsetInit::get()->convertInitializerTo(Ty); + : Name(N), TyAndPrefix(T, P) { + Value = UnsetInit::get()->convertInitializerTo(T); assert(Value && "Cannot create unset value for current type!"); } -RecordVal::RecordVal(const std::string &N, RecTy *T, bool P) - : NameAndPrefix(StringInit::get(N), P), Ty(T) { - Value = UnsetInit::get()->convertInitializerTo(Ty); +RecordVal::RecordVal(StringRef N, RecTy *T, bool P) + : Name(StringInit::get(N)), TyAndPrefix(T, P) { + Value = UnsetInit::get()->convertInitializerTo(T); assert(Value && "Cannot create unset value for current type!"); } -const std::string &RecordVal::getName() const { +StringRef RecordVal::getName() const { return cast<StringInit>(getNameInit())->getValue(); } @@ -1628,7 +1610,7 @@ void Record::init() { // Every record potentially has a def at the top. This value is // replaced with the top-level def name at instantiation time. - RecordVal DN("NAME", StringRecTy::get(), 0); + RecordVal DN("NAME", StringRecTy::get(), false); addValue(DN); } @@ -1641,11 +1623,11 @@ void Record::checkName() { DefInit *Record::getDefInit() { if (!TheInit) - TheInit.reset(new DefInit(this, new RecordRecTy(this))); - return TheInit.get(); + TheInit = new(Allocator) DefInit(this, new(Allocator) RecordRecTy(this)); + return TheInit; } -const std::string &Record::getName() const { +StringRef Record::getName() const { return cast<StringInit>(Name)->getValue(); } @@ -1665,18 +1647,18 @@ void Record::setName(Init *NewName) { // this. See TGParser::ParseDef and TGParser::ParseDefm. } -void Record::setName(const std::string &Name) { +void Record::setName(StringRef Name) { setName(StringInit::get(Name)); } void Record::resolveReferencesTo(const RecordVal *RV) { - for (unsigned i = 0, e = Values.size(); i != e; ++i) { - if (RV == &Values[i]) // Skip resolve the same field as the given one + for (RecordVal &Value : Values) { + if (RV == &Value) // Skip resolve the same field as the given one continue; - if (Init *V = Values[i].getValue()) - if (Values[i].setValue(V->resolveReferences(*this, RV))) + if (Init *V = Value.getValue()) + if (Value.setValue(V->resolveReferences(*this, RV))) PrintFatalError(getLoc(), "Invalid value is found when setting '" + - Values[i].getNameInitAsString() + + Value.getNameInitAsString() + "' after resolving references" + (RV ? " against '" + RV->getNameInitAsString() + "' of (" + RV->getValue()->getAsUnquotedString() + @@ -1720,10 +1702,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.getName())) + if (Val.getPrefix() && !R.isTemplateArg(Val.getNameInit())) OS << Val; for (const RecordVal &Val : R.getValues()) - if (!Val.getPrefix() && !R.isTemplateArg(Val.getName())) + if (!Val.getPrefix() && !R.isTemplateArg(Val.getNameInit())) OS << Val; return OS << "}\n"; @@ -1737,7 +1719,6 @@ Init *Record::getValueInit(StringRef FieldName) const { return R->getValue(); } - std::string Record::getValueAsString(StringRef FieldName) const { const RecordVal *R = getValue(FieldName); if (!R || !R->getValue()) @@ -1884,7 +1865,6 @@ DagInit *Record::getValueAsDag(StringRef FieldName) const { FieldName + "' does not have a dag initializer!"); } - LLVM_DUMP_METHOD void MultiClass::dump() const { errs() << "Record:\n"; Rec.dump(); @@ -1894,7 +1874,6 @@ LLVM_DUMP_METHOD void MultiClass::dump() const { Proto->dump(); } - LLVM_DUMP_METHOD void RecordKeeper::dump() const { errs() << *this; } raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) { @@ -1909,7 +1888,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) { } std::vector<Record *> -RecordKeeper::getAllDerivedDefinitions(const std::string &ClassName) const { +RecordKeeper::getAllDerivedDefinitions(StringRef ClassName) const { Record *Class = getClass(ClassName); if (!Class) PrintFatalError("ERROR: Couldn't find the `" + ClassName + "' class!\n"); @@ -1922,35 +1901,25 @@ RecordKeeper::getAllDerivedDefinitions(const std::string &ClassName) const { return Defs; } -Init *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass, - Init *Name, const std::string &Scoper) { - RecTy *Type = cast<TypedInit>(Name)->getType(); - - BinOpInit *NewName = - BinOpInit::get(BinOpInit::STRCONCAT, - BinOpInit::get(BinOpInit::STRCONCAT, - CurRec.getNameInit(), - StringInit::get(Scoper), - Type)->Fold(&CurRec, CurMultiClass), - Name, - Type); +static Init *GetStrConcat(Init *I0, Init *I1) { + // Shortcut for the common case of concatenating two strings. + if (const StringInit *I0s = dyn_cast<StringInit>(I0)) + if (const StringInit *I1s = dyn_cast<StringInit>(I1)) + return ConcatStringInits(I0s, I1s); + return BinOpInit::get(BinOpInit::STRCONCAT, I0, I1, StringRecTy::get()); +} +Init *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass, + Init *Name, StringRef Scoper) { + Init *NewName = GetStrConcat(CurRec.getNameInit(), StringInit::get(Scoper)); + NewName = GetStrConcat(NewName, Name); if (CurMultiClass && Scoper != "::") { - NewName = - BinOpInit::get(BinOpInit::STRCONCAT, - BinOpInit::get(BinOpInit::STRCONCAT, - CurMultiClass->Rec.getNameInit(), - StringInit::get("::"), - Type)->Fold(&CurRec, CurMultiClass), - NewName->Fold(&CurRec, CurMultiClass), - Type); + Init *Prefix = GetStrConcat(CurMultiClass->Rec.getNameInit(), + StringInit::get("::")); + NewName = GetStrConcat(Prefix, NewName); } - return NewName->Fold(&CurRec, CurMultiClass); -} - -Init *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass, - const std::string &Name, - const std::string &Scoper) { - return QualifyName(CurRec, CurMultiClass, StringInit::get(Name), Scoper); + if (BinOpInit *BinOp = dyn_cast<BinOpInit>(NewName)) + NewName = BinOp->Fold(&CurRec, CurMultiClass); + return NewName; } diff --git a/lib/TableGen/TGLexer.cpp b/lib/TableGen/TGLexer.cpp index 63b85842d6a9..5d6f7c23e0b6 100644 --- a/lib/TableGen/TGLexer.cpp +++ b/lib/TableGen/TGLexer.cpp @@ -15,11 +15,13 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "llvm/Config/config.h" // for strtoull()/strtoll() define +#include "llvm/Support/Compiler.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/TableGen/Error.h" #include <cctype> #include <cerrno> +#include <cstdint> #include <cstdio> #include <cstdlib> #include <cstring> @@ -155,7 +157,7 @@ tgtok::TokKind TGLexer::LexToken() { case '0': case '1': if (NextChar == 'b') return LexNumber(); - // Fallthrough + LLVM_FALLTHROUGH; case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': @@ -222,7 +224,7 @@ tgtok::TokKind TGLexer::LexString() { case '\0': if (CurPtr == CurBuf.end()) return ReturnError(StrStart, "End of file in string literal"); - // FALL THROUGH + LLVM_FALLTHROUGH; default: return ReturnError(CurPtr, "invalid escape in string literal"); } @@ -246,7 +248,6 @@ tgtok::TokKind TGLexer::LexVarName() { return tgtok::VarName; } - tgtok::TokKind TGLexer::LexIdentifier() { // The first letter is [a-zA-Z_#]. const char *IdentStart = TokStart; @@ -301,7 +302,6 @@ bool TGLexer::LexInclude() { std::string Filename = CurStrVal; std::string IncludedFile; - CurBuffer = SrcMgr.AddIncludeFile(Filename, SMLoc::getFromPointer(CurPtr), IncludedFile); if (!CurBuffer) { @@ -326,7 +326,7 @@ bool TGLexer::LexInclude() { void TGLexer::SkipBCPLComment() { ++CurPtr; // skip the second slash. - while (1) { + while (true) { switch (*CurPtr) { case '\n': case '\r': @@ -348,7 +348,7 @@ bool TGLexer::SkipCComment() { ++CurPtr; // skip the star. unsigned CommentDepth = 1; - while (1) { + while (true) { int CurChar = getNextChar(); switch (CurChar) { case EOF: @@ -436,7 +436,7 @@ tgtok::TokKind TGLexer::LexBracket() { return tgtok::l_square; ++CurPtr; const char *CodeStart = CurPtr; - while (1) { + while (true) { int Char = getNextChar(); if (Char == EOF) break; @@ -472,6 +472,7 @@ tgtok::TokKind TGLexer::LexExclaim() { .Case("con", tgtok::XConcat) .Case("add", tgtok::XADD) .Case("and", tgtok::XAND) + .Case("or", tgtok::XOR) .Case("shl", tgtok::XSHL) .Case("sra", tgtok::XSRA) .Case("srl", tgtok::XSRL) @@ -485,4 +486,3 @@ tgtok::TokKind TGLexer::LexExclaim() { return Kind != tgtok::Error ? Kind : ReturnError(Start-1, "Unknown operator"); } - diff --git a/lib/TableGen/TGLexer.h b/lib/TableGen/TGLexer.h index cbc30be8a572..b5b58161878b 100644 --- a/lib/TableGen/TGLexer.h +++ b/lib/TableGen/TGLexer.h @@ -45,9 +45,9 @@ namespace tgtok { // Keywords. Bit, Bits, Class, Code, Dag, Def, Foreach, Defm, Field, In, Int, Let, List, MultiClass, String, - + // !keywords. - XConcat, XADD, XAND, XSRA, XSRL, XSHL, XListConcat, XStrConcat, XCast, + XConcat, XADD, XAND, XOR, XSRA, XSRL, XSHL, XListConcat, XStrConcat, XCast, XSubst, XForEach, XHead, XTail, XEmpty, XIf, XEq, // Integer value. diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp index 34e90925e929..1a91b37b742b 100644 --- a/lib/TableGen/TGParser.cpp +++ b/lib/TableGen/TGParser.cpp @@ -12,11 +12,19 @@ //===----------------------------------------------------------------------===// #include "TGParser.h" +#include "llvm/ADT/None.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/TableGen/Record.h" #include <algorithm> +#include <cassert> +#include <cstdint> + using namespace llvm; //===----------------------------------------------------------------------===// @@ -24,10 +32,12 @@ using namespace llvm; //===----------------------------------------------------------------------===// namespace llvm { + struct SubClassReference { SMRange RefRange; Record *Rec; - std::vector<Init*> TemplateArgs; + SmallVector<Init*, 4> TemplateArgs; + SubClassReference() : Rec(nullptr) {} bool isInvalid() const { return Rec == nullptr; } @@ -36,7 +46,8 @@ struct SubClassReference { struct SubMultiClassReference { SMRange RefRange; MultiClass *MC; - std::vector<Init*> TemplateArgs; + SmallVector<Init*, 4> TemplateArgs; + SubMultiClassReference() : MC(nullptr) {} bool isInvalid() const { return MC == nullptr; } @@ -130,7 +141,7 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName, } if (RV->setValue(V)) { - std::string InitType = ""; + std::string InitType; if (BitsInit *BI = dyn_cast<BitsInit>(V)) InitType = (Twine("' of type bit initializer with length ") + Twine(BI->getNumBits())).str(); @@ -328,14 +339,14 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){ IterRec->addValue(RecordVal(IterVar->getName(), IVal->getType(), false)); - if (SetValue(IterRec.get(), Loc, IterVar->getName(), None, IVal)) + if (SetValue(IterRec.get(), Loc, IterVar->getNameInit(), None, IVal)) return Error(Loc, "when instantiating this def"); // Resolve it next. - IterRec->resolveReferencesTo(IterRec->getValue(IterVar->getName())); + IterRec->resolveReferencesTo(IterRec->getValue(IterVar->getNameInit())); // Remove it. - IterRec->removeValue(IterVar->getName()); + IterRec->removeValue(IterVar->getNameInit()); } if (Records.getDef(IterRec->getNameInitAsString())) { @@ -474,7 +485,7 @@ ParseSubClassReference(Record *CurRec, bool isDefm) { return Result; } - Result.TemplateArgs = ParseValueList(CurRec, Result.Rec); + ParseValueList(Result.TemplateArgs, CurRec, Result.Rec); if (Result.TemplateArgs.empty()) { Result.Rec = nullptr; // Error parsing value list. return Result; @@ -519,7 +530,7 @@ ParseSubMultiClassReference(MultiClass *CurMC) { return Result; } - Result.TemplateArgs = ParseValueList(&CurMC->Rec, &Result.MC->Rec); + ParseValueList(Result.TemplateArgs, &CurMC->Rec, &Result.MC->Rec); if (Result.TemplateArgs.empty()) { Result.MC = nullptr; // Error parsing value list. return Result; @@ -540,7 +551,7 @@ ParseSubMultiClassReference(MultiClass *CurMC) { /// RangePiece ::= INTVAL /// RangePiece ::= INTVAL '-' INTVAL /// RangePiece ::= INTVAL INTVAL -bool TGParser::ParseRangePiece(std::vector<unsigned> &Ranges) { +bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges) { if (Lex.getCode() != tgtok::IntVal) { TokError("expected integer or bitrange"); return true; @@ -584,26 +595,27 @@ bool TGParser::ParseRangePiece(std::vector<unsigned> &Ranges) { /// /// RangeList ::= RangePiece (',' RangePiece)* /// -std::vector<unsigned> TGParser::ParseRangeList() { - std::vector<unsigned> Result; - +void TGParser::ParseRangeList(SmallVectorImpl<unsigned> &Result) { // Parse the first piece. - if (ParseRangePiece(Result)) - return std::vector<unsigned>(); + if (ParseRangePiece(Result)) { + Result.clear(); + return; + } while (Lex.getCode() == tgtok::comma) { Lex.Lex(); // Eat the comma. // Parse the next range piece. - if (ParseRangePiece(Result)) - return std::vector<unsigned>(); + if (ParseRangePiece(Result)) { + Result.clear(); + return; + } } - return Result; } /// ParseOptionalRangeList - Parse either a range list in <>'s or nothing. /// OptionalRangeList ::= '<' RangeList '>' /// OptionalRangeList ::= /*empty*/ -bool TGParser::ParseOptionalRangeList(std::vector<unsigned> &Ranges) { +bool TGParser::ParseOptionalRangeList(SmallVectorImpl<unsigned> &Ranges) { if (Lex.getCode() != tgtok::less) return false; @@ -611,7 +623,7 @@ bool TGParser::ParseOptionalRangeList(std::vector<unsigned> &Ranges) { Lex.Lex(); // eat the '<' // Parse the range list. - Ranges = ParseRangeList(); + ParseRangeList(Ranges); if (Ranges.empty()) return true; if (Lex.getCode() != tgtok::greater) { @@ -625,7 +637,7 @@ bool TGParser::ParseOptionalRangeList(std::vector<unsigned> &Ranges) { /// ParseOptionalBitList - Parse either a bit list in {}'s or nothing. /// OptionalBitList ::= '{' RangeList '}' /// OptionalBitList ::= /*empty*/ -bool TGParser::ParseOptionalBitList(std::vector<unsigned> &Ranges) { +bool TGParser::ParseOptionalBitList(SmallVectorImpl<unsigned> &Ranges) { if (Lex.getCode() != tgtok::l_brace) return false; @@ -633,7 +645,7 @@ bool TGParser::ParseOptionalBitList(std::vector<unsigned> &Ranges) { Lex.Lex(); // eat the '{' // Parse the range list. - Ranges = ParseRangeList(); + ParseRangeList(Ranges); if (Ranges.empty()) return true; if (Lex.getCode() != tgtok::r_brace) { @@ -644,7 +656,6 @@ bool TGParser::ParseOptionalBitList(std::vector<unsigned> &Ranges) { return false; } - /// ParseType - Parse and return a tblgen type. This returns null on error. /// /// Type ::= STRING // string type @@ -705,8 +716,7 @@ RecTy *TGParser::ParseType() { /// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID /// has already been read. -Init *TGParser::ParseIDValue(Record *CurRec, - const std::string &Name, SMLoc NameLoc, +Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMLoc NameLoc, IDParseMode Mode) { if (CurRec) { if (const RecordVal *RV = CurRec->getValue(Name)) @@ -726,8 +736,7 @@ Init *TGParser::ParseIDValue(Record *CurRec, } if (CurMultiClass) { - Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, - "::"); + Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, "::"); if (CurMultiClass->Rec.isTemplateArg(MCName)) { const RecordVal *RV = CurMultiClass->Rec.getValue(MCName); @@ -739,22 +748,22 @@ Init *TGParser::ParseIDValue(Record *CurRec, // If this is in a foreach loop, make sure it's not a loop iterator for (const auto &L : Loops) { VarInit *IterVar = dyn_cast<VarInit>(L.IterVar); - if (IterVar && IterVar->getName() == Name) + if (IterVar && IterVar->getNameInit() == Name) return IterVar; } if (Mode == ParseNameMode) - return StringInit::get(Name); + return Name; - if (Record *D = Records.getDef(Name)) + if (Record *D = Records.getDef(Name->getValue())) return DefInit::get(D); if (Mode == ParseValueMode) { - Error(NameLoc, "Variable not defined: '" + Name + "'"); + Error(NameLoc, "Variable not defined: '" + Name->getValue() + "'"); return nullptr; } - return StringInit::get(Name); + return Name; } /// ParseOperation - Parse an operator. This returns null on error. @@ -871,6 +880,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { case tgtok::XConcat: case tgtok::XADD: case tgtok::XAND: + case tgtok::XOR: case tgtok::XSRA: case tgtok::XSRL: case tgtok::XSHL: @@ -889,6 +899,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { case tgtok::XConcat: Code = BinOpInit::CONCAT;Type = DagRecTy::get(); break; case tgtok::XADD: Code = BinOpInit::ADD; Type = IntRecTy::get(); break; case tgtok::XAND: Code = BinOpInit::AND; Type = IntRecTy::get(); break; + case tgtok::XOR: Code = BinOpInit::OR; Type = IntRecTy::get(); break; case tgtok::XSRA: Code = BinOpInit::SRA; Type = IntRecTy::get(); break; case tgtok::XSRL: Code = BinOpInit::SRL; Type = IntRecTy::get(); break; case tgtok::XSHL: Code = BinOpInit::SHL; Type = IntRecTy::get(); break; @@ -1110,7 +1121,6 @@ RecTy *TGParser::ParseOperatorType() { return Type; } - /// ParseSimpleValue - Parse a tblgen value. This returns null on error. /// /// SimpleValue ::= IDValue @@ -1173,7 +1183,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, break; case tgtok::Id: { SMLoc NameLoc = Lex.getLoc(); - std::string Name = Lex.getCurStrVal(); + StringInit *Name = StringInit::get(Lex.getCurStrVal()); if (Lex.Lex() != tgtok::less) // consume the Id. return ParseIDValue(CurRec, Name, NameLoc, Mode); // Value ::= IDValue @@ -1186,14 +1196,15 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, // This is a CLASS<initvalslist> expression. This is supposed to synthesize // a new anonymous definition, deriving from CLASS<initvalslist> with no // body. - Record *Class = Records.getClass(Name); + Record *Class = Records.getClass(Name->getValue()); if (!Class) { - Error(NameLoc, "Expected a class name, got '" + Name + "'"); + Error(NameLoc, "Expected a class name, got '" + Name->getValue() + "'"); return nullptr; } - std::vector<Init*> ValueList = ParseValueList(CurRec, Class); - if (ValueList.empty()) return nullptr; + SubClassReference SCRef; + ParseValueList(SCRef.TemplateArgs, CurRec, Class); + if (SCRef.TemplateArgs.empty()) return nullptr; if (Lex.getCode() != tgtok::greater) { TokError("expected '>' at end of value list"); @@ -1206,10 +1217,8 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, auto NewRecOwner = llvm::make_unique<Record>(GetNewAnonymousName(), NameLoc, Records, /*IsAnonymous=*/true); Record *NewRec = NewRecOwner.get(); // Keep a copy since we may release. - SubClassReference SCRef; SCRef.RefRange = SMRange(NameLoc, EndLoc); SCRef.Rec = Class; - SCRef.TemplateArgs = ValueList; // Add info about the subclass to NewRec. if (AddSubClass(NewRec, SCRef)) return nullptr; @@ -1251,10 +1260,10 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, case tgtok::l_brace: { // Value ::= '{' ValueList '}' SMLoc BraceLoc = Lex.getLoc(); Lex.Lex(); // eat the '{' - std::vector<Init*> Vals; + SmallVector<Init*, 16> Vals; if (Lex.getCode() != tgtok::r_brace) { - Vals = ParseValueList(CurRec); + ParseValueList(Vals, CurRec); if (Vals.empty()) return nullptr; } if (Lex.getCode() != tgtok::r_brace) { @@ -1301,7 +1310,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, } case tgtok::l_square: { // Value ::= '[' ValueList ']' Lex.Lex(); // eat the '[' - std::vector<Init*> Vals; + SmallVector<Init*, 16> Vals; RecTy *DeducedEltTy = nullptr; ListRecTy *GivenListTy = nullptr; @@ -1317,8 +1326,8 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, } if (Lex.getCode() != tgtok::r_square) { - Vals = ParseValueList(CurRec, nullptr, - GivenListTy ? GivenListTy->getElementType() : nullptr); + ParseValueList(Vals, CurRec, nullptr, + GivenListTy ? GivenListTy->getElementType() : nullptr); if (Vals.empty()) return nullptr; } if (Lex.getCode() != tgtok::r_square) { @@ -1405,19 +1414,19 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, if (!Operator) return nullptr; // If the operator name is present, parse it. - std::string OperatorName; + StringInit *OperatorName = nullptr; if (Lex.getCode() == tgtok::colon) { if (Lex.Lex() != tgtok::VarName) { // eat the ':' TokError("expected variable name in dag operator"); return nullptr; } - OperatorName = Lex.getCurStrVal(); + OperatorName = StringInit::get(Lex.getCurStrVal()); Lex.Lex(); // eat the VarName. } - std::vector<std::pair<llvm::Init*, std::string> > DagArgs; + SmallVector<std::pair<llvm::Init*, StringInit*>, 8> DagArgs; if (Lex.getCode() != tgtok::r_paren) { - DagArgs = ParseDagArgList(CurRec); + ParseDagArgList(DagArgs, CurRec); if (DagArgs.empty()) return nullptr; } @@ -1437,6 +1446,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, case tgtok::XConcat: case tgtok::XADD: case tgtok::XAND: + case tgtok::XOR: case tgtok::XSRA: case tgtok::XSRL: case tgtok::XSHL: @@ -1465,7 +1475,7 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) { if (!Result) return nullptr; // Parse the suffixes now if present. - while (1) { + while (true) { switch (Lex.getCode()) { default: return Result; case tgtok::l_brace: { @@ -1475,7 +1485,8 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) { SMLoc CurlyLoc = Lex.getLoc(); Lex.Lex(); // eat the '{' - std::vector<unsigned> Ranges = ParseRangeList(); + SmallVector<unsigned, 16> Ranges; + ParseRangeList(Ranges); if (Ranges.empty()) return nullptr; // Reverse the bitlist. @@ -1497,7 +1508,8 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) { case tgtok::l_square: { SMLoc SquareLoc = Lex.getLoc(); Lex.Lex(); // eat the '[' - std::vector<unsigned> Ranges = ParseRangeList(); + SmallVector<unsigned, 16> Ranges; + ParseRangeList(Ranges); if (Ranges.empty()) return nullptr; Result = Result->convertInitListSlice(Ranges); @@ -1514,19 +1526,21 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) { Lex.Lex(); break; } - case tgtok::period: + case tgtok::period: { if (Lex.Lex() != tgtok::Id) { // eat the . TokError("expected field identifier after '.'"); return nullptr; } - if (!Result->getFieldType(Lex.getCurStrVal())) { + StringInit *FieldName = StringInit::get(Lex.getCurStrVal()); + if (!Result->getFieldType(FieldName)) { TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" + Result->getAsString() + "'"); return nullptr; } - Result = FieldInit::get(Result, Lex.getCurStrVal()); + Result = FieldInit::get(Result, FieldName); Lex.Lex(); // eat field name break; + } case tgtok::paste: SMLoc PasteLoc = Lex.getLoc(); @@ -1587,30 +1601,34 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) { /// DagArg ::= VARNAME /// DagArgList ::= DagArg /// DagArgList ::= DagArgList ',' DagArg -std::vector<std::pair<llvm::Init*, std::string> > -TGParser::ParseDagArgList(Record *CurRec) { - std::vector<std::pair<llvm::Init*, std::string> > Result; +void TGParser::ParseDagArgList( + SmallVectorImpl<std::pair<llvm::Init*, StringInit*>> &Result, + Record *CurRec) { - while (1) { + while (true) { // DagArg ::= VARNAME if (Lex.getCode() == tgtok::VarName) { // A missing value is treated like '?'. - Result.emplace_back(UnsetInit::get(), Lex.getCurStrVal()); + StringInit *VarName = StringInit::get(Lex.getCurStrVal()); + Result.emplace_back(UnsetInit::get(), VarName); Lex.Lex(); } else { // DagArg ::= Value (':' VARNAME)? Init *Val = ParseValue(CurRec); - if (!Val) - return std::vector<std::pair<llvm::Init*, std::string> >(); + if (!Val) { + Result.clear(); + return; + } // If the variable name is present, add it. - std::string VarName; + StringInit *VarName = nullptr; if (Lex.getCode() == tgtok::colon) { if (Lex.Lex() != tgtok::VarName) { // eat the ':' TokError("expected variable name in dag literal"); - return std::vector<std::pair<llvm::Init*, std::string> >(); + Result.clear(); + return; } - VarName = Lex.getCurStrVal(); + VarName = StringInit::get(Lex.getCurStrVal()); Lex.Lex(); // eat the VarName. } @@ -1619,27 +1637,24 @@ TGParser::ParseDagArgList(Record *CurRec) { if (Lex.getCode() != tgtok::comma) break; Lex.Lex(); // eat the ',' } - - return Result; } - /// ParseValueList - Parse a comma separated list of values, returning them as a /// vector. Note that this always expects to be able to parse at least one /// value. It returns an empty list if this is not possible. /// /// ValueList ::= Value (',' Value) /// -std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, - RecTy *EltTy) { - std::vector<Init*> Result; +void TGParser::ParseValueList(SmallVectorImpl<Init*> &Result, Record *CurRec, + Record *ArgsRec, RecTy *EltTy) { RecTy *ItemType = EltTy; unsigned int ArgN = 0; if (ArgsRec && !EltTy) { ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs(); if (TArgs.empty()) { TokError("template argument provided to non-template class"); - return std::vector<Init*>(); + Result.clear(); + return; } const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]); if (!RV) { @@ -1651,7 +1666,10 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, ++ArgN; } Result.push_back(ParseValue(CurRec, ItemType)); - if (!Result.back()) return std::vector<Init*>(); + if (!Result.back()) { + Result.clear(); + return; + } while (Lex.getCode() == tgtok::comma) { Lex.Lex(); // Eat the comma @@ -1660,7 +1678,8 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs(); if (ArgN >= TArgs.size()) { TokError("too many template arguments"); - return std::vector<Init*>(); + Result.clear(); + return; } const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]); assert(RV && "Template argument record not found??"); @@ -1668,13 +1687,13 @@ std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, ++ArgN; } Result.push_back(ParseValue(CurRec, ItemType)); - if (!Result.back()) return std::vector<Init*>(); + if (!Result.back()) { + Result.clear(); + return; + } } - - return Result; } - /// ParseDeclaration - Read a declaration, returning the name of field ID, or an /// empty string on error. This can happen in a number of different context's, /// including within a def or in the template args for a def (which which case @@ -1758,7 +1777,7 @@ VarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) { Lex.Lex(); // Eat the '=' RecTy *IterType = nullptr; - std::vector<unsigned> Ranges; + SmallVector<unsigned, 16> Ranges; switch (Lex.getCode()) { default: TokError("Unknown token when expecting a range list"); return nullptr; @@ -1787,7 +1806,7 @@ VarInit *TGParser::ParseForeachDeclaration(ListInit *&ForeachListValue) { case tgtok::l_brace: { // '{' RangeList '}' Lex.Lex(); // eat the '{' - Ranges = ParseRangeList(); + ParseRangeList(Ranges); if (Lex.getCode() != tgtok::r_brace) { TokError("expected '}' at end of bit range list"); return nullptr; @@ -1848,7 +1867,6 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) { return false; } - /// ParseBodyItem - Parse a single item at within the body of a def or class. /// /// BodyItem ::= Declaration ';' @@ -1869,10 +1887,10 @@ bool TGParser::ParseBodyItem(Record *CurRec) { return TokError("expected field identifier after let"); SMLoc IdLoc = Lex.getLoc(); - std::string FieldName = Lex.getCurStrVal(); + StringInit *FieldName = StringInit::get(Lex.getCurStrVal()); Lex.Lex(); // eat the field name. - std::vector<unsigned> BitList; + SmallVector<unsigned, 16> BitList; if (ParseOptionalBitList(BitList)) return true; std::reverse(BitList.begin(), BitList.end()); @@ -1883,7 +1901,7 @@ bool TGParser::ParseBodyItem(Record *CurRec) { RecordVal *Field = CurRec->getValue(FieldName); if (!Field) - return TokError("Value '" + FieldName + "' unknown!"); + return TokError("Value '" + FieldName->getValue() + "' unknown!"); RecTy *Type = Field->getType(); @@ -1928,7 +1946,7 @@ bool TGParser::ParseBody(Record *CurRec) { /// \brief Apply the current let bindings to \a CurRec. /// \returns true on error, false otherwise. bool TGParser::ApplyLetStack(Record *CurRec) { - for (std::vector<LetRecord> &LetInfo : LetStack) + for (SmallVectorImpl<LetRecord> &LetInfo : LetStack) for (LetRecord &LR : LetInfo) if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value)) return true; @@ -1951,7 +1969,7 @@ bool TGParser::ParseObjectBody(Record *CurRec) { // Read all of the subclasses. SubClassReference SubClass = ParseSubClassReference(CurRec, false); - while (1) { + while (true) { // Check for error. if (!SubClass.Rec) return true; @@ -2139,38 +2157,44 @@ bool TGParser::ParseClass() { /// LetList ::= LetItem (',' LetItem)* /// LetItem ::= ID OptionalRangeList '=' Value /// -std::vector<LetRecord> TGParser::ParseLetList() { - std::vector<LetRecord> Result; - - while (1) { +void TGParser::ParseLetList(SmallVectorImpl<LetRecord> &Result) { + while (true) { if (Lex.getCode() != tgtok::Id) { TokError("expected identifier in let definition"); - return std::vector<LetRecord>(); + Result.clear(); + return; } - std::string Name = Lex.getCurStrVal(); + + StringInit *Name = StringInit::get(Lex.getCurStrVal()); SMLoc NameLoc = Lex.getLoc(); Lex.Lex(); // Eat the identifier. // Check for an optional RangeList. - std::vector<unsigned> Bits; - if (ParseOptionalRangeList(Bits)) - return std::vector<LetRecord>(); + SmallVector<unsigned, 16> Bits; + if (ParseOptionalRangeList(Bits)) { + Result.clear(); + return; + } std::reverse(Bits.begin(), Bits.end()); if (Lex.getCode() != tgtok::equal) { TokError("expected '=' in let expression"); - return std::vector<LetRecord>(); + Result.clear(); + return; } Lex.Lex(); // eat the '='. Init *Val = ParseValue(nullptr); - if (!Val) return std::vector<LetRecord>(); + if (!Val) { + Result.clear(); + return; + } // Now that we have everything, add the record. - Result.emplace_back(std::move(Name), std::move(Bits), Val, NameLoc); + Result.emplace_back(Name, Bits, Val, NameLoc); if (Lex.getCode() != tgtok::comma) - return Result; + return; Lex.Lex(); // eat the comma. } } @@ -2186,7 +2210,8 @@ bool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) { Lex.Lex(); // Add this entry to the let stack. - std::vector<LetRecord> LetInfo = ParseLetList(); + SmallVector<LetRecord, 8> LetInfo; + ParseLetList(LetInfo); if (LetInfo.empty()) return true; LetStack.push_back(std::move(LetInfo)); @@ -2264,7 +2289,7 @@ bool TGParser::ParseMultiClass() { // Read all of the submulticlasses. SubMultiClassReference SubMultiClass = ParseSubMultiClassReference(CurMultiClass); - while (1) { + while (true) { // Check for error. if (!SubMultiClass.MC) return true; @@ -2312,7 +2337,7 @@ Record *TGParser::InstantiateMulticlassDef(MultiClass &MC, Record *DefProto, Init *&DefmPrefix, SMRange DefmPrefixRange, ArrayRef<Init *> TArgs, - std::vector<Init *> &TemplateVals) { + ArrayRef<Init *> TemplateVals) { // We need to preserve DefProto so it can be reused for later // instantiations, so create a new Record to inherit from it. @@ -2353,8 +2378,8 @@ Record *TGParser::InstantiateMulticlassDef(MultiClass &MC, Record *DefProto, // Set the value for NAME. We don't resolve references to it 'til later, // though, so that uses in nested multiclass names don't get // confused. - if (SetValue(CurRec.get(), Ref.RefRange.Start, "NAME", None, DefmPrefix, - /*AllowSelfAssignment*/true)) { + if (SetValue(CurRec.get(), Ref.RefRange.Start, StringInit::get("NAME"), None, + DefmPrefix, /*AllowSelfAssignment*/true)) { Error(DefmPrefixRange.Start, "Could not resolve " + CurRec->getNameInitAsString() + ":NAME to '" + DefmPrefix->getAsUnquotedString() + "'"); @@ -2433,7 +2458,7 @@ Record *TGParser::InstantiateMulticlassDef(MultiClass &MC, Record *DefProto, bool TGParser::ResolveMulticlassDefArgs(MultiClass &MC, Record *CurRec, SMLoc DefmPrefixLoc, SMLoc SubClassLoc, ArrayRef<Init *> TArgs, - std::vector<Init *> &TemplateVals, + ArrayRef<Init *> TemplateVals, bool DeleteArgs) { // Loop over all of the template arguments, setting them to the specified // value or leaving them as the default if necessary. @@ -2519,7 +2544,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) { SMLoc SubClassLoc = Lex.getLoc(); SubClassReference Ref = ParseSubClassReference(nullptr, true); - while (1) { + while (true) { if (!Ref.Rec) return true; // To instantiate a multiclass, we need to first get the multiclass, then @@ -2527,7 +2552,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) { // template parameters. MultiClass *MC = MultiClasses[Ref.Rec->getName()].get(); assert(MC && "Didn't lookup multiclass correctly?"); - std::vector<Init*> &TemplateVals = Ref.TemplateArgs; + ArrayRef<Init*> TemplateVals = Ref.TemplateArgs; // Verify that the correct number of template arguments were specified. ArrayRef<Init *> TArgs = MC->Rec.getTemplateArgs(); @@ -2589,7 +2614,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) { // Process all the classes to inherit as if they were part of a // regular 'def' and inherit all record values. SubClassReference SubClass = ParseSubClassReference(nullptr, false); - while (1) { + while (true) { // Check for error. if (!SubClass.Rec) return true; @@ -2664,4 +2689,3 @@ bool TGParser::ParseFile() { return TokError("Unexpected input at top level"); } - diff --git a/lib/TableGen/TGParser.h b/lib/TableGen/TGParser.h index 739d9a9c5f37..76f7d8fe5026 100644 --- a/lib/TableGen/TGParser.h +++ b/lib/TableGen/TGParser.h @@ -32,12 +32,11 @@ namespace llvm { struct SubMultiClassReference; struct LetRecord { - std::string Name; + StringInit *Name; std::vector<unsigned> Bits; Init *Value; SMLoc Loc; - LetRecord(const std::string &N, const std::vector<unsigned> &B, Init *V, - SMLoc L) + LetRecord(StringInit *N, ArrayRef<unsigned> B, Init *V, SMLoc L) : Name(N), Bits(B), Value(V), Loc(L) { } }; @@ -54,7 +53,7 @@ namespace llvm { class TGParser { TGLexer Lex; - std::vector<std::vector<LetRecord> > LetStack; + std::vector<SmallVector<LetRecord, 4>> LetStack; std::map<std::string, std::unique_ptr<MultiClass>> MultiClasses; /// Loops - Keep track of any foreach loops we are within. @@ -107,12 +106,6 @@ private: // Semantic analysis methods. bool SetValue(Record *TheRec, SMLoc Loc, Init *ValName, ArrayRef<unsigned> BitList, Init *V, bool AllowSelfAssignment = false); - bool SetValue(Record *TheRec, SMLoc Loc, const std::string &ValName, - ArrayRef<unsigned> BitList, Init *V, - bool AllowSelfAssignment = false) { - return SetValue(TheRec, Loc, StringInit::get(ValName), BitList, V, - AllowSelfAssignment); - } bool AddSubClass(Record *Rec, SubClassReference &SubClass); bool AddSubMultiClass(MultiClass *CurMC, SubMultiClassReference &SubMultiClass); @@ -141,12 +134,11 @@ private: // Parser methods. Record *InstantiateMulticlassDef(MultiClass &MC, Record *DefProto, Init *&DefmPrefix, SMRange DefmPrefixRange, ArrayRef<Init *> TArgs, - std::vector<Init *> &TemplateVals); + ArrayRef<Init *> TemplateVals); bool ResolveMulticlassDefArgs(MultiClass &MC, Record *DefProto, SMLoc DefmPrefixLoc, SMLoc SubClassLoc, ArrayRef<Init *> TArgs, - std::vector<Init *> &TemplateVals, - bool DeleteArgs); + ArrayRef<Init *> TemplateVals, bool DeleteArgs); bool ResolveMulticlassDef(MultiClass &MC, Record *CurRec, Record *DefProto, @@ -155,7 +147,7 @@ private: // Parser methods. bool ParseDef(MultiClass *CurMultiClass); bool ParseForeach(MultiClass *CurMultiClass); bool ParseTopLevelLet(MultiClass *CurMultiClass); - std::vector<LetRecord> ParseLetList(); + void ParseLetList(SmallVectorImpl<LetRecord> &Result); bool ParseObjectBody(Record *CurRec); bool ParseBody(Record *CurRec); @@ -168,19 +160,21 @@ private: // Parser methods. SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm); SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC); - Init *ParseIDValue(Record *CurRec, const std::string &Name, SMLoc NameLoc, + Init *ParseIDValue(Record *CurRec, StringInit *Name, SMLoc NameLoc, IDParseMode Mode = ParseValueMode); Init *ParseSimpleValue(Record *CurRec, RecTy *ItemType = nullptr, IDParseMode Mode = ParseValueMode); Init *ParseValue(Record *CurRec, RecTy *ItemType = nullptr, IDParseMode Mode = ParseValueMode); - std::vector<Init*> ParseValueList(Record *CurRec, Record *ArgsRec = nullptr, - RecTy *EltTy = nullptr); - std::vector<std::pair<llvm::Init*, std::string> > ParseDagArgList(Record *); - bool ParseOptionalRangeList(std::vector<unsigned> &Ranges); - bool ParseOptionalBitList(std::vector<unsigned> &Ranges); - std::vector<unsigned> ParseRangeList(); - bool ParseRangePiece(std::vector<unsigned> &Ranges); + void ParseValueList(SmallVectorImpl<llvm::Init*> &Result, Record *CurRec, + Record *ArgsRec = nullptr, RecTy *EltTy = nullptr); + void ParseDagArgList( + SmallVectorImpl<std::pair<llvm::Init*, StringInit*>> &Result, + Record *CurRec); + bool ParseOptionalRangeList(SmallVectorImpl<unsigned> &Ranges); + bool ParseOptionalBitList(SmallVectorImpl<unsigned> &Ranges); + void ParseRangeList(SmallVectorImpl<unsigned> &Result); + bool ParseRangePiece(SmallVectorImpl<unsigned> &Ranges); RecTy *ParseType(); Init *ParseOperation(Record *CurRec, RecTy *ItemType); RecTy *ParseOperatorType(); |