Skip to content

[llvm] Support llvm::Any across shared libraries on windows #108051

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Oct 24, 2024
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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an any_cast<const LoopNest *> in an assertion left above.

Though generally I don't get why you're removing the LoopNest support here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess i missed the line above, but unless i was misunderstood layers of template template instantiation i found no code creating Any with LoopNest when i checked before.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To add some more context it looks like LoopPassManager::runSinglePass would be the path a LoopNest Any could be created but it decayed to a Loop from a overload of getLoopFromIR that takes a LoopNest and returns a Loop.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, so the code intentionally passes the outermost loop instead of the LoopNest to pass instrumentation. In that case these changes are fine.

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
Loading