|
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