diff --git a/llvm/include/llvm/TableGen/Error.h b/llvm/include/llvm/TableGen/Error.h --- a/llvm/include/llvm/TableGen/Error.h +++ b/llvm/include/llvm/TableGen/Error.h @@ -20,6 +20,8 @@ void PrintNote(const Twine &Msg); void PrintNote(ArrayRef NoteLoc, const Twine &Msg); +LLVM_ATTRIBUTE_NORETURN void PrintFatalNote(ArrayRef ErrorLoc, + const Twine &Msg); void PrintWarning(ArrayRef WarningLoc, const Twine &Msg); void PrintWarning(const char *Loc, const Twine &Msg); diff --git a/llvm/lib/TableGen/Error.cpp b/llvm/lib/TableGen/Error.cpp --- a/llvm/lib/TableGen/Error.cpp +++ b/llvm/lib/TableGen/Error.cpp @@ -45,6 +45,13 @@ PrintMessage(NoteLoc, SourceMgr::DK_Note, Msg); } +void PrintFatalNote(ArrayRef NoteLoc, const Twine &Msg) { + PrintNote(NoteLoc, Msg); + // The following call runs the file cleanup handlers. + sys::RunInterruptHandlers(); + std::exit(1); +} + void PrintWarning(ArrayRef WarningLoc, const Twine &Msg) { PrintMessage(WarningLoc, SourceMgr::DK_Warning, Msg); } diff --git a/llvm/test/TableGen/CodeGenSchedule-duplicate-instrw.td b/llvm/test/TableGen/CodeGenSchedule-duplicate-instrw.td new file mode 100644 --- /dev/null +++ b/llvm/test/TableGen/CodeGenSchedule-duplicate-instrw.td @@ -0,0 +1,21 @@ +// RUN: not llvm-tblgen --gen-subtarget -I %p/../../include -I %p/Common %s -o - 2>&1 | FileCheck %s + +include "llvm/Target/Target.td" + +def FakeTarget : Target { } + +def FakeModel : SchedMachineModel { } + +def WriteA : SchedWrite; +def WriteB : SchedWrite; + +let SchedModel = NoSchedModel in { + def : InstRW<[WriteA], (instrs COPY)>; + + def : InstRW<[WriteB], (instrs COPY)>; +// CHECK: [[@LINE-1]]:3: error: Overlapping InstRW definition for "COPY" also matches previous "(instrs COPY)". +// CHECK-NEXT: def : InstRW<[WriteB], (instrs COPY)>; + +// CHECK: [[@LINE-6]]:3: note: Previous match was here. +// CHECK-NEXT: def : InstRW<[WriteA], (instrs COPY)>; +} \ No newline at end of file diff --git a/llvm/utils/TableGen/CodeGenSchedule.cpp b/llvm/utils/TableGen/CodeGenSchedule.cpp --- a/llvm/utils/TableGen/CodeGenSchedule.cpp +++ b/llvm/utils/TableGen/CodeGenSchedule.cpp @@ -248,8 +248,7 @@ } PrintError(R->getLoc(), "STIPredicate " + Name + " multiply declared."); - PrintNote(It->second->getLoc(), "Previous declaration was here."); - PrintFatalError(R->getLoc(), "Invalid STIPredicateDecl found."); + PrintFatalNote(It->second->getLoc(), "Previous declaration was here."); } // Disallow InstructionEquivalenceClasses with an empty instruction list. @@ -454,10 +453,8 @@ PrintError(TIIPred->getLoc(), "TIIPredicate " + Name + " is multiply defined."); - PrintNote(It->second->getLoc(), - " Previous definition of " + Name + " was here."); - PrintFatalError(TIIPred->getLoc(), - "Found conflicting definitions of TIIPredicate."); + PrintFatalNote(It->second->getLoc(), + " Previous definition of " + Name + " was here."); } } @@ -1083,13 +1080,14 @@ if (RWD->getValueAsDef("SchedModel") == RWModelDef && RWModelDef->getValueAsBit("FullInstRWOverlapCheck")) { assert(!InstDefs.empty()); // Checked at function start. - PrintFatalError - (InstRWDef->getLoc(), - "Overlapping InstRW definition for \"" + - InstDefs.front()->getName() + - "\" also matches previous \"" + - RWD->getValue("Instrs")->getValue()->getAsString() + - "\"."); + PrintError( + InstRWDef->getLoc(), + "Overlapping InstRW definition for \"" + + InstDefs.front()->getName() + + "\" also matches previous \"" + + RWD->getValue("Instrs")->getValue()->getAsString() + + "\"."); + PrintFatalNote(RWD->getLoc(), "Previous match was here."); } } LLVM_DEBUG(dbgs() << "InstRW: Reuse SC " << OldSCIdx << ":" @@ -1118,13 +1116,13 @@ for (Record *OldRWDef : SchedClasses[OldSCIdx].InstRWs) { if (OldRWDef->getValueAsDef("SchedModel") == RWModelDef) { assert(!InstDefs.empty()); // Checked at function start. - PrintFatalError - (InstRWDef->getLoc(), - "Overlapping InstRW definition for \"" + - InstDefs.front()->getName() + - "\" also matches previous \"" + - OldRWDef->getValue("Instrs")->getValue()->getAsString() + - "\"."); + PrintError( + InstRWDef->getLoc(), + "Overlapping InstRW definition for \"" + + InstDefs.front()->getName() + "\" also matches previous \"" + + OldRWDef->getValue("Instrs")->getValue()->getAsString() + + "\"."); + PrintFatalNote(OldRWDef->getLoc(), "Previous match was here."); } assert(OldRWDef != InstRWDef && "SchedClass has duplicate InstRW def");