Skip to content
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