diff options
author | Stephen Hines <srhines@google.com> | 2014-12-01 14:51:49 -0800 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-12-02 16:08:10 -0800 |
commit | 37ed9c199ca639565f6ce88105f9e39e898d82d0 (patch) | |
tree | 8fb36d3910e3ee4c4e1b7422f4f017108efc52f5 /lib/TableGen | |
parent | d2327b22152ced7bc46dc629fc908959e8a52d03 (diff) | |
download | external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.zip external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.gz external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.bz2 |
Update aosp/master LLVM for rebase to r222494.
Change-Id: Ic787f5e0124df789bd26f3f24680f45e678eef2d
Diffstat (limited to 'lib/TableGen')
-rw-r--r-- | lib/TableGen/Main.cpp | 23 | ||||
-rw-r--r-- | lib/TableGen/Record.cpp | 52 | ||||
-rw-r--r-- | lib/TableGen/TGLexer.cpp | 3 | ||||
-rw-r--r-- | lib/TableGen/TGLexer.h | 17 | ||||
-rw-r--r-- | lib/TableGen/TGParser.cpp | 96 | ||||
-rw-r--r-- | lib/TableGen/TGParser.h | 4 |
6 files changed, 143 insertions, 52 deletions
diff --git a/lib/TableGen/Main.cpp b/lib/TableGen/Main.cpp index e317fbf..2578cc2 100644 --- a/lib/TableGen/Main.cpp +++ b/lib/TableGen/Main.cpp @@ -56,11 +56,11 @@ static int createDependencyFile(const TGParser &Parser, const char *argv0) { errs() << argv0 << ": the option -d must be used together with -o\n"; return 1; } - std::string Error; - tool_output_file DepOut(DependFilename.c_str(), Error, sys::fs::F_Text); - if (!Error.empty()) { - errs() << argv0 << ": error opening " << DependFilename - << ":" << Error << "\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; } DepOut.os() << OutputFilename << ":"; @@ -88,10 +88,9 @@ int TableGenMain(char *argv0, TableGenMainFn *MainFn) { << "': " << EC.message() << "\n"; return 1; } - MemoryBuffer *F = FileOrErr.get().release(); // Tell SrcMgr about this buffer, which is what TGParser will pick up. - SrcMgr.AddNewSourceBuffer(F, SMLoc()); + SrcMgr.AddNewSourceBuffer(std::move(*FileOrErr), SMLoc()); // Record the location of the include directory so that the lexer can find // it later. @@ -102,11 +101,11 @@ int TableGenMain(char *argv0, TableGenMainFn *MainFn) { if (Parser.ParseFile()) return 1; - std::string Error; - tool_output_file Out(OutputFilename.c_str(), Error, sys::fs::F_Text); - if (!Error.empty()) { - errs() << argv0 << ": error opening " << OutputFilename - << ":" << Error << "\n"; + 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 (!DependFilename.empty()) { diff --git a/lib/TableGen/Record.cpp b/lib/TableGen/Record.cpp index f7843dc..34e3ab4 100644 --- a/lib/TableGen/Record.cpp +++ b/lib/TableGen/Record.cpp @@ -114,8 +114,21 @@ Init *BitRecTy::convertValue(IntInit *II) { Init *BitRecTy::convertValue(TypedInit *VI) { RecTy *Ty = VI->getType(); - if (isa<BitRecTy>(Ty) || isa<BitsRecTy>(Ty) || isa<IntRecTy>(Ty)) + if (isa<BitRecTy>(Ty)) return VI; // Accept variable if it is already of bit type! + if (auto *BitsTy = dyn_cast<BitsRecTy>(Ty)) + // Accept only bits<1> expression. + return BitsTy->getNumBits() == 1 ? VI : nullptr; + // Ternary !if can be converted to bit, but only if both sides are + // convertible to a bit. + if (TernOpInit *TOI = dyn_cast<TernOpInit>(VI)) { + if (TOI->getOpcode() != TernOpInit::TernaryOp::IF) + return nullptr; + if (!TOI->getMHS()->convertInitializerTo(BitRecTy::get()) || + !TOI->getRHS()->convertInitializerTo(BitRecTy::get())) + return nullptr; + return TOI; + } return nullptr; } @@ -952,17 +965,21 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { break; } case ADD: + case AND: case SHL: case SRA: case SRL: { - IntInit *LHSi = dyn_cast<IntInit>(LHS); - IntInit *RHSi = dyn_cast<IntInit>(RHS); + IntInit *LHSi = + dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get())); + IntInit *RHSi = + dyn_cast_or_null<IntInit>(RHS->convertInitializerTo(IntRecTy::get())); if (LHSi && RHSi) { int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue(); int64_t Result; switch (getOpcode()) { default: llvm_unreachable("Bad opcode!"); case ADD: Result = LHSv + RHSv; break; + case AND: 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; @@ -989,6 +1006,7 @@ std::string BinOpInit::getAsString() const { switch (Opc) { case CONCAT: Result = "!con"; break; case ADD: Result = "!add"; break; + case AND: Result = "!and"; break; case SHL: Result = "!shl"; break; case SRA: Result = "!sra"; break; case SRL: Result = "!srl"; break; @@ -1690,13 +1708,6 @@ const std::string &Record::getName() const { } void Record::setName(Init *NewName) { - if (TrackedRecords.getDef(Name->getAsUnquotedString()) == this) { - TrackedRecords.removeDef(Name->getAsUnquotedString()); - TrackedRecords.addDef(this); - } else if (TrackedRecords.getClass(Name->getAsUnquotedString()) == this) { - TrackedRecords.removeClass(Name->getAsUnquotedString()); - TrackedRecords.addClass(this); - } // Otherwise this isn't yet registered. Name = NewName; checkName(); // DO NOT resolve record values to the name at this point because @@ -1996,16 +2007,14 @@ void RecordKeeper::dump() const { errs() << *this; } raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) { OS << "------------- Classes -----------------\n"; - const std::map<std::string, Record*> &Classes = RK.getClasses(); - for (std::map<std::string, Record*>::const_iterator I = Classes.begin(), - E = Classes.end(); I != E; ++I) - OS << "class " << *I->second; + const auto &Classes = RK.getClasses(); + for (const auto &C : Classes) + OS << "class " << *C.second; OS << "------------- Defs -----------------\n"; - const std::map<std::string, Record*> &Defs = RK.getDefs(); - for (std::map<std::string, Record*>::const_iterator I = Defs.begin(), - E = Defs.end(); I != E; ++I) - OS << "def " << *I->second; + const auto &Defs = RK.getDefs(); + for (const auto &D : Defs) + OS << "def " << *D.second; return OS; } @@ -2020,10 +2029,9 @@ RecordKeeper::getAllDerivedDefinitions(const std::string &ClassName) const { PrintFatalError("ERROR: Couldn't find the `" + ClassName + "' class!\n"); std::vector<Record*> Defs; - for (std::map<std::string, Record*>::const_iterator I = getDefs().begin(), - E = getDefs().end(); I != E; ++I) - if (I->second->isSubClassOf(Class)) - Defs.push_back(I->second); + for (const auto &D : getDefs()) + if (D.second->isSubClassOf(Class)) + Defs.push_back(D.second.get()); return Defs; } diff --git a/lib/TableGen/TGLexer.cpp b/lib/TableGen/TGLexer.cpp index fc1d3ca..63b8584 100644 --- a/lib/TableGen/TGLexer.cpp +++ b/lib/TableGen/TGLexer.cpp @@ -411,7 +411,7 @@ tgtok::TokKind TGLexer::LexNumber() { if (CurPtr == NumStart) return ReturnError(CurPtr-2, "Invalid binary number"); CurIntVal = strtoll(NumStart, nullptr, 2); - return tgtok::IntVal; + return tgtok::BinaryIntVal; } } @@ -471,6 +471,7 @@ tgtok::TokKind TGLexer::LexExclaim() { .Case("tail", tgtok::XTail) .Case("con", tgtok::XConcat) .Case("add", tgtok::XADD) + .Case("and", tgtok::XAND) .Case("shl", tgtok::XSHL) .Case("sra", tgtok::XSRA) .Case("srl", tgtok::XSRL) diff --git a/lib/TableGen/TGLexer.h b/lib/TableGen/TGLexer.h index a2c95ca..1f750fc 100644 --- a/lib/TableGen/TGLexer.h +++ b/lib/TableGen/TGLexer.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef TGLEXER_H -#define TGLEXER_H +#ifndef LLVM_LIB_TABLEGEN_TGLEXER_H +#define LLVM_LIB_TABLEGEN_TGLEXER_H #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" @@ -47,11 +47,15 @@ namespace tgtok { MultiClass, String, // !keywords. - XConcat, XADD, XSRA, XSRL, XSHL, XListConcat, XStrConcat, XCast, XSubst, - XForEach, XHead, XTail, XEmpty, XIf, XEq, + XConcat, XADD, XAND, XSRA, XSRL, XSHL, XListConcat, XStrConcat, XCast, + XSubst, XForEach, XHead, XTail, XEmpty, XIf, XEq, // Integer value. IntVal, + + // Binary constant. Note that these are sized according to the number of + // bits given. + BinaryIntVal, // String valued tokens. Id, StrVal, VarName, CodeFragment @@ -105,6 +109,11 @@ public: assert(CurCode == tgtok::IntVal && "This token isn't an integer"); return CurIntVal; } + std::pair<int64_t, unsigned> getCurBinaryIntVal() const { + assert(CurCode == tgtok::BinaryIntVal && + "This token isn't a binary integer"); + return std::make_pair(CurIntVal, (CurPtr - TokStart)-2); + } SMLoc getLoc() const; diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp index 0550692..4d4bbe9 100644 --- a/lib/TableGen/TGParser.cpp +++ b/lib/TableGen/TGParser.cpp @@ -135,11 +135,18 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName, V = BitsInit::get(NewBits); } - if (RV->setValue(V)) + if (RV->setValue(V)) { + std::string InitType = ""; + if (BitsInit *BI = dyn_cast<BitsInit>(V)) { + InitType = (Twine("' of type bit initializer with length ") + + Twine(BI->getNumBits())).str(); + } return Error(Loc, "Value '" + ValName->getAsUnquotedString() + "' of type '" + RV->getType()->getAsString() + "' is incompatible with initializer '" + V->getAsString() + + InitType + "'"); + } return false; } @@ -225,14 +232,14 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC, i != iend; ++i) { // Clone the def and add it to the current multiclass - Record *NewDef = new Record(**i); + auto NewDef = make_unique<Record>(**i); // Add all of the values in the superclass into the current def. for (unsigned i = 0, e = MCVals.size(); i != e; ++i) - if (AddValue(NewDef, SubMultiClass.RefRange.Start, MCVals[i])) + if (AddValue(NewDef.get(), SubMultiClass.RefRange.Start, MCVals[i])) return true; - CurMC->DefPrototypes.push_back(NewDef); + CurMC->DefPrototypes.push_back(NewDef.release()); } const std::vector<Init *> &SMCTArgs = SMC->Rec.getTemplateArgs(); @@ -341,6 +348,7 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){ TypedInit *IVal = dyn_cast<TypedInit>(IterVals[i].IterValue); if (!IVal) { Error(Loc, "foreach iterator value is untyped"); + delete IterRec; return true; } @@ -349,6 +357,7 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){ if (SetValue(IterRec, Loc, IterVar->getName(), std::vector<unsigned>(), IVal)) { Error(Loc, "when instantiating this def"); + delete IterRec; return true; } @@ -365,6 +374,7 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){ IterRec->setName(GetNewAnonymousName()); else { Error(Loc, "def already exists: " + IterRec->getNameInitAsString()); + delete IterRec; return true; } } @@ -904,6 +914,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { case tgtok::XConcat: case tgtok::XADD: + case tgtok::XAND: case tgtok::XSRA: case tgtok::XSRL: case tgtok::XSHL: @@ -921,6 +932,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { default: llvm_unreachable("Unhandled code!"); 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::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; @@ -1173,6 +1185,15 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, Lex.Lex(); // Skip '#'. return ParseSimpleValue(CurRec, ItemType, Mode); case tgtok::IntVal: R = IntInit::get(Lex.getCurIntVal()); Lex.Lex(); break; + case tgtok::BinaryIntVal: { + auto BinaryVal = Lex.getCurBinaryIntVal(); + SmallVector<Init*, 16> Bits(BinaryVal.second); + for (unsigned i = 0, e = BinaryVal.second; i != e; ++i) + Bits[i] = BitInit::get(BinaryVal.first & (1LL << i)); + R = BitsInit::get(Bits); + Lex.Lex(); + break; + } case tgtok::StrVal: { std::string Val = Lex.getCurStrVal(); Lex.Lex(); @@ -1233,12 +1254,17 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, SCRef.Rec = Class; SCRef.TemplateArgs = ValueList; // Add info about the subclass to NewRec. - if (AddSubClass(NewRec, SCRef)) + if (AddSubClass(NewRec, SCRef)) { + delete NewRec; return nullptr; + } if (!CurMultiClass) { NewRec->resolveReferences(); Records.addDef(NewRec); } else { + // This needs to get resolved once the multiclass template arguments are + // known before any use. + NewRec->setResolveFirst(true); // Otherwise, we're inside a multiclass, add it to the multiclass. CurMultiClass->DefPrototypes.push_back(NewRec); @@ -1284,17 +1310,40 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, } Lex.Lex(); // eat the '}' - SmallVector<Init *, 16> NewBits(Vals.size()); + SmallVector<Init *, 16> NewBits; + // As we parse { a, b, ... }, 'a' is the highest bit, but we parse it + // first. We'll first read everything in to a vector, then we can reverse + // it to get the bits in the correct order for the BitsInit value. for (unsigned i = 0, e = Vals.size(); i != e; ++i) { + // FIXME: The following two loops would not be duplicated + // if the API was a little more orthogonal. + + // bits<n> values are allowed to initialize n bits. + if (BitsInit *BI = dyn_cast<BitsInit>(Vals[i])) { + for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) + NewBits.push_back(BI->getBit((e - i) - 1)); + continue; + } + // bits<n> can also come from variable initializers. + if (VarInit *VI = dyn_cast<VarInit>(Vals[i])) { + if (BitsRecTy *BitsRec = dyn_cast<BitsRecTy>(VI->getType())) { + for (unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i) + NewBits.push_back(VI->getBit((e - i) - 1)); + continue; + } + // Fallthrough to try convert this to a bit. + } + // All other values must be convertible to just a single bit. Init *Bit = Vals[i]->convertInitializerTo(BitRecTy::get()); if (!Bit) { Error(BraceLoc, "Element #" + utostr(i) + " (" + Vals[i]->getAsString()+ ") is not convertable to a bit"); return nullptr; } - NewBits[Vals.size()-i-1] = Bit; + NewBits.push_back(Bit); } + std::reverse(NewBits.begin(), NewBits.end()); return BitsInit::get(NewBits); } case tgtok::l_square: { // Value ::= '[' ValueList ']' @@ -1439,6 +1488,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, case tgtok::XCast: // Value ::= !unop '(' Value ')' case tgtok::XConcat: case tgtok::XADD: + case tgtok::XAND: case tgtok::XSRA: case tgtok::XSRL: case tgtok::XSHL: @@ -1727,7 +1777,10 @@ Init *TGParser::ParseDeclaration(Record *CurRec, Init *Val = ParseValue(CurRec, Type); if (!Val || SetValue(CurRec, ValLoc, DeclName, std::vector<unsigned>(), Val)) - return nullptr; + // Return the name, even if an error is thrown. This is so that we can + // continue to make some progress, even without the value having been + // initialized. + return DeclName; } return DeclName; @@ -1984,6 +2037,7 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { // Parse ObjectName and make a record for it. Record *CurRec; + bool CurRecOwnershipTransferred = false; Init *Name = ParseObjectName(CurMultiClass); if (Name) CurRec = new Record(Name, DefLoc, Records); @@ -1998,9 +2052,11 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { if (Records.getDef(CurRec->getNameInitAsString())) { Error(DefLoc, "def '" + CurRec->getNameInitAsString() + "' already defined"); + delete CurRec; return true; } Records.addDef(CurRec); + CurRecOwnershipTransferred = true; if (ParseObjectBody(CurRec)) return true; @@ -2010,8 +2066,10 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { // before this object, instantiated prior to defs derived from this object, // and this available for indirect name resolution when defs derived from // this object are instantiated. - if (ParseObjectBody(CurRec)) + if (ParseObjectBody(CurRec)) { + delete CurRec; return true; + } // Otherwise, a def inside a multiclass, add it to the multiclass. for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); i != e; ++i) @@ -2019,11 +2077,15 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { == CurRec->getNameInit()) { Error(DefLoc, "def '" + CurRec->getNameInitAsString() + "' already defined in this multiclass!"); + delete CurRec; return true; } CurMultiClass->DefPrototypes.push_back(CurRec); - } else if (ParseObjectBody(CurRec)) + CurRecOwnershipTransferred = true; + } else if (ParseObjectBody(CurRec)) { + delete CurRec; return true; + } if (!CurMultiClass) // Def's in multiclasses aren't really defs. // See Record::setName(). This resolve step will see any new name @@ -2049,9 +2111,13 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { if (ProcessForeachDefs(CurRec, DefLoc)) { Error(DefLoc, "Could not process loops for def" + CurRec->getNameInitAsString()); + if (!CurRecOwnershipTransferred) + delete CurRec; return true; } + if (!CurRecOwnershipTransferred) + delete CurRec; return false; } @@ -2196,7 +2262,7 @@ bool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) { // Add this entry to the let stack. std::vector<LetRecord> LetInfo = ParseLetList(); if (LetInfo.empty()) return true; - LetStack.push_back(LetInfo); + LetStack.push_back(std::move(LetInfo)); if (Lex.getCode() != tgtok::In) return TokError("expected 'in' at end of top-level 'let'"); @@ -2365,6 +2431,7 @@ InstantiateMulticlassDef(MultiClass &MC, Error(DefmPrefixRange.Start, "Could not resolve " + CurRec->getNameInitAsString() + ":NAME to '" + DefmPrefix->getAsUnquotedString() + "'"); + delete CurRec; return nullptr; } @@ -2396,6 +2463,7 @@ InstantiateMulticlassDef(MultiClass &MC, Error(DefmPrefixRange.Start, "def '" + CurRec->getNameInitAsString() + "' already defined, instantiating defm with subdef '" + DefProto->getNameInitAsString() + "'"); + delete CurRec; return nullptr; } @@ -2535,6 +2603,12 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) { if (ResolveMulticlassDef(*MC, CurRec, DefProto, DefmLoc)) return Error(SubClassLoc, "could not instantiate def"); + // Defs that can be used by other definitions should be fully resolved + // before any use. + if (DefProto->isResolveFirst() && !CurMultiClass) { + CurRec->resolveReferences(); + CurRec->setResolveFirst(false); + } NewRecDefs.push_back(CurRec); } diff --git a/lib/TableGen/TGParser.h b/lib/TableGen/TGParser.h index 9f4b7e9..79994cb 100644 --- a/lib/TableGen/TGParser.h +++ b/lib/TableGen/TGParser.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef TGPARSER_H -#define TGPARSER_H +#ifndef LLVM_LIB_TABLEGEN_TGPARSER_H +#define LLVM_LIB_TABLEGEN_TGPARSER_H #include "TGLexer.h" #include "llvm/ADT/Twine.h" |