Skip to content

Commit

Permalink
[llvm] Support llvm::Any across shared libraries on windows (llvm#108051
Browse files Browse the repository at this point in the history
)

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 llvm#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>`
  • Loading branch information
fsfod authored and NoumanAmir657 committed Nov 4, 2024
1 parent 937360c commit e1b178e
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 7 deletions.
10 changes: 10 additions & 0 deletions clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -38,4 +39,13 @@ inline std::ostream &operator<<(std::ostream &OS, const NoopLattice &) {
} // namespace dataflow
} // 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>;
}; // namespace llvm

#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H
15 changes: 15 additions & 0 deletions clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,28 @@
#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"
#include "llvm/Support/Error.h"

#define DEBUG_TYPE "clang-dataflow"

namespace clang {
namespace dataflow {
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>;
} // namespace llvm

namespace clang {
namespace dataflow {

Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/Analysis/LazyCallGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -1308,6 +1309,8 @@ class LazyCallGraphDOTPrinterPass
static bool isRequired() { return true; }
};

extern template struct LLVM_TEMPLATE_ABI
Any::TypeId<const LazyCallGraph::SCC *>;
} // end namespace llvm

#endif // LLVM_ANALYSIS_LAZYCALLGRAPH_H
10 changes: 9 additions & 1 deletion llvm/include/llvm/IR/PassInstrumentation.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,25 @@
#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>

namespace llvm {

class PreservedAnalyses;
class StringRef;
class Module;
class Loop;
class Function;

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 *>;

/// This class manages callbacks registration, as well as provides a way for
/// PassInstrumentation to pass control to the registered callbacks.
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Analysis/LazyCallGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ using namespace llvm;

#define DEBUG_TYPE "lcg"

template struct LLVM_EXPORT_TEMPLATE Any::TypeId<const LazyCallGraph::SCC *>;

void LazyCallGraph::EdgeSequence::insertEdgeInternal(Node &TargetN,
Edge::Kind EK) {
EdgeIndexMap.try_emplace(&TargetN, Edges.size());
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/IR/PassInstrumentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

namespace llvm {

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 *>;

void PassInstrumentationCallbacks::addClassToPassName(StringRef ClassName,
StringRef PassName) {
ClassToPassName.try_emplace(ClassName, PassName.str());
Expand Down
5 changes: 1 addition & 4 deletions llvm/lib/Transforms/Scalar/LoopPassManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,9 @@ 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;
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.
Expand Down
2 changes: 0 additions & 2 deletions llvm/unittests/IR/PassBuilderCallbacksTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit e1b178e

Please sign in to comment.