summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Analysis/CGSCCPassManager.h43
-rw-r--r--llvm/include/llvm/IR/PassManager.h22
-rw-r--r--llvm/lib/Analysis/CGSCCPassManager.cpp8
-rw-r--r--llvm/lib/IR/PassManager.cpp4
4 files changed, 59 insertions, 18 deletions
diff --git a/llvm/include/llvm/Analysis/CGSCCPassManager.h b/llvm/include/llvm/Analysis/CGSCCPassManager.h
index d314858c8dc..7d01ebb9a00 100644
--- a/llvm/include/llvm/Analysis/CGSCCPassManager.h
+++ b/llvm/include/llvm/Analysis/CGSCCPassManager.h
@@ -49,17 +49,26 @@ typedef AnalysisManager<LazyCallGraph::SCC> CGSCCAnalysisManager;
/// never use a CGSCC analysis manager from within (transitively) a module
/// pass manager unless your parent module pass has received a proxy result
/// object for it.
+///
+/// Note that the proxy's result is a move-only object and represents ownership
+/// of the validity of the analyses in the \c CGSCCAnalysisManager it provides.
class CGSCCAnalysisManagerModuleProxy {
public:
class Result {
public:
explicit Result(CGSCCAnalysisManager &CGAM) : CGAM(&CGAM) {}
- // We have to explicitly define all the special member functions because
- // MSVC refuses to generate them.
- Result(const Result &Arg) : CGAM(Arg.CGAM) {}
- Result(Result &&Arg) : CGAM(std::move(Arg.CGAM)) {}
- Result &operator=(Result RHS) {
- std::swap(CGAM, RHS.CGAM);
+ Result(Result &&Arg) : CGAM(std::move(Arg.CGAM)) {
+ // We have to null out the analysis manager in the moved-from state
+ // because we are taking ownership of its responsibilty to clear the
+ // analysis state.
+ Arg.CGAM = nullptr;
+ }
+ Result &operator=(Result &&RHS) {
+ CGAM = RHS.CGAM;
+ // We have to null out the analysis manager in the moved-from state
+ // because we are taking ownership of its responsibilty to clear the
+ // analysis state.
+ RHS.CGAM = nullptr;
return *this;
}
~Result();
@@ -275,17 +284,27 @@ createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass) {
/// never use a function analysis manager from within (transitively) a CGSCC
/// pass manager unless your parent CGSCC pass has received a proxy result
/// object for it.
+///
+/// Note that the proxy's result is a move-only object and represents ownership
+/// of the validity of the analyses in the \c FunctionAnalysisManager it
+/// provides.
class FunctionAnalysisManagerCGSCCProxy {
public:
class Result {
public:
explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
- // We have to explicitly define all the special member functions because
- // MSVC refuses to generate them.
- Result(const Result &Arg) : FAM(Arg.FAM) {}
- Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {}
- Result &operator=(Result RHS) {
- std::swap(FAM, RHS.FAM);
+ Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {
+ // We have to null out the analysis manager in the moved-from state
+ // because we are taking ownership of the responsibilty to clear the
+ // analysis state.
+ Arg.FAM = nullptr;
+ }
+ Result &operator=(Result &&RHS) {
+ FAM = RHS.FAM;
+ // We have to null out the analysis manager in the moved-from state
+ // because we are taking ownership of the responsibilty to clear the
+ // analysis state.
+ RHS.FAM = nullptr;
return *this;
}
~Result();
diff --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h
index 9b0301b4a66..56ddfeb97a5 100644
--- a/llvm/include/llvm/IR/PassManager.h
+++ b/llvm/include/llvm/IR/PassManager.h
@@ -618,6 +618,10 @@ typedef AnalysisManager<Function> FunctionAnalysisManager;
/// never use a function analysis manager from within (transitively) a module
/// pass manager unless your parent module pass has received a proxy result
/// object for it.
+///
+/// Note that the proxy's result is a move-only object and represents ownership
+/// of the validity of the analyses in the \c FunctionAnalysisManager it
+/// provides.
class FunctionAnalysisManagerModuleProxy {
public:
class Result;
@@ -665,12 +669,18 @@ private:
class FunctionAnalysisManagerModuleProxy::Result {
public:
explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
- // We have to explicitly define all the special member functions because MSVC
- // refuses to generate them.
- Result(const Result &Arg) : FAM(Arg.FAM) {}
- Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {}
- Result &operator=(Result RHS) {
- std::swap(FAM, RHS.FAM);
+ Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {
+ // We have to null out the analysis manager in the moved-from state
+ // because we are taking ownership of the responsibilty to clear the
+ // analysis state.
+ Arg.FAM = nullptr;
+ }
+ Result &operator=(Result &&RHS) {
+ FAM = RHS.FAM;
+ // We have to null out the analysis manager in the moved-from state
+ // because we are taking ownership of the responsibilty to clear the
+ // analysis state.
+ RHS.FAM = nullptr;
return *this;
}
~Result();
diff --git a/llvm/lib/Analysis/CGSCCPassManager.cpp b/llvm/lib/Analysis/CGSCCPassManager.cpp
index 4a03002e510..9cceed4ba87 100644
--- a/llvm/lib/Analysis/CGSCCPassManager.cpp
+++ b/llvm/lib/Analysis/CGSCCPassManager.cpp
@@ -22,6 +22,10 @@ CGSCCAnalysisManagerModuleProxy::run(Module &M) {
}
CGSCCAnalysisManagerModuleProxy::Result::~Result() {
+ // CGAM is cleared in a moved from state where there is nothing to do.
+ if (!CGAM)
+ return;
+
// Clear out the analysis manager if we're being destroyed -- it means we
// didn't even see an invalidate call when we got invalidated.
CGAM->clear();
@@ -51,6 +55,10 @@ FunctionAnalysisManagerCGSCCProxy::run(LazyCallGraph::SCC &C) {
}
FunctionAnalysisManagerCGSCCProxy::Result::~Result() {
+ // FAM is cleared in a moved from state where there is nothing to do.
+ if (!FAM)
+ return;
+
// Clear out the analysis manager if we're being destroyed -- it means we
// didn't even see an invalidate call when we got invalidated.
FAM->clear();
diff --git a/llvm/lib/IR/PassManager.cpp b/llvm/lib/IR/PassManager.cpp
index a5f407c00e8..f55db9c1e64 100644
--- a/llvm/lib/IR/PassManager.cpp
+++ b/llvm/lib/IR/PassManager.cpp
@@ -22,6 +22,10 @@ FunctionAnalysisManagerModuleProxy::run(Module &M) {
}
FunctionAnalysisManagerModuleProxy::Result::~Result() {
+ // FAM is cleared in a moved from state where there is nothing to do.
+ if (!FAM)
+ return;
+
// Clear out the analysis manager if we're being destroyed -- it means we
// didn't even see an invalidate call when we got invalidated.
FAM->clear();
OpenPOWER on IntegriCloud