1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 02:33:06 +01:00

[TableGen] Eliminte source location from CodeInit

Step 1 in eliminating the 'code' type.

Differential Revision: https://reviews.llvm.org/D91932
This commit is contained in:
Paul C. Anagnostopoulos 2020-11-22 09:56:42 -05:00
parent 87d0019c62
commit 58226c6585
7 changed files with 46 additions and 72 deletions

View File

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

View File

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

View File

@ -514,20 +514,13 @@ IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
return BitsInit::get(NewBits); return BitsInit::get(NewBits);
} }
CodeInit *CodeInit::get(StringRef V, const SMLoc &Loc) { CodeInit *CodeInit::get(StringRef V) {
static StringSet<BumpPtrAllocator &> ThePool(Allocator); static StringMap<CodeInit*, BumpPtrAllocator &> ThePool(Allocator);
CodeInitsConstructed++; auto &Entry = *ThePool.insert(std::make_pair(V, nullptr)).first;
if (!Entry.second)
// Unlike StringMap, StringSet doesn't accept empty keys. Entry.second = new(Allocator) CodeInit(Entry.getKey());
if (V.empty()) return Entry.second;
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);
} }
StringInit *StringInit::get(StringRef V) { StringInit *StringInit::get(StringRef V) {
@ -543,7 +536,7 @@ Init *StringInit::convertInitializerTo(RecTy *Ty) const {
if (isa<StringRecTy>(Ty)) if (isa<StringRecTy>(Ty))
return const_cast<StringInit *>(this); return const_cast<StringInit *>(this);
if (isa<CodeRecTy>(Ty)) if (isa<CodeRecTy>(Ty))
return CodeInit::get(getValue(), SMLoc()); return CodeInit::get(getValue());
return nullptr; return nullptr;
} }
@ -1046,8 +1039,6 @@ Init *BinOpInit::Fold(Record *CurRec) const {
default: llvm_unreachable("unhandled comparison"); default: llvm_unreachable("unhandled comparison");
} }
return BitInit::get(Result); return BitInit::get(Result);
//// bool Equal = LHSs->getValue() == RHSs->getValue();
//// return BitInit::get(getOpcode() == EQ ? Equal : !Equal);
} }
// Finally, !eq and !ne can be used with records. // Finally, !eq and !ne can be used with records.
@ -2170,7 +2161,7 @@ bool RecordVal::setValue(Init *V) {
return false; return false;
} }
// This version of setValue takes an source location and resets the // This version of setValue takes a source location and resets the
// location in the RecordVal. // location in the RecordVal.
bool RecordVal::setValue(Init *V, SMLoc NewLoc) { bool RecordVal::setValue(Init *V, SMLoc NewLoc) {
Loc = NewLoc; Loc = NewLoc;
@ -2351,6 +2342,14 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
return OS << "}\n"; return OS << "}\n";
} }
SMLoc Record::getFieldLoc(StringRef FieldName) const {
const RecordVal *R = getValue(FieldName);
if (!R)
PrintFatalError(getLoc(), "Record `" + getName() +
"' does not have a field named `" + FieldName + "'!\n");
return R->getLoc();
}
Init *Record::getValueInit(StringRef FieldName) const { Init *Record::getValueInit(StringRef FieldName) const {
const RecordVal *R = getValue(FieldName); const RecordVal *R = getValue(FieldName);
if (!R || !R->getValue()) if (!R || !R->getValue())

View File

@ -1920,7 +1920,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
break; break;
} }
case tgtok::CodeFragment: case tgtok::CodeFragment:
R = CodeInit::get(Lex.getCurStrVal(), Lex.getLoc()); R = CodeInit::get(Lex.getCurStrVal());
Lex.Lex(); Lex.Lex();
break; break;
case tgtok::question: case tgtok::question:

View File

@ -113,8 +113,8 @@ TEST(CodeExpander, NotAnExpansion) {
.emit(OS); .emit(OS);
EXPECT_EQ(OS.str(), " $foo"); EXPECT_EQ(OS.str(), " $foo");
DiagChecker.expect(SMDiagnostic( DiagChecker.expect(SMDiagnostic(
SrcMgr, SMLoc::getFromPointer(In.data() + 1), "TestBuffer", 1, 1, SrcMgr, SMLoc::getFromPointer(In.data()), "TestBuffer", 1, 0,
SourceMgr::DK_Warning, "Assuming missing escape character", " $foo", {})); SourceMgr::DK_Warning, "Assuming missing escape character: \\$", " $foo", {}));
} }
// \$foo is not an expansion but shouldn't warn as it's using the escape. // \$foo is not an expansion but shouldn't warn as it's using the escape.
@ -162,27 +162,7 @@ TEST(CodeExpander, UndefinedExpansion) {
EXPECT_EQ(OS.str(), "expansion"); EXPECT_EQ(OS.str(), "expansion");
DiagChecker.expect( DiagChecker.expect(
SMDiagnostic(SrcMgr, SMLoc(), "<unknown>", 0, -1, SourceMgr::DK_Error, SMDiagnostic(SrcMgr, SMLoc(), "<unknown>", 0, -1, SourceMgr::DK_Error,
"Attempting to expand an undeclared variable foo", "", {})); "Attempt to expand an undeclared variable 'foo'", "", {}));
}
// ${foo} is an undefined expansion and should error. When given a valid
// location for the start of the buffer it should correctly point at the
// expansion being performed.
TEST(CodeExpander, UndefinedExpansionWithLoc) {
std::string Result;
raw_string_ostream OS(Result);
CodeExpansions Expansions;
Expansions.declare("bar", "expansion");
RAIIDiagnosticChecker DiagChecker;
StringRef In = bufferize("Padding ${foo}${bar}");
CodeExpander(In, Expansions, SMLoc::getFromPointer(In.data()), false)
.emit(OS);
EXPECT_EQ(OS.str(), "Padding expansion");
DiagChecker.expect(SMDiagnostic(
SrcMgr, SMLoc::getFromPointer(In.data() + 8), "TestBuffer", 1, 8,
SourceMgr::DK_Error, "Attempting to expand an undeclared variable foo",
"Padding ${foo}${bar}", {}));
} }
// ${bar is an unterminated expansion. Warn and implicitly terminate it. // ${bar is an unterminated expansion. Warn and implicitly terminate it.
@ -197,7 +177,7 @@ TEST(CodeExpander, UnterminatedExpansion) {
CodeExpander(In, Expansions, SMLoc::getFromPointer(In.data()), false) CodeExpander(In, Expansions, SMLoc::getFromPointer(In.data()), false)
.emit(OS); .emit(OS);
EXPECT_EQ(OS.str(), " expansion"); EXPECT_EQ(OS.str(), " expansion");
DiagChecker.expect(SMDiagnostic(SrcMgr, SMLoc::getFromPointer(In.data() + 1), DiagChecker.expect(SMDiagnostic(SrcMgr, SMLoc::getFromPointer(In.data()),
"TestBuffer", 1, 1, SourceMgr::DK_Warning, "TestBuffer", 1, 0, SourceMgr::DK_Warning,
"Unterminated expansion", " ${bar", {})); "Unterminated expansion '${bar'", " ${bar", {}));
} }

View File

@ -759,7 +759,7 @@ void GICombinerEmitter::generateCodeForTree(raw_ostream &OS,
DagInit *Applyer = RuleDef.getValueAsDag("Apply"); DagInit *Applyer = RuleDef.getValueAsDag("Apply");
if (Applyer->getOperatorAsDef(RuleDef.getLoc())->getName() != if (Applyer->getOperatorAsDef(RuleDef.getLoc())->getName() !=
"apply") { "apply") {
PrintError(RuleDef.getLoc(), "Expected apply operator"); PrintError(RuleDef.getLoc(), "Expected 'apply' operator in Apply DAG");
return; return;
} }
@ -800,7 +800,7 @@ void GICombinerEmitter::generateCodeForTree(raw_ostream &OS,
OS << Indent << " && [&]() {\n" OS << Indent << " && [&]() {\n"
<< Indent << " " << Indent << " "
<< CodeExpander(Rule->getMatchingFixupCode()->getValue(), Expansions, << CodeExpander(Rule->getMatchingFixupCode()->getValue(), Expansions,
Rule->getMatchingFixupCode()->getLoc(), ShowExpansions) RuleDef.getLoc(), ShowExpansions)
<< "\n" << "\n"
<< Indent << " return true;\n" << Indent << " return true;\n"
<< Indent << " }()"; << Indent << " }()";
@ -809,7 +809,7 @@ void GICombinerEmitter::generateCodeForTree(raw_ostream &OS,
if (const CodeInit *Code = dyn_cast<CodeInit>(Applyer->getArg(0))) { if (const CodeInit *Code = dyn_cast<CodeInit>(Applyer->getArg(0))) {
OS << CodeExpander(Code->getAsUnquotedString(), Expansions, OS << CodeExpander(Code->getAsUnquotedString(), Expansions,
Code->getLoc(), ShowExpansions) RuleDef.getLoc(), ShowExpansions)
<< "\n" << "\n"
<< Indent << " return true;\n" << Indent << " return true;\n"
<< Indent << " }\n"; << Indent << " }\n";

View File

@ -58,21 +58,15 @@ void CodeExpander::emit(raw_ostream &OS) const {
// Warn if we split because no terminator was found. // Warn if we split because no terminator was found.
StringRef EndVar = StartVar.drop_front(2 /* ${ */ + Var.size()); StringRef EndVar = StartVar.drop_front(2 /* ${ */ + Var.size());
if (EndVar.empty()) { if (EndVar.empty()) {
size_t LocOffset = StartVar.data() - Code.data(); PrintWarning(Loc, "Unterminated expansion '${" + Var + "'");
PrintWarning( PrintNote("Code: [{" + Code + "}]");
Loc.size() > 0 && Loc[0].isValid()
? SMLoc::getFromPointer(Loc[0].getPointer() + LocOffset)
: SMLoc(),
"Unterminated expansion");
} }
auto ValueI = Expansions.find(Var); auto ValueI = Expansions.find(Var);
if (ValueI == Expansions.end()) { if (ValueI == Expansions.end()) {
size_t LocOffset = StartVar.data() - Code.data(); PrintError(Loc,
PrintError(Loc.size() > 0 && Loc[0].isValid() "Attempt to expand an undeclared variable '" + Var + "'");
? SMLoc::getFromPointer(Loc[0].getPointer() + LocOffset) PrintNote("Code: [{" + Code + "}]");
: SMLoc(),
"Attempting to expand an undeclared variable " + Var);
} }
if (ShowExpansions) if (ShowExpansions)
OS << "/*$" << Var << "{*/"; OS << "/*$" << Var << "{*/";
@ -82,11 +76,8 @@ void CodeExpander::emit(raw_ostream &OS) const {
continue; continue;
} }
size_t LocOffset = Current.data() - Code.data(); PrintWarning(Loc, "Assuming missing escape character: \\$");
PrintWarning(Loc.size() > 0 && Loc[0].isValid() PrintNote("Code: [{" + Code + "}]");
? SMLoc::getFromPointer(Loc[0].getPointer() + LocOffset)
: SMLoc(),
"Assuming missing escape character");
OS << "$"; OS << "$";
Current = Current.drop_front(1); Current = Current.drop_front(1);
} }