[llvm] [llvm] Support llvm::Any across shared libraries on windows (PR #108051)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 10 09:23:06 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Thomas Fransham (fsfod)
<details>
<summary>Changes</summary>
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>`
---
Full diff: https://github.com/llvm/llvm-project/pull/108051.diff
6 Files Affected:
- (modified) llvm/include/llvm/Analysis/LazyCallGraph.h (+5)
- (modified) llvm/include/llvm/IR/PassInstrumentation.h (+11-1)
- (modified) llvm/lib/Analysis/LazyCallGraph.cpp (+4)
- (modified) llvm/lib/IR/PassInstrumentation.cpp (+6)
- (modified) llvm/lib/Transforms/Scalar/LoopPassManager.cpp (-2)
- (modified) llvm/unittests/IR/PassBuilderCallbacksTest.cpp (-2)
``````````diff
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();
``````````
</details>
https://github.com/llvm/llvm-project/pull/108051
More information about the llvm-commits
mailing list