[clang] [llvm] [llvm] Support llvm::Any across shared libraries on windows (PR #108051)

Thomas Fransham via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 23 11:15:03 PDT 2024


https://github.com/fsfod updated https://github.com/llvm/llvm-project/pull/108051

>From 7761ab1ad8eee08fa86aba04e89f7aab5064cb4f 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 1/7] [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 5ef25c21162fe2..3b08d5889edb12 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();

>From 90bdee97a72018974305b436c2b915fec597bb74 Mon Sep 17 00:00:00 2001
From: Thomas Fransham <tfransham at gmail.com>
Date: Wed, 11 Sep 2024 14:55:53 +0100
Subject: [PATCH 2/7] Just enable the extern template declarations and
 definitions on all platforms

---
 llvm/include/llvm/Analysis/LazyCallGraph.h | 2 --
 llvm/include/llvm/IR/PassInstrumentation.h | 2 --
 llvm/lib/Analysis/LazyCallGraph.cpp        | 2 --
 llvm/lib/IR/PassInstrumentation.cpp        | 2 --
 4 files changed, 8 deletions(-)

diff --git a/llvm/include/llvm/Analysis/LazyCallGraph.h b/llvm/include/llvm/Analysis/LazyCallGraph.h
index 55060f506c3330..289e9c3990bcc6 100644
--- a/llvm/include/llvm/Analysis/LazyCallGraph.h
+++ b/llvm/include/llvm/Analysis/LazyCallGraph.h
@@ -1309,10 +1309,8 @@ 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 c41c287f5f1e99..45ee372e7959d1 100644
--- a/llvm/include/llvm/IR/PassInstrumentation.h
+++ b/llvm/include/llvm/IR/PassInstrumentation.h
@@ -66,11 +66,9 @@ 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 9d74bce98122bb..5aa36bfc36d468 100644
--- a/llvm/lib/Analysis/LazyCallGraph.cpp
+++ b/llvm/lib/Analysis/LazyCallGraph.cpp
@@ -37,9 +37,7 @@ 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) {
diff --git a/llvm/lib/IR/PassInstrumentation.cpp b/llvm/lib/IR/PassInstrumentation.cpp
index 134990eee26988..94ad124a6c770a 100644
--- a/llvm/lib/IR/PassInstrumentation.cpp
+++ b/llvm/lib/IR/PassInstrumentation.cpp
@@ -17,11 +17,9 @@
 
 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) {

>From 00ac0c1cb997b9d61b3eb5a962fd89ef352b9c4b Mon Sep 17 00:00:00 2001
From: Thomas Fransham <tfransham at gmail.com>
Date: Thu, 10 Oct 2024 16:43:18 +0100
Subject: [PATCH 3/7] Remove assert testing for a Any<const LoopNest>

---
 llvm/lib/Transforms/Scalar/LoopPassManager.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/LoopPassManager.cpp b/llvm/lib/Transforms/Scalar/LoopPassManager.cpp
index 3b08d5889edb12..d3bcfb8cc64044 100644
--- a/llvm/lib/Transforms/Scalar/LoopPassManager.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopPassManager.cpp
@@ -269,8 +269,7 @@ PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F,
   PI.pushBeforeNonSkippedPassCallback([&LAR, &LI](StringRef PassID, Any IR) {
     if (isSpecialPass(PassID, {"PassManager"}))
       return;
-    assert(llvm::any_cast<const Loop *>(&IR) ||
-           llvm::any_cast<const LoopNest *>(&IR));
+    assert(llvm::any_cast<const Loop *>(&IR));
     const Loop **LPtr = llvm::any_cast<const Loop *>(&IR);
     const Loop *L = LPtr ? *LPtr : nullptr;
     assert(L && "Loop should be valid for printing");

>From 7f3ab129a7062df7325b8e733277df785c2212c7 Mon Sep 17 00:00:00 2001
From: Thomas Fransham <tfransham at gmail.com>
Date: Tue, 15 Oct 2024 00:14:13 +0100
Subject: [PATCH 4/7] Fix missing export of Any::TypeId for
 clang::dataflow::NoopLattice

---
 .../clang/Analysis/FlowSensitive/DataflowAnalysis.h  | 12 ++++++++++++
 .../FlowSensitive/TypeErasedDataflowAnalysis.cpp     | 11 +++++++++++
 2 files changed, 23 insertions(+)

diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
index e6efde091871fc..8261dcf8286659 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
@@ -28,12 +28,24 @@
 #include "clang/Analysis/FlowSensitive/MatchSwitch.h"
 #include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
 #include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
+#include "clang/Support/Compiler.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/STLFunctionalExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Error.h"
 
+namespace clang {
+namespace dataflow {
+class NoopLattice;
+}
+}
+
+namespace llvm {
+extern template struct CLANG_TEMPLATE_ABI
+    Any::TypeId<clang::dataflow::NoopLattice>;
+};
+
 namespace clang {
 namespace dataflow {
 
diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
index 8afd18b315d286..560367c6f84f6f 100644
--- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
+++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
@@ -30,6 +30,7 @@
 #include "clang/Analysis/FlowSensitive/Transfer.h"
 #include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
 #include "clang/Analysis/FlowSensitive/Value.h"
+#include "clang/Support/Compiler.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Debug.h"
@@ -37,6 +38,16 @@
 
 #define DEBUG_TYPE "clang-dataflow"
 
+namespace clang {
+namespace dataflow {
+class NoopLattice;
+}
+} // namespace clang
+
+namespace llvm {
+template struct CLANG_EXPORT_TEMPLATE Any::TypeId<clang::dataflow::NoopLattice>;
+}
+
 namespace clang {
 namespace dataflow {
 

>From 662a96b77124da89d527410e6d383f32a6204fc1 Mon Sep 17 00:00:00 2001
From: Thomas Fransham <tfransham at gmail.com>
Date: Tue, 15 Oct 2024 19:10:40 +0100
Subject: [PATCH 5/7] Move extern template definition for NoopLattice's
 Any::TypeId

---
 .../clang/Analysis/FlowSensitive/DataflowAnalysis.h  | 12 ------------
 .../clang/Analysis/FlowSensitive/NoopLattice.h       |  6 ++++++
 2 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
index 8261dcf8286659..e6efde091871fc 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
@@ -28,24 +28,12 @@
 #include "clang/Analysis/FlowSensitive/MatchSwitch.h"
 #include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
 #include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
-#include "clang/Support/Compiler.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/STLFunctionalExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Error.h"
 
-namespace clang {
-namespace dataflow {
-class NoopLattice;
-}
-}
-
-namespace llvm {
-extern template struct CLANG_TEMPLATE_ABI
-    Any::TypeId<clang::dataflow::NoopLattice>;
-};
-
 namespace clang {
 namespace dataflow {
 
diff --git a/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h b/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
index 01921932811198..9db3a758fa5a14 100644
--- a/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
+++ b/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
@@ -14,6 +14,7 @@
 #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H
 
 #include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "llvm/ADT/Any.h"
 #include <ostream>
 
 namespace clang {
@@ -38,4 +39,9 @@ inline std::ostream &operator<<(std::ostream &OS, const NoopLattice &) {
 } // namespace dataflow
 } // namespace clang
 
+namespace llvm {
+extern template struct CLANG_TEMPLATE_ABI
+    Any::TypeId<clang::dataflow::NoopLattice>;
+};
+
 #endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H

>From b487d595bb8917a643fa953f4f7f4ea712f5945a Mon Sep 17 00:00:00 2001
From: Thomas Fransham <tfransham at gmail.com>
Date: Wed, 23 Oct 2024 19:08:41 +0100
Subject: [PATCH 6/7] Add comment for Any::TypeId<clang::dataflow::NoopLattice>

---
 clang/include/clang/Analysis/FlowSensitive/NoopLattice.h      | 4 ++++
 .../lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h b/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
index 9db3a758fa5a14..9e63cb50947b21 100644
--- a/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
+++ b/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
@@ -40,6 +40,10 @@ inline std::ostream &operator<<(std::ostream &OS, const NoopLattice &) {
 } // namespace clang
 
 namespace llvm {
+// This needs to be exported for ClangAnalysisFlowSensitiveTests so any_cast
+// uses the correct address of Any::TypeId from the clang shared library instead
+// of creating one in the test executable. when building with
+// CLANG_LINK_CLANG_DYLIB
 extern template struct CLANG_TEMPLATE_ABI
     Any::TypeId<clang::dataflow::NoopLattice>;
 };
diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
index 560367c6f84f6f..80e94f631cbba1 100644
--- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
+++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
@@ -45,6 +45,10 @@ class NoopLattice;
 } // namespace clang
 
 namespace llvm {
+// This needs to be exported for ClangAnalysisFlowSensitiveTests so any_cast
+// uses the correct address of Any::TypeId from the clang shared library instead
+// of creating one in the test executable. when building with
+// CLANG_LINK_CLANG_DYLIB
 template struct CLANG_EXPORT_TEMPLATE Any::TypeId<clang::dataflow::NoopLattice>;
 }
 

>From 455dea18edc97cdc4286211907a71a02fbd7ed33 Mon Sep 17 00:00:00 2001
From: Thomas Fransham <tfransham at gmail.com>
Date: Wed, 23 Oct 2024 19:14:45 +0100
Subject: [PATCH 7/7] Fix formatting

---
 clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
index 80e94f631cbba1..32b3886439495f 100644
--- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
+++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
@@ -50,7 +50,7 @@ namespace llvm {
 // of creating one in the test executable. when building with
 // CLANG_LINK_CLANG_DYLIB
 template struct CLANG_EXPORT_TEMPLATE Any::TypeId<clang::dataflow::NoopLattice>;
-}
+} // namespace llvm
 
 namespace clang {
 namespace dataflow {



More information about the cfe-commits mailing list