[llvm] [llvm] Support llvm::Any across shared libraries on windows (PR #108051)
Thomas Fransham via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 10 09:22:27 PDT 2024
https://github.com/fsfod created https://github.com/llvm/llvm-project/pull/108051
This is part of the effort to support for enabling plugins on windows by adding better support for building llvm as a DLL. The export macros used here were added in #96630
Since shared library symbols aren't deduplicated across multiple libraries on windows like Linux we have to manually explicitly import and export `Any::TypeId` template instantiations for the uses of `llvm::Any` in the LLVM codebase to support LLVM Windows shared library builds.
This change ensures that external code, including LLVM's own tests, can use PassManager callbacks when LLVM is built as a DLL.
I also removed the only use of llvm::Any for LoopNest that only existed in debug code and there also doesn't seem to be any code creating `Any<LoopNest>`
>From dbf1ac0ad9e0fcf40e5d38757c4378669997d7e2 Mon Sep 17 00:00:00 2001
From: Thomas Fransham <tfransham at gmail.com>
Date: Sat, 7 Sep 2024 15:53:09 +0100
Subject: [PATCH] [llvm] Support llvm::Any across shared libraries on windows
in a limited form
Explicitly import and export Any::TypeId template instantiations for uses of llvm::Any
in the LLVM codebase to support LLVM Windows shared library builds.
This change is required to allow external code to use PassManager callbacks
including LLVM's own tests for it.
Remove the only use of llvm::Any for LoopNest that only existed in debug code and
there was no code creating Any<LoopNest>
---
llvm/include/llvm/Analysis/LazyCallGraph.h | 5 +++++
llvm/include/llvm/IR/PassInstrumentation.h | 12 +++++++++++-
llvm/lib/Analysis/LazyCallGraph.cpp | 4 ++++
llvm/lib/IR/PassInstrumentation.cpp | 6 ++++++
llvm/lib/Transforms/Scalar/LoopPassManager.cpp | 2 --
llvm/unittests/IR/PassBuilderCallbacksTest.cpp | 2 --
6 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/llvm/include/llvm/Analysis/LazyCallGraph.h b/llvm/include/llvm/Analysis/LazyCallGraph.h
index e7fd18967d9bed..55060f506c3330 100644
--- a/llvm/include/llvm/Analysis/LazyCallGraph.h
+++ b/llvm/include/llvm/Analysis/LazyCallGraph.h
@@ -34,6 +34,7 @@
#ifndef LLVM_ANALYSIS_LAZYCALLGRAPH_H
#define LLVM_ANALYSIS_LAZYCALLGRAPH_H
+#include "llvm/ADT/Any.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
@@ -1308,6 +1309,10 @@ class LazyCallGraphDOTPrinterPass
static bool isRequired() { return true; }
};
+#ifdef _WIN32
+extern template struct LLVM_TEMPLATE_ABI
+ Any::TypeId<const LazyCallGraph::SCC *>;
+#endif
} // end namespace llvm
#endif // LLVM_ANALYSIS_LAZYCALLGRAPH_H
diff --git a/llvm/include/llvm/IR/PassInstrumentation.h b/llvm/include/llvm/IR/PassInstrumentation.h
index 9fcc2d5957a30c..c41c287f5f1e99 100644
--- a/llvm/include/llvm/IR/PassInstrumentation.h
+++ b/llvm/include/llvm/IR/PassInstrumentation.h
@@ -50,10 +50,11 @@
#define LLVM_IR_PASSINSTRUMENTATION_H
#include "llvm/ADT/Any.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FunctionExtras.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Support/Compiler.h"
#include <type_traits>
#include <vector>
@@ -61,6 +62,15 @@ namespace llvm {
class PreservedAnalyses;
class StringRef;
+class Module;
+class Loop;
+class Function;
+
+#ifdef _WIN32
+extern template struct LLVM_TEMPLATE_ABI Any::TypeId<const Module *>;
+extern template struct LLVM_TEMPLATE_ABI Any::TypeId<const Function *>;
+extern template struct LLVM_TEMPLATE_ABI Any::TypeId<const Loop *>;
+#endif
/// This class manages callbacks registration, as well as provides a way for
/// PassInstrumentation to pass control to the registered callbacks.
diff --git a/llvm/lib/Analysis/LazyCallGraph.cpp b/llvm/lib/Analysis/LazyCallGraph.cpp
index e6bf8c9cbb289f..9d74bce98122bb 100644
--- a/llvm/lib/Analysis/LazyCallGraph.cpp
+++ b/llvm/lib/Analysis/LazyCallGraph.cpp
@@ -37,6 +37,10 @@ using namespace llvm;
#define DEBUG_TYPE "lcg"
+#ifdef _WIN32
+template struct LLVM_EXPORT_TEMPLATE Any::TypeId<const LazyCallGraph::SCC *>;
+#endif
+
void LazyCallGraph::EdgeSequence::insertEdgeInternal(Node &TargetN,
Edge::Kind EK) {
EdgeIndexMap.try_emplace(&TargetN, Edges.size());
diff --git a/llvm/lib/IR/PassInstrumentation.cpp b/llvm/lib/IR/PassInstrumentation.cpp
index 0c4e7698d9fa87..134990eee26988 100644
--- a/llvm/lib/IR/PassInstrumentation.cpp
+++ b/llvm/lib/IR/PassInstrumentation.cpp
@@ -17,6 +17,12 @@
namespace llvm {
+#ifdef _WIN32
+template struct LLVM_EXPORT_TEMPLATE Any::TypeId<const Module *>;
+template struct LLVM_EXPORT_TEMPLATE Any::TypeId<const Function *>;
+template struct LLVM_EXPORT_TEMPLATE Any::TypeId<const Loop *>;
+#endif
+
void PassInstrumentationCallbacks::addClassToPassName(StringRef ClassName,
StringRef PassName) {
ClassToPassName.try_emplace(ClassName, PassName.str());
diff --git a/llvm/lib/Transforms/Scalar/LoopPassManager.cpp b/llvm/lib/Transforms/Scalar/LoopPassManager.cpp
index a4f2dbf9a58289..cc1921d61791a4 100644
--- a/llvm/lib/Transforms/Scalar/LoopPassManager.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopPassManager.cpp
@@ -273,8 +273,6 @@ PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F,
llvm::any_cast<const LoopNest *>(&IR));
const Loop **LPtr = llvm::any_cast<const Loop *>(&IR);
const Loop *L = LPtr ? *LPtr : nullptr;
- if (!L)
- L = &llvm::any_cast<const LoopNest *>(IR)->getOutermostLoop();
assert(L && "Loop should be valid for printing");
// Verify the loop structure and LCSSA form before visiting the loop.
diff --git a/llvm/unittests/IR/PassBuilderCallbacksTest.cpp b/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
index 6230aed7b7119b..9aad6e3ca91255 100644
--- a/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
+++ b/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
@@ -298,8 +298,6 @@ template <> std::string getName(const Any &WrappedIR) {
return (*F)->getName().str();
if (const auto *const *L = llvm::any_cast<const Loop *>(&WrappedIR))
return (*L)->getName().str();
- if (const auto *const *L = llvm::any_cast<const LoopNest *>(&WrappedIR))
- return (*L)->getName().str();
if (const auto *const *C =
llvm::any_cast<const LazyCallGraph::SCC *>(&WrappedIR))
return (*C)->getName();
More information about the llvm-commits
mailing list