Skip to content

Commit 89e9b4a

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.5-bogner
1 parent 36819ea commit 89e9b4a

File tree

3 files changed

+49
-20
lines changed

3 files changed

+49
-20
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ class EmitAssemblyHelper {
144144
const LangOptions &LangOpts;
145145
llvm::Module *TheModule;
146146
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS;
147+
llvm::SmallVector<llvm::PassPlugin> Plugins;
147148

148149
std::unique_ptr<raw_pwrite_stream> OS;
149150

@@ -973,16 +974,9 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
973974
}
974975
#endif
975976
}
976-
// Attempt to load pass plugins and register their callbacks with PB.
977-
for (auto &PluginFN : CodeGenOpts.PassPlugins) {
978-
auto PassPlugin = PassPlugin::Load(PluginFN);
979-
if (PassPlugin) {
980-
PassPlugin->registerPassBuilderCallbacks(PB);
981-
} else {
982-
Diags.Report(diag::err_fe_unable_to_load_plugin)
983-
<< PluginFN << toString(PassPlugin.takeError());
984-
}
985-
}
977+
// Register plugin callbacks with PB.
978+
for (auto &Plugin : Plugins)
979+
Plugin.registerPassBuilderCallbacks(PB);
986980
for (const auto &PassCallback : CodeGenOpts.PassBuilderCallbacks)
987981
PassCallback(PB);
988982
#define HANDLE_EXTENSION(Ext) \
@@ -1211,6 +1205,14 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
12111205
void EmitAssemblyHelper::RunCodegenPipeline(
12121206
BackendAction Action, std::unique_ptr<raw_pwrite_stream> &OS,
12131207
std::unique_ptr<llvm::ToolOutputFile> &DwoOS) {
1208+
// Invoke pre-codegen callback from plugin, which might want to take over the
1209+
// entire code generation itself.
1210+
for (auto &Plugin : Plugins) {
1211+
CodeGenFileType CGFT = getCodeGenFileType(Action);
1212+
if (Plugin.invokePreCodeGenCallback(*TheModule, *TM, CGFT, *OS))
1213+
return;
1214+
}
1215+
12141216
// We still use the legacy PM to run the codegen pipeline since the new PM
12151217
// does not work with the codegen pipeline.
12161218
// FIXME: make the new PM work with the codegen pipeline.
@@ -1274,6 +1276,17 @@ void EmitAssemblyHelper::emitAssembly(BackendAction Action,
12741276
// Before executing passes, print the final values of the LLVM options.
12751277
cl::PrintOptionValues();
12761278

1279+
// Attempt to load pass plugins.
1280+
for (auto &PluginFN : CodeGenOpts.PassPlugins) {
1281+
auto PassPlugin = PassPlugin::Load(PluginFN);
1282+
if (PassPlugin) {
1283+
Plugins.push_back(std::move(*PassPlugin));
1284+
} else {
1285+
Diags.Report(diag::err_fe_unable_to_load_plugin)
1286+
<< PluginFN << toString(PassPlugin.takeError());
1287+
}
1288+
}
1289+
12771290
std::unique_ptr<llvm::ToolOutputFile> ThinLinkOS, DwoOS;
12781291
RunOptimizationPipeline(Action, OS, ThinLinkOS, BC);
12791292
RunCodegenPipeline(Action, OS, DwoOS);

llvm/include/llvm/Passes/PassPlugin.h

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,17 @@
1414
#define LLVM_PASSES_PASSPLUGIN_H
1515

1616
#include "llvm/ADT/StringRef.h"
17+
#include "llvm/Support/CodeGen.h"
1718
#include "llvm/Support/Compiler.h"
1819
#include "llvm/Support/DynamicLibrary.h"
1920
#include "llvm/Support/Error.h"
2021
#include <cstdint>
2122
#include <string>
2223

2324
namespace llvm {
25+
class Module;
2426
class PassBuilder;
27+
class TargetMachine;
2528

2629
/// \macro LLVM_PLUGIN_API_VERSION
2730
/// Identifies the API version understood by this plugin.
@@ -30,14 +33,15 @@ class PassBuilder;
3033
/// against that of the plugin. A mismatch is an error. The supported version
3134
/// will be incremented for ABI-breaking changes to the \c PassPluginLibraryInfo
3235
/// struct, i.e. when callbacks are added, removed, or reordered.
33-
#define LLVM_PLUGIN_API_VERSION 1
36+
#define LLVM_PLUGIN_API_VERSION 2
3437

3538
extern "C" {
3639
/// Information about the plugin required to load its passes
3740
///
3841
/// This struct defines the core interface for pass plugins and is supposed to
39-
/// be filled out by plugin implementors. LLVM-side users of a plugin are
40-
/// expected to use the \c PassPlugin class below to interface with it.
42+
/// be filled out by plugin implementors. Unused function pointers can be set to
43+
/// nullptr. LLVM-side users of a plugin are expected to use the \c PassPlugin
44+
/// class below to interface with it.
4145
struct PassPluginLibraryInfo {
4246
/// The API version understood by this plugin, usually \c
4347
/// LLVM_PLUGIN_API_VERSION
@@ -49,7 +53,14 @@ struct PassPluginLibraryInfo {
4953

5054
/// The callback for registering plugin passes with a \c PassBuilder
5155
/// instance
52-
void (*RegisterPassBuilderCallbacks)(PassBuilder &);
56+
void (*RegisterPassBuilderCallbacks)(PassBuilder &) = nullptr;
57+
58+
/// Callback called before running the back-end passes on the module. The
59+
/// callback can generate code itself by writing the expected output to OS and
60+
/// returning true to prevent the default pipeline and further plugin
61+
/// callbacks from running.
62+
bool (*PreCodeGenCallback)(Module &, TargetMachine &, CodeGenFileType,
63+
raw_pwrite_stream &OS) = nullptr;
5364
};
5465
}
5566

@@ -80,7 +91,17 @@ class PassPlugin {
8091

8192
/// Invoke the PassBuilder callback registration
8293
void registerPassBuilderCallbacks(PassBuilder &PB) const {
83-
Info.RegisterPassBuilderCallbacks(PB);
94+
if (Info.RegisterPassBuilderCallbacks)
95+
Info.RegisterPassBuilderCallbacks(PB);
96+
}
97+
98+
/// Invoke the pre-codegen callback.
99+
bool invokePreCodeGenCallback(Module &M, TargetMachine &TM,
100+
CodeGenFileType CGFT,
101+
raw_pwrite_stream &OS) const {
102+
if (Info.PreCodeGenCallback)
103+
return Info.PreCodeGenCallback(M, TM, CGFT, OS);
104+
return false;
84105
}
85106

86107
private:

llvm/lib/Passes/PassPlugin.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,5 @@ Expected<PassPlugin> PassPlugin::Load(const std::string &Filename) {
4545
Twine(LLVM_PLUGIN_API_VERSION) + ".",
4646
inconvertibleErrorCode());
4747

48-
if (!P.Info.RegisterPassBuilderCallbacks)
49-
return make_error<StringError>(Twine("Empty entry callback in plugin '") +
50-
Filename + "'.'",
51-
inconvertibleErrorCode());
52-
5348
return P;
5449
}

0 commit comments

Comments
 (0)