Skip to content

Commit d602e04

Browse files
committed
MemorySSA: Link all defs together into an intrusive defslist, to make updater easier
Summary: This is the first in a series of patches to add a simple, generalized updater to MemorySSA. For MemorySSA, every def is may-def, instead of the normal must-def. (the best way to think of memoryssa is "everything is really one variable, with different versions of that variable at different points in the program). This means when updating, we end up having to do a bunch of work to touch defs below and above us. In order to support this quickly, i have ilist'd all the defs for each block. ilist supports tags, so this is quite easy. the only slightly messy part is that you can't have two iplists for the same type that differ only whether they have the ownership part enabled or not, because the traits are for the value type. The verifiers have been updated to test that the def order is correct. Reviewers: george.burgess.iv Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D29046 llvm-svn: 293085
1 parent c7b9dfa commit d602e04

File tree

3 files changed

+212
-44
lines changed

3 files changed

+212
-44
lines changed

llvm/include/llvm/Transforms/Utils/MemorySSA.h

Lines changed: 80 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,14 @@
7373
#define LLVM_TRANSFORMS_UTILS_MEMORYSSA_H
7474

7575
#include "llvm/ADT/DenseMap.h"
76+
#include "llvm/ADT/DenseSet.h"
7677
#include "llvm/ADT/GraphTraits.h"
77-
#include "llvm/ADT/iterator_range.h"
7878
#include "llvm/ADT/SmallPtrSet.h"
7979
#include "llvm/ADT/SmallVector.h"
8080
#include "llvm/ADT/ilist.h"
8181
#include "llvm/ADT/ilist_node.h"
8282
#include "llvm/ADT/iterator.h"
83+
#include "llvm/ADT/iterator_range.h"
8384
#include "llvm/Analysis/AliasAnalysis.h"
8485
#include "llvm/Analysis/MemoryLocation.h"
8586
#include "llvm/Analysis/PHITransAddr.h"
@@ -108,6 +109,11 @@ class Instruction;
108109
class MemoryAccess;
109110
class LLVMContext;
110111
class raw_ostream;
112+
namespace MSSAHelpers {
113+
114+
struct AllAccessTag {};
115+
struct DefsOnlyTag {};
116+
}
111117

112118
enum {
113119
// Used to signify what the default invalid ID is for MemoryAccess's
@@ -122,8 +128,16 @@ using const_memoryaccess_def_iterator =
122128

123129
// \brief The base for all memory accesses. All memory accesses in a block are
124130
// linked together using an intrusive list.
125-
class MemoryAccess : public User, public ilist_node<MemoryAccess> {
131+
class MemoryAccess
132+
: public User,
133+
public ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::AllAccessTag>>,
134+
public ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::DefsOnlyTag>> {
126135
public:
136+
using AllAccessType =
137+
ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::AllAccessTag>>;
138+
using DefsOnlyType =
139+
ilist_node<MemoryAccess, ilist_tag<MSSAHelpers::DefsOnlyTag>>;
140+
127141
// Methods for support type inquiry through isa, cast, and
128142
// dyn_cast
129143
static inline bool classof(const MemoryAccess *) { return true; }
@@ -156,6 +170,33 @@ class MemoryAccess : public User, public ilist_node<MemoryAccess> {
156170
memoryaccess_def_iterator defs_end();
157171
const_memoryaccess_def_iterator defs_end() const;
158172

173+
/// \brief Get the iterators for the all access list and the defs only list
174+
/// We default to the all access list.
175+
AllAccessType::self_iterator getIterator() {
176+
return this->AllAccessType::getIterator();
177+
}
178+
AllAccessType::const_self_iterator getIterator() const {
179+
return this->AllAccessType::getIterator();
180+
}
181+
AllAccessType::reverse_self_iterator getReverseIterator() {
182+
return this->AllAccessType::getReverseIterator();
183+
}
184+
AllAccessType::const_reverse_self_iterator getReverseIterator() const {
185+
return this->AllAccessType::getReverseIterator();
186+
}
187+
DefsOnlyType::self_iterator getDefsIterator() {
188+
return this->DefsOnlyType::getIterator();
189+
}
190+
DefsOnlyType::const_self_iterator getDefsIterator() const {
191+
return this->DefsOnlyType::getIterator();
192+
}
193+
DefsOnlyType::reverse_self_iterator getReverseDefsIterator() {
194+
return this->DefsOnlyType::getReverseIterator();
195+
}
196+
DefsOnlyType::const_reverse_self_iterator getReverseDefsIterator() const {
197+
return this->DefsOnlyType::getReverseIterator();
198+
}
199+
159200
protected:
160201
friend class MemorySSA;
161202
friend class MemoryUseOrDef;
@@ -531,7 +572,14 @@ class MemorySSA {
531572
return LiveOnEntryDef.get();
532573
}
533574

534-
using AccessList = iplist<MemoryAccess>;
575+
// Sadly, iplists, by default, owns and deletes pointers added to the
576+
// list. It's not currently possible to have two iplists for the same type,
577+
// where one owns the pointers, and one does not. This is because the traits
578+
// are per-type, not per-tag. If this ever changes, we should make the
579+
// DefList an iplist.
580+
using AccessList = iplist<MemoryAccess, ilist_tag<MSSAHelpers::AllAccessTag>>;
581+
using DefsList =
582+
simple_ilist<MemoryAccess, ilist_tag<MSSAHelpers::DefsOnlyTag>>;
535583

536584
/// \brief Return the list of MemoryAccess's for a given basic block.
537585
///
@@ -540,6 +588,14 @@ class MemorySSA {
540588
return getWritableBlockAccesses(BB);
541589
}
542590

591+
/// \brief Return the list of MemoryDef's and MemoryPhi's for a given basic
592+
/// block.
593+
///
594+
/// This list is not modifiable by the user.
595+
const DefsList *getBlockDefs(const BasicBlock *BB) const {
596+
return getWritableBlockDefs(BB);
597+
}
598+
543599
/// \brief Create an empty MemoryPhi in MemorySSA for a given basic block.
544600
/// Only one MemoryPhi for a block exists at a time, so this function will
545601
/// assert if you try to create one where it already exists.
@@ -623,12 +679,18 @@ class MemorySSA {
623679
void verifyDomination(Function &F) const;
624680
void verifyOrdering(Function &F) const;
625681

626-
// This is used by the use optimizer class
682+
// This is used by the use optimizer and updater.
627683
AccessList *getWritableBlockAccesses(const BasicBlock *BB) const {
628684
auto It = PerBlockAccesses.find(BB);
629685
return It == PerBlockAccesses.end() ? nullptr : It->second.get();
630686
}
631687

688+
// This is used by the use optimizer and updater.
689+
DefsList *getWritableBlockDefs(const BasicBlock *BB) const {
690+
auto It = PerBlockDefs.find(BB);
691+
return It == PerBlockDefs.end() ? nullptr : It->second.get();
692+
}
693+
632694
private:
633695
class CachingWalker;
634696
class OptimizeUses;
@@ -639,6 +701,7 @@ class MemorySSA {
639701

640702
void verifyUseInDefs(MemoryAccess *, MemoryAccess *) const;
641703
using AccessMap = DenseMap<const BasicBlock *, std::unique_ptr<AccessList>>;
704+
using DefsMap = DenseMap<const BasicBlock *, std::unique_ptr<DefsList>>;
642705

643706
void
644707
determineInsertionPoint(const SmallPtrSetImpl<BasicBlock *> &DefiningBlocks);
@@ -656,15 +719,26 @@ class MemorySSA {
656719
void renamePass(DomTreeNode *, MemoryAccess *IncomingVal,
657720
SmallPtrSet<BasicBlock *, 16> &Visited);
658721
AccessList *getOrCreateAccessList(const BasicBlock *);
722+
DefsList *getOrCreateDefsList(const BasicBlock *);
659723
void renumberBlock(const BasicBlock *) const;
660-
724+
void insertIntoListsForBlock(MemoryAccess *, const BasicBlock *,
725+
InsertionPlace);
726+
void insertIntoListsBefore(MemoryAccess *, const BasicBlock *,
727+
AccessList::iterator);
661728
AliasAnalysis *AA;
662729
DominatorTree *DT;
663730
Function &F;
664731

665732
// Memory SSA mappings
666733
DenseMap<const Value *, MemoryAccess *> ValueToMemoryAccess;
734+
// These two mappings contain the main block to access/def mappings for
735+
// MemorySSA. The list contained in PerBlockAccesses really owns all the
736+
// MemoryAccesses.
737+
// Both maps maintain the invariant that if a block is found in them, the
738+
// corresponding list is not empty, and if a block is not found in them, the
739+
// corresponding list is empty.
667740
AccessMap PerBlockAccesses;
741+
DefsMap PerBlockDefs;
668742
std::unique_ptr<MemoryAccess> LiveOnEntryDef;
669743

670744
// Domination mappings
@@ -957,9 +1031,7 @@ class upward_defs_iterator
9571031
fillInCurrentPair();
9581032
}
9591033

960-
upward_defs_iterator() {
961-
CurrentPair.first = nullptr;
962-
}
1034+
upward_defs_iterator() { CurrentPair.first = nullptr; }
9631035

9641036
bool operator==(const upward_defs_iterator &Other) const {
9651037
return DefIterator == Other.DefIterator;

0 commit comments

Comments
 (0)