[llvm] [CodeGen] Expose the extensibility of PassConfig to plugins (PR #139059)
Stefan Gränitz via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 2 08:44:06 PDT 2025
================
@@ -0,0 +1,114 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugin/CodeGenTestPass.h"
+
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/Config/config.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+void anchor() {}
+
+std::optional<std::string> libPath(const std::string &Name) {
+ const auto &Argvs = testing::internal::GetArgvs();
+ if (Argvs.size() <= 0)
+ return std::nullopt;
+ void *Ptr = (void *)(intptr_t)anchor;
+ std::string Path = sys::fs::getMainExecutable(Argvs[0].c_str(), Ptr);
+ SmallString<256> Buf{sys::path::parent_path(Path)};
+ sys::path::append(Buf, (Name + LLVM_PLUGIN_EXT).c_str());
+ return std::string(Buf.str());
+}
+} // namespace
+
+namespace llvm {
+class CGPluginTests : public testing::Test {
+protected:
+ static void SetUpTestCase() {
+ InitializeAllTargetMCs();
+ InitializeAllTargetInfos();
+ InitializeAllTargets();
+ }
+};
+} // namespace llvm
+
+TEST_F(CGPluginTests, LoadPlugin) {
+#if !defined(LLVM_ENABLE_PLUGINS)
+ // Skip the test if plugins are disabled.
+ GTEST_SKIP();
+#endif
+
+ auto PluginPath = libPath("CGTestPlugin");
+ ASSERT_TRUE(PluginPath.has_value());
+ ASSERT_NE("", PluginPath);
+
+ ASSERT_EQ(TargetMachine::TargetPassConfigCallbacks->size(), 0u);
+ std::string Error;
+ auto Library =
+ sys::DynamicLibrary::getPermanentLibrary(PluginPath->c_str(), &Error);
+ ASSERT_TRUE(Library.isValid()) << Error;
+ ASSERT_EQ(TargetMachine::TargetPassConfigCallbacks->size(), 1u);
+ TargetMachine::TargetPassConfigCallbacks->clear();
+}
+
+TEST_F(CGPluginTests, ExecuteCallback) {
+#if !defined(LLVM_ENABLE_PLUGINS)
+ // Skip the test if plugins are disabled.
+ GTEST_SKIP();
+#endif
+
+ volatile bool CallbackExecuted = false;
+ volatile bool MPassExecuted = false;
+
+ ASSERT_EQ(TargetMachine::TargetPassConfigCallbacks->size(), 0u);
+ TargetMachine::registerTargetPassConfigCallback(
+ [&](auto &TM, auto &PM, auto *TPC) {
+ CallbackExecuted = true;
+ TPC->insertPass(&GCLoweringID, &CodeGenTest::ID);
+ });
+ ASSERT_EQ(TargetMachine::TargetPassConfigCallbacks->size(), 1u);
+
+ CodeGenTest::RunCallback = [&] { MPassExecuted = true; };
+
+ TargetOptions Options;
+ std::unique_ptr<MCContext> MCC;
+ for (auto T : TargetRegistry::targets()) {
+ if (!T.hasTargetMachine())
+ continue;
+ Triple TT{T.getName(), "", ""};
+ auto *TM = T.createTargetMachine(TT, "", "", Options, std::nullopt,
+ std::nullopt, CodeGenOptLevel::Default);
+ ASSERT_TRUE(TM);
+
+ legacy::PassManager PM;
+ MCC.reset(new MCContext(TT, TM->getMCAsmInfo(), TM->getMCRegisterInfo(),
+ TM->getMCSubtargetInfo()));
+ auto *PtrMCC = MCC.get();
+ CallbackExecuted = false;
+ MPassExecuted = false;
+ if (TM->addPassesToEmitMC(PM, PtrMCC, outs()) == true)
+ continue;
+ ASSERT_TRUE(CallbackExecuted) << T.getName() << " callback failed";
+ ASSERT_TRUE(MPassExecuted) << T.getName() << " MachinePass failed";
+ }
+
+ TargetMachine::TargetPassConfigCallbacks->clear();
+}
----------------
weliveindetail wrote:
FYI: test passes for me on Ubuntu 22.04 with this config
```
> cmake -Sllvm -Bbuild -GNinja -DLLVM_BUILD_LLVM_DYLIB=On -DLLVM_LINK_LLVM_DYLIB=On ...
> ninja -C build CGPluginTest FileCheck llvm-config llc count not
> cd build && bin/llvm-lit -a --filter=codegen-plugin test
```
The `LLVM_DYLIB` options enable the LLVM shared library. This simplifies compatibility, because we always link the same ABI, even if we load the plugin e.g. in clang. It correctly shows up as unsupported without these options.
https://github.com/llvm/llvm-project/pull/139059
More information about the llvm-commits
mailing list