From 5e10e21d28496ba40ccd385740d7d1b4bb1368e4 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Wed, 14 Jan 2015 10:07:19 +0000 Subject: [PATCH] [PM] Make DominatorTrees (corectly) movable so that we can move them into the new pass manager's analysis cache which stores results by-value. Technically speaking, the dom trees were originally not movable but copyable! This, unsurprisingly, didn't work at all -- the copy was shallow and just resulted in rampant memory corruption. This change explicitly forbids copying (as it would need to be a deep copy) and makes them explicitly movable with the unsurprising boiler plate to member-wise move them because we can't rely on MSVC to generate this code for us. =/ llvm-svn: 225966 --- llvm/include/llvm/IR/Dominators.h | 7 ++++ llvm/include/llvm/Support/GenericDomTree.h | 52 +++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/IR/Dominators.h b/llvm/include/llvm/IR/Dominators.h index e2d1ccc..4e7dacc 100644 --- a/llvm/include/llvm/IR/Dominators.h +++ b/llvm/include/llvm/IR/Dominators.h @@ -69,6 +69,13 @@ public: DominatorTree() : DominatorTreeBase(false) {} + DominatorTree(DominatorTree &&Arg) + : Base(std::move(static_cast(Arg))) {} + DominatorTree &operator=(DominatorTree &&RHS) { + Base::operator=(std::move(static_cast(RHS))); + return *this; + } + /// \brief Returns *false* if the other dominator tree matches this dominator /// tree. inline bool compare(const DominatorTree &Other) const { diff --git a/llvm/include/llvm/Support/GenericDomTree.h b/llvm/include/llvm/Support/GenericDomTree.h index 7640bf8..fa56f9a 100644 --- a/llvm/include/llvm/Support/GenericDomTree.h +++ b/llvm/include/llvm/Support/GenericDomTree.h @@ -34,9 +34,20 @@ namespace llvm { template class DominatorBase { protected: std::vector Roots; - const bool IsPostDominators; + bool IsPostDominators; explicit DominatorBase(bool isPostDom) : Roots(), IsPostDominators(isPostDom) {} + DominatorBase(DominatorBase &&Arg) + : Roots(std::move(Arg.Roots)), + IsPostDominators(std::move(Arg.IsPostDominators)) { + Arg.Roots.clear(); + } + DominatorBase &operator=(DominatorBase &&RHS) { + Roots = std::move(RHS.Roots); + IsPostDominators = std::move(RHS.IsPostDominators); + RHS.Roots.clear(); + return *this; + } public: /// getRoots - Return the root blocks of the current CFG. This may include @@ -171,6 +182,9 @@ void Calculate(DominatorTreeBase::NodeType> &DT, /// This class is a generic template over graph nodes. It is instantiated for /// various graphs in the LLVM IR or in the code generator. template class DominatorTreeBase : public DominatorBase { + DominatorTreeBase(const DominatorTreeBase &) LLVM_DELETED_FUNCTION; + DominatorTreeBase &operator=(const DominatorTreeBase &) LLVM_DELETED_FUNCTION; + bool dominatedBySlowTreeWalk(const DomTreeNodeBase *A, const DomTreeNodeBase *B) const { assert(A != B); @@ -183,6 +197,18 @@ template class DominatorTreeBase : public DominatorBase { return IDom != nullptr; } + /// \brief Wipe this tree's state without releasing any resources. + /// + /// This is essentially a post-move helper only. It leaves the object in an + /// assignable and destroyable state, but otherwise invalid. + void wipe() { + DomTreeNodes.clear(); + IDoms.clear(); + Vertex.clear(); + Info.clear(); + RootNode = nullptr; + } + protected: typedef DenseMap *> DomTreeNodeMapType; DomTreeNodeMapType DomTreeNodes; @@ -290,6 +316,30 @@ public: : DominatorBase(isPostDom), DFSInfoValid(false), SlowQueries(0) {} virtual ~DominatorTreeBase() { reset(); } + DominatorTreeBase(DominatorTreeBase &&Arg) + : DominatorBase( + std::move(static_cast &>(Arg))), + DomTreeNodes(std::move(Arg.DomTreeNodes)), + RootNode(std::move(Arg.RootNode)), + DFSInfoValid(std::move(Arg.DFSInfoValid)), + SlowQueries(std::move(Arg.SlowQueries)), IDoms(std::move(Arg.IDoms)), + Vertex(std::move(Arg.Vertex)), Info(std::move(Arg.Info)) { + Arg.wipe(); + } + DominatorTreeBase &operator=(DominatorTreeBase &&RHS) { + DominatorBase::operator=( + std::move(static_cast &>(RHS))); + DomTreeNodes = std::move(RHS.DomTreeNodes); + RootNode = std::move(RHS.RootNode); + DFSInfoValid = std::move(RHS.DFSInfoValid); + SlowQueries = std::move(RHS.SlowQueries); + IDoms = std::move(RHS.IDoms); + Vertex = std::move(RHS.Vertex); + Info = std::move(RHS.Info); + RHS.wipe(); + return *this; + } + /// compare - Return false if the other dominator tree base matches this /// dominator tree base. Otherwise return true. bool compare(const DominatorTreeBase &Other) const { -- 2.7.4