about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-10-08 03:36:37 +0000
committerbors <bors@rust-lang.org>2023-10-08 03:36:37 +0000
commit1516ca1bc01181af73c7b7760fb90137007da75f (patch)
tree290e3dc14afdbdfa633f7a667311bd8cbee72fa5
parentfdf32ee9fcd259913c7dece8f7b915b2d5560a49 (diff)
parent5048f813130f5c50fb95b784ad14ff40477c500b (diff)
downloadrust-1516ca1bc01181af73c7b7760fb90137007da75f.tar.gz
rust-1516ca1bc01181af73c7b7760fb90137007da75f.zip
Auto merge of #116486 - van-ema:master, r=nikic
Fix to register analysis passes with -Zllvm-plugins at link-time

This PR fixes an unexpected behavior of the `-Zllvm-plugins` flag. It allows to run an out-of-tree pass as part of LTO.
However, analysis passes are registered before the plugin is loaded. As a result an analysis pass, which is passed as a plugin, is not registered. This causes the LLVM PassManager to fail when the analysis pass is queried from a transformation pass  [(here)](https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/IR/PassManager.h#L776).

This fix mimics the bahavior in [LLVM LTOBackend.cpp](https://github.com/llvm/llvm-project/blob/main/llvm/lib/LTO/LTOBackend.cpp#L273) by loading the plugin before the analysis passes are registered.

Tested with rustc 1.60 and 1.65 and LLVM-13.0.1.
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp28
1 files changed, 14 insertions, 14 deletions
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index b729c40228b..31565db1b79 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -795,6 +795,20 @@ LLVMRustOptimize(
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
 
+  if (LLVMPluginsLen) {
+    auto PluginsStr = StringRef(LLVMPlugins, LLVMPluginsLen);
+    SmallVector<StringRef> Plugins;
+    PluginsStr.split(Plugins, ',', -1, false);
+    for (auto PluginPath: Plugins) {
+      auto Plugin = PassPlugin::Load(PluginPath.str());
+      if (!Plugin) {
+        LLVMRustSetLastError(("Failed to load pass plugin" + PluginPath.str()).c_str());
+        return LLVMRustResult::Failure;
+      }
+      Plugin->registerPassBuilderCallbacks(PB);
+    }
+  }
+
   FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
 
   Triple TargetTriple(TheModule->getTargetTriple());
@@ -918,20 +932,6 @@ LLVMRustOptimize(
     }
   }
 
-  if (LLVMPluginsLen) {
-    auto PluginsStr = StringRef(LLVMPlugins, LLVMPluginsLen);
-    SmallVector<StringRef> Plugins;
-    PluginsStr.split(Plugins, ',', -1, false);
-    for (auto PluginPath: Plugins) {
-      auto Plugin = PassPlugin::Load(PluginPath.str());
-      if (!Plugin) {
-        LLVMRustSetLastError(("Failed to load pass plugin" + PluginPath.str()).c_str());
-        return LLVMRustResult::Failure;
-      }
-      Plugin->registerPassBuilderCallbacks(PB);
-    }
-  }
-
   ModulePassManager MPM;
   bool NeedThinLTOBufferPasses = UseThinLTOBuffers;
   if (!NoPrepopulatePasses) {