From 7761ab1ad8eee08fa86aba04e89f7aab5064cb4f Mon Sep 17 00:00:00 2001 From: Thomas Fransham Date: Sat, 7 Sep 2024 15:53:09 +0100 Subject: [PATCH 1/8] [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 --- 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 e7fd18967d9be..55060f506c333 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; +#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 9fcc2d5957a30..c41c287f5f1e9 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 #include @@ -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; +extern template struct LLVM_TEMPLATE_ABI Any::TypeId; +extern template struct LLVM_TEMPLATE_ABI Any::TypeId; +#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 e6bf8c9cbb289..9d74bce98122b 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; +#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 0c4e7698d9fa8..134990eee2698 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; +template struct LLVM_EXPORT_TEMPLATE Any::TypeId; +template struct LLVM_EXPORT_TEMPLATE Any::TypeId; +#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 5ef25c21162fe..3b08d5889edb1 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(&IR)); const Loop **LPtr = llvm::any_cast(&IR); const Loop *L = LPtr ? *LPtr : nullptr; - if (!L) - L = &llvm::any_cast(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 6230aed7b7119..9aad6e3ca9125 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(&WrappedIR)) return (*L)->getName().str(); - if (const auto *const *L = llvm::any_cast(&WrappedIR)) - return (*L)->getName().str(); if (const auto *const *C = llvm::any_cast(&WrappedIR)) return (*C)->getName(); From 90bdee97a72018974305b436c2b915fec597bb74 Mon Sep 17 00:00:00 2001 From: Thomas Fransham Date: Wed, 11 Sep 2024 14:55:53 +0100 Subject: [PATCH 2/8] 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 55060f506c333..289e9c3990bcc 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; -#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 c41c287f5f1e9..45ee372e7959d 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; extern template struct LLVM_TEMPLATE_ABI Any::TypeId; extern template struct LLVM_TEMPLATE_ABI Any::TypeId; -#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 9d74bce98122b..5aa36bfc36d46 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; -#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 134990eee2698..94ad124a6c770 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; template struct LLVM_EXPORT_TEMPLATE Any::TypeId; template struct LLVM_EXPORT_TEMPLATE Any::TypeId; -#endif void PassInstrumentationCallbacks::addClassToPassName(StringRef ClassName, StringRef PassName) { From 00ac0c1cb997b9d61b3eb5a962fd89ef352b9c4b Mon Sep 17 00:00:00 2001 From: Thomas Fransham Date: Thu, 10 Oct 2024 16:43:18 +0100 Subject: [PATCH 3/8] Remove assert testing for a Any --- 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 3b08d5889edb1..d3bcfb8cc6404 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(&IR) || - llvm::any_cast(&IR)); + assert(llvm::any_cast(&IR)); const Loop **LPtr = llvm::any_cast(&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 Date: Tue, 15 Oct 2024 00:14:13 +0100 Subject: [PATCH 4/8] 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 e6efde091871f..8261dcf828665 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; +}; + namespace clang { namespace dataflow { diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index 8afd18b315d28..560367c6f84f6 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; +} + namespace clang { namespace dataflow { From 662a96b77124da89d527410e6d383f32a6204fc1 Mon Sep 17 00:00:00 2001 From: Thomas Fransham Date: Tue, 15 Oct 2024 19:10:40 +0100 Subject: [PATCH 5/8] 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 8261dcf828665..e6efde091871f 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; -}; - namespace clang { namespace dataflow { diff --git a/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h b/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h index 0192193281119..9db3a758fa5a1 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 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; +}; + #endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H From b487d595bb8917a643fa953f4f7f4ea712f5945a Mon Sep 17 00:00:00 2001 From: Thomas Fransham Date: Wed, 23 Oct 2024 19:08:41 +0100 Subject: [PATCH 6/8] Add comment for Any::TypeId --- 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 9db3a758fa5a1..9e63cb50947b2 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; }; diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index 560367c6f84f6..80e94f631cbba 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; } From 455dea18edc97cdc4286211907a71a02fbd7ed33 Mon Sep 17 00:00:00 2001 From: Thomas Fransham Date: Wed, 23 Oct 2024 19:14:45 +0100 Subject: [PATCH 7/8] 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 80e94f631cbba..32b3886439495 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; -} +} // namespace llvm namespace clang { namespace dataflow { From 80efa6abe664674a24988fd798e71ee2eed45fd6 Mon Sep 17 00:00:00 2001 From: Thomas Fransham Date: Wed, 23 Oct 2024 20:13:03 +0100 Subject: [PATCH 8/8] Fix the right file --- clang/include/clang/Analysis/FlowSensitive/NoopLattice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h b/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h index 9e63cb50947b2..6cc00680eab79 100644 --- a/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h +++ b/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h @@ -46,6 +46,6 @@ namespace llvm { // CLANG_LINK_CLANG_DYLIB extern template struct CLANG_TEMPLATE_ABI Any::TypeId; -}; +}; // namespace llvm #endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H