|
69 | 69 | #include "llvm/MC/TargetRegistry.h"
|
70 | 70 | #include "llvm/Object/ObjectFile.h"
|
71 | 71 | #include "llvm/Passes/PassBuilder.h"
|
| 72 | +#include "llvm/Passes/PassPlugin.h" |
72 | 73 | #include "llvm/Passes/StandardInstrumentations.h"
|
73 | 74 | #include "llvm/Support/CommandLine.h"
|
74 | 75 | #include "llvm/Support/Debug.h"
|
@@ -233,7 +234,21 @@ static void populatePGOOptions(std::optional<PGOOptions> &Out,
|
233 | 234 | }
|
234 | 235 | }
|
235 | 236 |
|
| 237 | +template <typename... ArgTypes> |
| 238 | +void diagnoseSync( |
| 239 | + DiagnosticEngine &Diags, llvm::sys::Mutex *DiagMutex, SourceLoc Loc, |
| 240 | + Diag<ArgTypes...> ID, |
| 241 | + typename swift::detail::PassArgument<ArgTypes>::type... Args) { |
| 242 | + std::optional<llvm::sys::ScopedLock> Lock; |
| 243 | + if (DiagMutex) |
| 244 | + Lock.emplace(*DiagMutex); |
| 245 | + |
| 246 | + Diags.diagnose(Loc, ID, std::move(Args)...); |
| 247 | +} |
| 248 | + |
236 | 249 | void swift::performLLVMOptimizations(const IRGenOptions &Opts,
|
| 250 | + DiagnosticEngine &Diags, |
| 251 | + llvm::sys::Mutex *DiagMutex, |
237 | 252 | llvm::Module *Module,
|
238 | 253 | llvm::TargetMachine *TargetMachine,
|
239 | 254 | llvm::raw_pwrite_stream *out) {
|
@@ -279,6 +294,18 @@ void swift::performLLVMOptimizations(const IRGenOptions &Opts,
|
279 | 294 |
|
280 | 295 | PassBuilder PB(TargetMachine, PTO, PGOOpt, &PIC);
|
281 | 296 |
|
| 297 | + // Attempt to load pass plugins and register their callbacks with PB. |
| 298 | + for (const auto &PluginFile : Opts.LLVMPassPlugins) { |
| 299 | + Expected<PassPlugin> PassPlugin = PassPlugin::Load(PluginFile); |
| 300 | + if (PassPlugin) { |
| 301 | + PassPlugin->registerPassBuilderCallbacks(PB); |
| 302 | + } else { |
| 303 | + diagnoseSync(Diags, DiagMutex, SourceLoc(), |
| 304 | + diag::unable_to_load_pass_plugin, PluginFile, |
| 305 | + toString(PassPlugin.takeError())); |
| 306 | + } |
| 307 | + } |
| 308 | + |
282 | 309 | // Register the AA manager first so that our version is the one used.
|
283 | 310 | FAM.registerPass([&] {
|
284 | 311 | auto AA = PB.buildDefaultAAPipeline();
|
@@ -565,20 +592,6 @@ static void countStatsPostIRGen(UnifiedStatsReporter &Stats,
|
565 | 592 | }
|
566 | 593 | }
|
567 | 594 |
|
568 |
| -template<typename ...ArgTypes> |
569 |
| -void |
570 |
| -diagnoseSync(DiagnosticEngine &Diags, llvm::sys::Mutex *DiagMutex, |
571 |
| - SourceLoc Loc, Diag<ArgTypes...> ID, |
572 |
| - typename swift::detail::PassArgument<ArgTypes>::type... Args) { |
573 |
| - if (DiagMutex) |
574 |
| - DiagMutex->lock(); |
575 |
| - |
576 |
| - Diags.diagnose(Loc, ID, std::move(Args)...); |
577 |
| - |
578 |
| - if (DiagMutex) |
579 |
| - DiagMutex->unlock(); |
580 |
| -} |
581 |
| - |
582 | 595 | /// Run the LLVM passes. In multi-threaded compilation this will be done for
|
583 | 596 | /// multiple LLVM modules in parallel.
|
584 | 597 | bool swift::performLLVM(const IRGenOptions &Opts,
|
@@ -647,7 +660,7 @@ bool swift::performLLVM(const IRGenOptions &Opts,
|
647 | 660 | assert(Opts.OutputKind == IRGenOutputKind::Module && "no output specified");
|
648 | 661 | }
|
649 | 662 |
|
650 |
| - performLLVMOptimizations(Opts, Module, TargetMachine, |
| 663 | + performLLVMOptimizations(Opts, Diags, DiagMutex, Module, TargetMachine, |
651 | 664 | OutputFile ? &OutputFile->getOS() : nullptr);
|
652 | 665 |
|
653 | 666 | if (Stats) {
|
@@ -1779,7 +1792,7 @@ GeneratedModule OptimizedIRRequest::evaluate(Evaluator &evaluator,
|
1779 | 1792 | if (!irMod)
|
1780 | 1793 | return irMod;
|
1781 | 1794 |
|
1782 |
| - performLLVMOptimizations(desc.Opts, irMod.getModule(), |
| 1795 | + performLLVMOptimizations(desc.Opts, ctx.Diags, nullptr, irMod.getModule(), |
1783 | 1796 | irMod.getTargetMachine(), desc.out);
|
1784 | 1797 | return irMod;
|
1785 | 1798 | }
|
|
0 commit comments