Skip to content

Commit 1e1c7cd

Browse files
author
git apple-llvm automerger
committed
Merge commit '71eaf14094f5' from llvm.org/main into next
2 parents 69e5749 + 71eaf14 commit 1e1c7cd

File tree

14 files changed

+201
-73
lines changed

14 files changed

+201
-73
lines changed

llvm/docs/TableGen/index.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ TableGen runs just like any other LLVM tool. The first (optional) argument
5555
specifies the file to read. If a filename is not specified, ``llvm-tblgen``
5656
reads from standard input.
5757

58+
The ``-o`` option specifies the output file or ``-`` to output to
59+
stdout. Where TableGen produces multiple output files, the option
60+
specifies the name of the main output file, which also works as the
61+
name prefix for other output files.
62+
5863
To be useful, one of the `backends`_ must be used. These backends are
5964
selectable on the command line (type '``llvm-tblgen -help``' for a list). For
6065
example, to get a list of all of the definitions that subclass a particular type

llvm/include/llvm/TableGen/Main.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,34 @@
1515

1616
#include "llvm/Support/CommandLine.h"
1717
#include <functional>
18+
#include <map>
1819

1920
namespace llvm {
2021

2122
class raw_ostream;
2223
class RecordKeeper;
2324

24-
/// Perform the action using Records, and write output to OS.
25+
struct TableGenOutputFiles {
26+
std::string MainFile;
27+
28+
// Translates additional output file names to their contents.
29+
std::map<StringRef, std::string> AdditionalFiles;
30+
};
31+
2532
/// Returns true on error, false otherwise.
2633
using TableGenMainFn = bool(raw_ostream &OS, const RecordKeeper &Records);
2734

35+
/// Perform the action using Records, and store output in OutFiles.
36+
/// Returns true on error, false otherwise.
37+
using MultiFileTableGenMainFn = bool(TableGenOutputFiles &OutFiles,
38+
const RecordKeeper &Records);
39+
2840
int TableGenMain(const char *argv0,
2941
std::function<TableGenMainFn> MainFn = nullptr);
3042

43+
int TableGenMain(const char *argv0,
44+
std::function<MultiFileTableGenMainFn> MainFn = nullptr);
45+
3146
/// Controls emitting large character arrays as strings or character arrays.
3247
/// Typically set to false when building with MSVC.
3348
extern cl::opt<bool> EmitLongStrLiterals;

llvm/include/llvm/TableGen/TableGenBackend.h

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "llvm/ADT/STLFunctionalExtras.h"
1717
#include "llvm/ADT/StringRef.h"
18+
#include "llvm/TableGen/Main.h"
1819
#include "llvm/TableGen/Record.h"
1920

2021
namespace llvm {
@@ -23,7 +24,27 @@ class RecordKeeper;
2324
class raw_ostream;
2425

2526
namespace TableGen::Emitter {
26-
using FnT = function_ref<void(const RecordKeeper &Records, raw_ostream &OS)>;
27+
28+
/// Represents the emitting function. Can produce a single or multple output
29+
/// files.
30+
struct FnT {
31+
using SingleFileGeneratorType = void(const RecordKeeper &Records,
32+
raw_ostream &OS);
33+
using MultiFileGeneratorType = TableGenOutputFiles(
34+
StringRef FilenamePrefix, const RecordKeeper &Records);
35+
36+
SingleFileGeneratorType *SingleFileGenerator = nullptr;
37+
MultiFileGeneratorType *MultiFileGenerator = nullptr;
38+
39+
FnT() = default;
40+
FnT(SingleFileGeneratorType *Gen) : SingleFileGenerator(Gen) {}
41+
FnT(MultiFileGeneratorType *Gen) : MultiFileGenerator(Gen) {}
42+
43+
bool operator==(const FnT &Other) const {
44+
return SingleFileGenerator == Other.SingleFileGenerator &&
45+
MultiFileGenerator == Other.MultiFileGenerator;
46+
}
47+
};
2748

2849
/// Creating an `Opt` object registers the command line option \p Name with
2950
/// TableGen backend and associates the callback \p CB with that option. If
@@ -36,17 +57,33 @@ struct Opt {
3657
/// Convienence wrapper around `Opt` that registers `EmitterClass::run` as the
3758
/// callback.
3859
template <class EmitterC> class OptClass : Opt {
39-
static void run(const RecordKeeper &RK, raw_ostream &OS) {
60+
static TableGenOutputFiles run(StringRef /*FilenamePrefix*/,
61+
const RecordKeeper &RK) {
62+
std::string S;
63+
raw_string_ostream OS(S);
4064
EmitterC(RK).run(OS);
65+
return {S, {}};
4166
}
4267

4368
public:
4469
OptClass(StringRef Name, StringRef Desc) : Opt(Name, run, Desc) {}
4570
};
4671

72+
/// A version of the wrapper for backends emitting multiple files.
73+
template <class EmitterC> class MultiFileOptClass : Opt {
74+
static TableGenOutputFiles run(StringRef FilenamePrefix,
75+
const RecordKeeper &RK) {
76+
return EmitterC(RK).run(FilenamePrefix);
77+
}
78+
79+
public:
80+
MultiFileOptClass(StringRef Name, StringRef Desc) : Opt(Name, run, Desc) {}
81+
};
82+
4783
/// Apply callback for any command line option registered above. Returns false
4884
/// is no callback was applied.
49-
bool ApplyCallback(const RecordKeeper &Records, raw_ostream &OS);
85+
bool ApplyCallback(const RecordKeeper &Records, TableGenOutputFiles &OutFiles,
86+
StringRef FilenamePrefix);
5087

5188
} // namespace TableGen::Emitter
5289

llvm/lib/TableGen/Main.cpp

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "llvm/Support/ErrorOr.h"
2424
#include "llvm/Support/FileSystem.h"
2525
#include "llvm/Support/MemoryBuffer.h"
26+
#include "llvm/Support/Path.h"
2627
#include "llvm/Support/SMLoc.h"
2728
#include "llvm/Support/SourceMgr.h"
2829
#include "llvm/Support/ToolOutputFile.h"
@@ -104,8 +105,30 @@ static int createDependencyFile(const TGParser &Parser, const char *argv0) {
104105
return 0;
105106
}
106107

108+
static int WriteOutput(const TGParser &Parser, const char *argv0,
109+
StringRef Filename, StringRef Content) {
110+
if (WriteIfChanged) {
111+
// Only updates the real output file if there are any differences.
112+
// This prevents recompilation of all the files depending on it if there
113+
// aren't any.
114+
if (auto ExistingOrErr = MemoryBuffer::getFile(Filename, /*IsText=*/true))
115+
if (std::move(ExistingOrErr.get())->getBuffer() == Content)
116+
return 0;
117+
}
118+
std::error_code EC;
119+
ToolOutputFile OutFile(Filename, EC, sys::fs::OF_Text);
120+
if (EC)
121+
return reportError(argv0, "error opening " + Filename + ": " +
122+
EC.message() + "\n");
123+
OutFile.os() << Content;
124+
if (ErrorsPrinted == 0)
125+
OutFile.keep();
126+
127+
return 0;
128+
}
129+
107130
int llvm::TableGenMain(const char *argv0,
108-
std::function<TableGenMainFn> MainFn) {
131+
std::function<MultiFileTableGenMainFn> MainFn) {
109132
RecordKeeper Records;
110133
TGTimer &Timer = Records.getTimer();
111134

@@ -144,13 +167,14 @@ int llvm::TableGenMain(const char *argv0,
144167

145168
// Write output to memory.
146169
Timer.startBackendTimer("Backend overall");
147-
std::string OutString;
148-
raw_string_ostream Out(OutString);
170+
SmallString<128> FilenamePrefix(OutputFilename);
171+
sys::path::replace_extension(FilenamePrefix, "");
172+
TableGenOutputFiles OutFiles;
149173
unsigned status = 0;
150174
// ApplyCallback will return true if it did not apply any callback. In that
151175
// case, attempt to apply the MainFn.
152-
if (TableGen::Emitter::ApplyCallback(Records, Out))
153-
status = MainFn ? MainFn(Out, Records) : 1;
176+
if (TableGen::Emitter::ApplyCallback(Records, OutFiles, FilenamePrefix))
177+
status = MainFn ? MainFn(OutFiles, Records) : 1;
154178
Timer.stopBackendTimer();
155179
if (status)
156180
return 1;
@@ -165,25 +189,17 @@ int llvm::TableGenMain(const char *argv0,
165189
}
166190

167191
Timer.startTimer("Write output");
168-
bool WriteFile = true;
169-
if (WriteIfChanged) {
170-
// Only updates the real output file if there are any differences.
171-
// This prevents recompilation of all the files depending on it if there
172-
// aren't any.
173-
if (auto ExistingOrErr =
174-
MemoryBuffer::getFile(OutputFilename, /*IsText=*/true))
175-
if (std::move(ExistingOrErr.get())->getBuffer() == OutString)
176-
WriteFile = false;
177-
}
178-
if (WriteFile) {
179-
std::error_code EC;
180-
ToolOutputFile OutFile(OutputFilename, EC, sys::fs::OF_Text);
181-
if (EC)
182-
return reportError(argv0, "error opening " + OutputFilename + ": " +
183-
EC.message() + "\n");
184-
OutFile.os() << OutString;
185-
if (ErrorsPrinted == 0)
186-
OutFile.keep();
192+
if (int Ret = WriteOutput(Parser, argv0, OutputFilename, OutFiles.MainFile))
193+
return Ret;
194+
for (auto [Suffix, Content] : OutFiles.AdditionalFiles) {
195+
SmallString<128> Filename(OutputFilename);
196+
// TODO: Format using the split-file convention when writing to stdout?
197+
if (Filename != "-") {
198+
Filename = FilenamePrefix;
199+
Filename.append(Suffix);
200+
}
201+
if (int Ret = WriteOutput(Parser, argv0, Filename, Content))
202+
return Ret;
187203
}
188204

189205
Timer.stopTimer();
@@ -193,3 +209,15 @@ int llvm::TableGenMain(const char *argv0,
193209
return reportError(argv0, Twine(ErrorsPrinted) + " errors.\n");
194210
return 0;
195211
}
212+
213+
int llvm::TableGenMain(const char *argv0,
214+
std::function<TableGenMainFn> MainFn) {
215+
return TableGenMain(argv0, [&MainFn](TableGenOutputFiles &OutFiles,
216+
const RecordKeeper &Records) {
217+
std::string S;
218+
raw_string_ostream OS(S);
219+
int Res = MainFn(OS, Records);
220+
OutFiles = {S, {}};
221+
return Res;
222+
});
223+
}

llvm/lib/TableGen/TableGenBackend.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,21 @@ Opt::Opt(StringRef Name, FnT CB, StringRef Desc, bool ByDefault) {
6161
/// Apply callback specified on the command line. Returns true if no callback
6262
/// was applied.
6363
bool llvm::TableGen::Emitter::ApplyCallback(const RecordKeeper &Records,
64-
raw_ostream &OS) {
64+
TableGenOutputFiles &OutFiles,
65+
StringRef FilenamePrefix) {
6566
FnT Fn = CallbackFunction->getValue();
66-
if (!Fn)
67-
return true;
68-
Fn(Records, OS);
69-
return false;
67+
if (Fn.SingleFileGenerator) {
68+
std::string S;
69+
raw_string_ostream OS(S);
70+
Fn.SingleFileGenerator(Records, OS);
71+
OutFiles = {S, {}};
72+
return false;
73+
}
74+
if (Fn.MultiFileGenerator) {
75+
OutFiles = Fn.MultiFileGenerator(FilenamePrefix, Records);
76+
return false;
77+
}
78+
return true;
7079
}
7180

7281
static void printLine(raw_ostream &OS, const Twine &Prefix, char Fill,

llvm/lib/Target/AMDGPU/SIFoldOperands.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1358,7 +1358,7 @@ void SIFoldOperandsImpl::foldOperand(
13581358
// Remove this if 16-bit SGPRs (i.e. SGPR_LO16) are added to the
13591359
// VS_16RegClass
13601360
//
1361-
// Excerpt from AMDGPUGenRegisterInfo.inc
1361+
// Excerpt from AMDGPUGenRegisterInfoEnums.inc
13621362
// NoSubRegister, //0
13631363
// hi16, // 1
13641364
// lo16, // 2

llvm/test/TableGen/ArtificialSubregs.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: llvm-tblgen -gen-register-info -register-info-debug -I %p/../../include %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK
1+
// RUN: llvm-tblgen -gen-register-info -register-info-debug -I %p/../../include %s -o - 2>&1 >/dev/null | FileCheck %s --check-prefix=CHECK
22
include "llvm/Target/Target.td"
33

44
// This file tests that when using `isArtificial` for subregisters in

llvm/test/TableGen/ConcatenatedSubregs.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: llvm-tblgen -gen-register-info -register-info-debug -I %p/../../include %s -o /dev/null 2>&1 | FileCheck %s
1+
// RUN: llvm-tblgen -gen-register-info -register-info-debug -I %p/../../include %s -o - 2>&1 >/dev/null | FileCheck %s
22
// Checks that tablegen correctly and completely infers subregister relations.
33
include "llvm/Target/Target.td"
44

llvm/test/TableGen/HwModeBitSet.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// This is to test the scenario where different HwMode attributes coexist.
2-
// RUN: llvm-tblgen -gen-register-info -register-info-debug -I %p/../../include %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-REG
2+
// RUN: llvm-tblgen -gen-register-info -register-info-debug -I %p/../../include %s -o - 2>&1 >/dev/null | FileCheck %s --check-prefix=CHECK-REG
33
// RUN: llvm-tblgen -gen-subtarget -I %p/../../include %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-SUBTARGET
44

55

llvm/test/TableGen/HwModeSubRegs.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: llvm-tblgen -gen-register-info -register-info-debug -I %p/../../include %s -o /dev/null 2>&1 | FileCheck %s
1+
// RUN: llvm-tblgen -gen-register-info -register-info-debug -I %p/../../include %s -o - 2>&1 >/dev/null | FileCheck %s
22
include "llvm/Target/Target.td"
33

44
def HasFeat : Predicate<"Subtarget->hasFeat()">;

0 commit comments

Comments
 (0)