Skip to content

Commit 0ceffd3

Browse files
authored
[TableGen] Add PrintError family overload that take a print function (#107333)
Add PrintError and family overload that accepts a print function. This avoids constructing potentially long strings for passing into these print functions.
1 parent 6df1291 commit 0ceffd3

File tree

6 files changed

+69
-47
lines changed

6 files changed

+69
-47
lines changed

llvm/include/llvm/TableGen/Error.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@
1414
#ifndef LLVM_TABLEGEN_ERROR_H
1515
#define LLVM_TABLEGEN_ERROR_H
1616

17+
#include "llvm/ADT/STLFunctionalExtras.h"
1718
#include "llvm/Support/SourceMgr.h"
18-
#include "llvm/TableGen/Record.h"
1919

2020
namespace llvm {
21+
class Record;
22+
class RecordVal;
23+
class Init;
2124

2225
void PrintNote(const Twine &Msg);
26+
void PrintNote(function_ref<void(raw_ostream &OS)> PrintMsg);
2327
void PrintNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg);
2428

2529
[[noreturn]] void PrintFatalNote(const Twine &Msg);
@@ -32,6 +36,7 @@ void PrintWarning(ArrayRef<SMLoc> WarningLoc, const Twine &Msg);
3236
void PrintWarning(const char *Loc, const Twine &Msg);
3337

3438
void PrintError(const Twine &Msg);
39+
void PrintError(function_ref<void(raw_ostream &OS)> PrintMsg);
3540
void PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg);
3641
void PrintError(const char *Loc, const Twine &Msg);
3742
void PrintError(const Record *Rec, const Twine &Msg);
@@ -41,6 +46,7 @@ void PrintError(const RecordVal *RecVal, const Twine &Msg);
4146
[[noreturn]] void PrintFatalError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg);
4247
[[noreturn]] void PrintFatalError(const Record *Rec, const Twine &Msg);
4348
[[noreturn]] void PrintFatalError(const RecordVal *RecVal, const Twine &Msg);
49+
[[noreturn]] void PrintFatalError(function_ref<void(raw_ostream &OS)> PrintMsg);
4450

4551
void CheckAssert(SMLoc Loc, Init *Condition, Init *Message);
4652
void dumpMessage(SMLoc Loc, Init *Message);

llvm/lib/TableGen/Error.cpp

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,23 @@ static void PrintMessage(ArrayRef<SMLoc> Loc, SourceMgr::DiagKind Kind,
4040
"instantiated from multiclass");
4141
}
4242

43+
// Run file cleanup handlers and then exit fatally (with non-zero exit code).
44+
[[noreturn]] inline static void fatal_exit() {
45+
// The following call runs the file cleanup handlers.
46+
sys::RunInterruptHandlers();
47+
std::exit(1);
48+
}
49+
4350
// Functions to print notes.
4451

4552
void PrintNote(const Twine &Msg) {
4653
WithColor::note() << Msg << "\n";
4754
}
4855

56+
void PrintNote(function_ref<void(raw_ostream &OS)> PrintMsg) {
57+
PrintMsg(WithColor::note());
58+
}
59+
4960
void PrintNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {
5061
PrintMessage(NoteLoc, SourceMgr::DK_Note, Msg);
5162
}
@@ -54,34 +65,26 @@ void PrintNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {
5465

5566
void PrintFatalNote(const Twine &Msg) {
5667
PrintNote(Msg);
57-
// The following call runs the file cleanup handlers.
58-
sys::RunInterruptHandlers();
59-
std::exit(1);
68+
fatal_exit();
6069
}
6170

6271
void PrintFatalNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {
6372
PrintNote(NoteLoc, Msg);
64-
// The following call runs the file cleanup handlers.
65-
sys::RunInterruptHandlers();
66-
std::exit(1);
73+
fatal_exit();
6774
}
6875

6976
// This method takes a Record and uses the source location
7077
// stored in it.
7178
void PrintFatalNote(const Record *Rec, const Twine &Msg) {
7279
PrintNote(Rec->getLoc(), Msg);
73-
// The following call runs the file cleanup handlers.
74-
sys::RunInterruptHandlers();
75-
std::exit(1);
80+
fatal_exit();
7681
}
7782

7883
// This method takes a RecordVal and uses the source location
7984
// stored in it.
8085
void PrintFatalNote(const RecordVal *RecVal, const Twine &Msg) {
8186
PrintNote(RecVal->getLoc(), Msg);
82-
// The following call runs the file cleanup handlers.
83-
sys::RunInterruptHandlers();
84-
std::exit(1);
87+
fatal_exit();
8588
}
8689

8790
// Functions to print warnings.
@@ -100,6 +103,10 @@ void PrintWarning(const char *Loc, const Twine &Msg) {
100103

101104
void PrintError(const Twine &Msg) { WithColor::error() << Msg << "\n"; }
102105

106+
void PrintError(function_ref<void(raw_ostream &OS)> PrintMsg) {
107+
PrintMsg(WithColor::error());
108+
}
109+
103110
void PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) {
104111
PrintMessage(ErrorLoc, SourceMgr::DK_Error, Msg);
105112
}
@@ -124,34 +131,31 @@ void PrintError(const RecordVal *RecVal, const Twine &Msg) {
124131

125132
void PrintFatalError(const Twine &Msg) {
126133
PrintError(Msg);
127-
// The following call runs the file cleanup handlers.
128-
sys::RunInterruptHandlers();
129-
std::exit(1);
134+
fatal_exit();
135+
}
136+
137+
void PrintFatalError(function_ref<void(raw_ostream &OS)> PrintMsg) {
138+
PrintError(PrintMsg);
139+
fatal_exit();
130140
}
131141

132142
void PrintFatalError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) {
133143
PrintError(ErrorLoc, Msg);
134-
// The following call runs the file cleanup handlers.
135-
sys::RunInterruptHandlers();
136-
std::exit(1);
144+
fatal_exit();
137145
}
138146

139147
// This method takes a Record and uses the source location
140148
// stored in it.
141149
void PrintFatalError(const Record *Rec, const Twine &Msg) {
142150
PrintError(Rec->getLoc(), Msg);
143-
// The following call runs the file cleanup handlers.
144-
sys::RunInterruptHandlers();
145-
std::exit(1);
151+
fatal_exit();
146152
}
147153

148154
// This method takes a RecordVal and uses the source location
149155
// stored in it.
150156
void PrintFatalError(const RecordVal *RecVal, const Twine &Msg) {
151157
PrintError(RecVal->getLoc(), Msg);
152-
// The following call runs the file cleanup handlers.
153-
sys::RunInterruptHandlers();
154-
std::exit(1);
158+
fatal_exit();
155159
}
156160

157161
// Check an assertion: Obtain the condition value and be sure it is true.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: not llvm-tblgen -gen-intrinsic-enums --intrinsic-prefix=gen3 -I %p/../../include %s -DTEST_INTRINSICS_SUPPRESS_DEFS 2>&1 | FileCheck %s
2+
3+
include "llvm/IR/Intrinsics.td"
4+
5+
// CHECK: error: tried to generate intrinsics for unknown target gen3
6+
// CHECK-NEXT: Known targets are: gen1, gen2
7+
8+
let TargetPrefix = "gen1" in {
9+
def int_gen1_int0 : Intrinsic<[llvm_i32_ty]>;
10+
}
11+
12+
let TargetPrefix = "gen2" in {
13+
def int_gen2_int0 : Intrinsic<[llvm_i32_ty]>;
14+
}

llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,14 +1603,11 @@ static TreePatternNode &getOperandNum(unsigned OpNo, TreePatternNode &N,
16031603
OpNo -= NumResults;
16041604

16051605
if (OpNo >= N.getNumChildren()) {
1606-
std::string S;
1607-
raw_string_ostream OS(S);
1608-
OS << "Invalid operand number in type constraint " << (OpNo + NumResults)
1609-
<< " ";
1610-
N.print(OS);
1611-
PrintFatalError(S);
1606+
PrintFatalError([&N, OpNo, NumResults](raw_ostream &OS) {
1607+
OS << "Invalid operand number in type constraint " << (OpNo + NumResults);
1608+
N.print(OS);
1609+
});
16121610
}
1613-
16141611
return N.getChild(OpNo);
16151612
}
16161613

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1961,12 +1961,11 @@ void parseVarLenInstOperand(const Record &Def,
19611961
}
19621962

19631963
static void debugDumpRecord(const Record &Rec) {
1964-
// Dump the record, so we can see what's going on...
1965-
std::string E;
1966-
raw_string_ostream S(E);
1967-
S << "Dumping record for previous error:\n";
1968-
S << Rec;
1969-
PrintNote(E);
1964+
// Dump the record, so we can see what's going on.
1965+
PrintNote([&Rec](raw_ostream &OS) {
1966+
OS << "Dumping record for previous error:\n";
1967+
OS << Rec;
1968+
});
19701969
}
19711970

19721971
/// For an operand field named OpName: populate OpInfo.InitValue with the

llvm/utils/TableGen/IntrinsicEmitter.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include "Basic/SequenceToOffsetTable.h"
1515
#include "llvm/ADT/STLExtras.h"
1616
#include "llvm/ADT/SmallVector.h"
17-
#include "llvm/ADT/StringExtras.h"
1817
#include "llvm/ADT/StringRef.h"
1918
#include "llvm/ADT/Twine.h"
2019
#include "llvm/Support/CommandLine.h"
@@ -122,21 +121,24 @@ void IntrinsicEmitter::EmitEnumInfo(const CodeGenIntrinsicTable &Ints,
122121
// Find the TargetSet for which to generate enums. There will be an initial
123122
// set with an empty target prefix which will include target independent
124123
// intrinsics like dbg.value.
125-
const CodeGenIntrinsicTable::TargetSet *Set = nullptr;
124+
using TargetSet = CodeGenIntrinsicTable::TargetSet;
125+
const TargetSet *Set = nullptr;
126126
for (const auto &Target : Ints.Targets) {
127127
if (Target.Name == IntrinsicPrefix) {
128128
Set = &Target;
129129
break;
130130
}
131131
}
132132
if (!Set) {
133-
std::vector<std::string> KnownTargets;
134-
for (const auto &Target : Ints.Targets)
135-
if (!Target.Name.empty())
136-
KnownTargets.push_back(Target.Name.str());
137-
PrintFatalError("tried to generate intrinsics for unknown target " +
138-
IntrinsicPrefix +
139-
"\nKnown targets are: " + join(KnownTargets, ", ") + "\n");
133+
// The first entry is for target independent intrinsics, so drop it.
134+
auto KnowTargets = ArrayRef<TargetSet>(Ints.Targets).drop_front();
135+
PrintFatalError([KnowTargets](raw_ostream &OS) {
136+
OS << "tried to generate intrinsics for unknown target "
137+
<< IntrinsicPrefix << "\nKnown targets are: ";
138+
interleaveComma(KnowTargets, OS,
139+
[&OS](const TargetSet &Target) { OS << Target.Name; });
140+
OS << '\n';
141+
});
140142
}
141143

142144
// Generate a complete header for target specific intrinsics.

0 commit comments

Comments
 (0)