Skip to content

Commit b8fddca

Browse files
authored
[llvm] Support llvm::Any across shared libraries on windows (#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>`
1 parent 04f14e4 commit b8fddca

File tree

8 files changed

+44
-7
lines changed

8 files changed

+44
-7
lines changed

clang/include/clang/Analysis/FlowSensitive/NoopLattice.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H
1515

1616
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
17+
#include "llvm/ADT/Any.h"
1718
#include <ostream>
1819

1920
namespace clang {
@@ -38,4 +39,13 @@ inline std::ostream &operator<<(std::ostream &OS, const NoopLattice &) {
3839
} // namespace dataflow
3940
} // namespace clang
4041

42+
namespace llvm {
43+
// This needs to be exported for ClangAnalysisFlowSensitiveTests so any_cast
44+
// uses the correct address of Any::TypeId from the clang shared library instead
45+
// of creating one in the test executable. when building with
46+
// CLANG_LINK_CLANG_DYLIB
47+
extern template struct CLANG_TEMPLATE_ABI
48+
Any::TypeId<clang::dataflow::NoopLattice>;
49+
}; // namespace llvm
50+
4151
#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H

clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,28 @@
3030
#include "clang/Analysis/FlowSensitive/Transfer.h"
3131
#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
3232
#include "clang/Analysis/FlowSensitive/Value.h"
33+
#include "clang/Support/Compiler.h"
3334
#include "llvm/ADT/ArrayRef.h"
3435
#include "llvm/ADT/STLExtras.h"
3536
#include "llvm/Support/Debug.h"
3637
#include "llvm/Support/Error.h"
3738

3839
#define DEBUG_TYPE "clang-dataflow"
3940

41+
namespace clang {
42+
namespace dataflow {
43+
class NoopLattice;
44+
}
45+
} // namespace clang
46+
47+
namespace llvm {
48+
// This needs to be exported for ClangAnalysisFlowSensitiveTests so any_cast
49+
// uses the correct address of Any::TypeId from the clang shared library instead
50+
// of creating one in the test executable. when building with
51+
// CLANG_LINK_CLANG_DYLIB
52+
template struct CLANG_EXPORT_TEMPLATE Any::TypeId<clang::dataflow::NoopLattice>;
53+
} // namespace llvm
54+
4055
namespace clang {
4156
namespace dataflow {
4257

llvm/include/llvm/Analysis/LazyCallGraph.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#ifndef LLVM_ANALYSIS_LAZYCALLGRAPH_H
3535
#define LLVM_ANALYSIS_LAZYCALLGRAPH_H
3636

37+
#include "llvm/ADT/Any.h"
3738
#include "llvm/ADT/ArrayRef.h"
3839
#include "llvm/ADT/DenseMap.h"
3940
#include "llvm/ADT/PointerIntPair.h"
@@ -1308,6 +1309,8 @@ class LazyCallGraphDOTPrinterPass
13081309
static bool isRequired() { return true; }
13091310
};
13101311

1312+
extern template struct LLVM_TEMPLATE_ABI
1313+
Any::TypeId<const LazyCallGraph::SCC *>;
13111314
} // end namespace llvm
13121315

13131316
#endif // LLVM_ANALYSIS_LAZYCALLGRAPH_H

llvm/include/llvm/IR/PassInstrumentation.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,25 @@
5050
#define LLVM_IR_PASSINSTRUMENTATION_H
5151

5252
#include "llvm/ADT/Any.h"
53+
#include "llvm/ADT/DenseMap.h"
5354
#include "llvm/ADT/FunctionExtras.h"
5455
#include "llvm/ADT/SmallVector.h"
55-
#include "llvm/ADT/DenseMap.h"
5656
#include "llvm/IR/PassManager.h"
57+
#include "llvm/Support/Compiler.h"
5758
#include <type_traits>
5859
#include <vector>
5960

6061
namespace llvm {
6162

6263
class PreservedAnalyses;
6364
class StringRef;
65+
class Module;
66+
class Loop;
67+
class Function;
68+
69+
extern template struct LLVM_TEMPLATE_ABI Any::TypeId<const Module *>;
70+
extern template struct LLVM_TEMPLATE_ABI Any::TypeId<const Function *>;
71+
extern template struct LLVM_TEMPLATE_ABI Any::TypeId<const Loop *>;
6472

6573
/// This class manages callbacks registration, as well as provides a way for
6674
/// PassInstrumentation to pass control to the registered callbacks.

llvm/lib/Analysis/LazyCallGraph.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ using namespace llvm;
3737

3838
#define DEBUG_TYPE "lcg"
3939

40+
template struct LLVM_EXPORT_TEMPLATE Any::TypeId<const LazyCallGraph::SCC *>;
41+
4042
void LazyCallGraph::EdgeSequence::insertEdgeInternal(Node &TargetN,
4143
Edge::Kind EK) {
4244
EdgeIndexMap.try_emplace(&TargetN, Edges.size());

llvm/lib/IR/PassInstrumentation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717

1818
namespace llvm {
1919

20+
template struct LLVM_EXPORT_TEMPLATE Any::TypeId<const Module *>;
21+
template struct LLVM_EXPORT_TEMPLATE Any::TypeId<const Function *>;
22+
template struct LLVM_EXPORT_TEMPLATE Any::TypeId<const Loop *>;
23+
2024
void PassInstrumentationCallbacks::addClassToPassName(StringRef ClassName,
2125
StringRef PassName) {
2226
ClassToPassName.try_emplace(ClassName, PassName.str());

llvm/lib/Transforms/Scalar/LoopPassManager.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,12 +269,9 @@ PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F,
269269
PI.pushBeforeNonSkippedPassCallback([&LAR, &LI](StringRef PassID, Any IR) {
270270
if (isSpecialPass(PassID, {"PassManager"}))
271271
return;
272-
assert(llvm::any_cast<const Loop *>(&IR) ||
273-
llvm::any_cast<const LoopNest *>(&IR));
272+
assert(llvm::any_cast<const Loop *>(&IR));
274273
const Loop **LPtr = llvm::any_cast<const Loop *>(&IR);
275274
const Loop *L = LPtr ? *LPtr : nullptr;
276-
if (!L)
277-
L = &llvm::any_cast<const LoopNest *>(IR)->getOutermostLoop();
278275
assert(L && "Loop should be valid for printing");
279276

280277
// Verify the loop structure and LCSSA form before visiting the loop.

llvm/unittests/IR/PassBuilderCallbacksTest.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,6 @@ template <> std::string getName(const Any &WrappedIR) {
298298
return (*F)->getName().str();
299299
if (const auto *const *L = llvm::any_cast<const Loop *>(&WrappedIR))
300300
return (*L)->getName().str();
301-
if (const auto *const *L = llvm::any_cast<const LoopNest *>(&WrappedIR))
302-
return (*L)->getName().str();
303301
if (const auto *const *C =
304302
llvm::any_cast<const LazyCallGraph::SCC *>(&WrappedIR))
305303
return (*C)->getName();

0 commit comments

Comments
 (0)