22 assert(
N &&
"Got a null node?");
23 if (
auto *Internal = dyn_cast<SuffixTreeInternalNode>(
N))
24 if (Internal->isRoot())
26 return N->getEndIdx() -
N->getStartIdx() + 1;
37 unsigned SuffixesToAdd = 0;
42 for (
unsigned PfxEndIdx = 0,
End =
Str.
size(); PfxEndIdx <
End; PfxEndIdx++) {
44 LeafEndIdx = PfxEndIdx;
45 SuffixesToAdd = extend(PfxEndIdx, SuffixesToAdd);
49 assert(Root &&
"Root node can't be nullptr!");
59 unsigned StartIdx,
unsigned Edge) {
60 assert(StartIdx <= LeafEndIdx &&
"String can't start after it ends!");
61 auto *
N =
new (LeafNodeAllocator.Allocate())
69 unsigned StartIdx,
unsigned EndIdx,
71 assert(StartIdx <= EndIdx &&
"String can't start after it ends!");
73 "Non-root internal nodes must have parents!");
74 auto *
N =
new (InternalNodeAllocator.Allocate())
86void SuffixTree::setSuffixIndices() {
95 unsigned CurrNodeLen = 0;
96 ToVisit.
push_back({CurrNode, CurrNodeLen});
97 while (!ToVisit.
empty()) {
98 std::tie(CurrNode, CurrNodeLen) = ToVisit.
back();
102 if (
auto *InternalNode = dyn_cast<SuffixTreeInternalNode>(CurrNode))
103 for (
auto &ChildPair : InternalNode->Children) {
104 assert(ChildPair.second &&
"Node had a null child!");
110 if (
auto *LeafNode = dyn_cast<SuffixTreeLeafNode>(CurrNode))
111 LeafNode->setSuffixIdx(
Str.
size() - CurrNodeLen);
115void SuffixTree::setLeafNodes() {
122 unsigned LeafCounter = 0;
127 std::pair<SuffixTreeNode *, SuffixTreeNode *>>
131 while (!ToVisit.
empty()) {
133 if (
auto *CurrInternalNode = dyn_cast<SuffixTreeInternalNode>(CurrNode)) {
135 auto I = ChildrenMap.find(CurrInternalNode);
136 if (
I == ChildrenMap.end()) {
141 auto J = CurrInternalNode->Children.begin();
142 if (J != CurrInternalNode->Children.end()) {
146 for (; J != CurrInternalNode->Children.end(); ++J) {
147 LastChild = J->second;
150 ChildrenMap[CurrInternalNode] = {FirstChild, LastChild};
156 auto [FirstChild, LastChild] =
I->second;
165 "LeftLeafIdx should not be larger than RightLeafIdx");
173 auto *CurrLeafNode = cast<SuffixTreeLeafNode>(CurrNode);
174 LeafNodes.push_back(CurrLeafNode);
179unsigned SuffixTree::extend(
unsigned EndIdx,
unsigned SuffixesToAdd) {
182 while (SuffixesToAdd > 0) {
185 if (Active.Len == 0) {
190 assert(Active.Idx <= EndIdx &&
"Start index can't be after end index!");
193 unsigned FirstChar =
Str[Active.Idx];
196 if (Active.Node->Children.count(FirstChar) == 0) {
198 insertLeaf(*Active.Node, EndIdx, FirstChar);
203 NeedsLink->
setLink(Active.Node);
215 if (Active.Len >= SubstringLen) {
218 assert(isa<SuffixTreeInternalNode>(NextNode) &&
219 "Expected an internal node?");
220 Active.Idx += SubstringLen;
221 Active.Len -= SubstringLen;
222 Active.Node = cast<SuffixTreeInternalNode>(NextNode);
228 unsigned LastChar =
Str[EndIdx];
235 if (NeedsLink && !Active.Node->isRoot()) {
236 NeedsLink->
setLink(Active.Node);
260 NextNode->
getStartIdx() + Active.Len - 1, FirstChar);
264 insertLeaf(*SplitNode, EndIdx, LastChar);
275 NeedsLink = SplitNode;
282 if (Active.Node->isRoot()) {
283 if (Active.Len > 0) {
285 Active.Idx = EndIdx - SuffixesToAdd + 1;
289 Active.Node = Active.Node->getLink();
293 return SuffixesToAdd;
296void SuffixTree::RepeatedSubstringIterator::advance() {
299 RS = RepeatedSubstring();
306 while (!InternalNodesToVisit.empty()) {
307 RepeatedSubstringStarts.
clear();
308 auto *Curr = InternalNodesToVisit.back();
309 InternalNodesToVisit.pop_back();
313 unsigned Length = Curr->getConcatLen();
317 for (
auto &ChildPair : Curr->Children)
319 if (
auto *InternalChild =
320 dyn_cast<SuffixTreeInternalNode>(ChildPair.second))
321 InternalNodesToVisit.push_back(InternalChild);
333 if (OutlinerLeafDescendants) {
334 for (
unsigned I = Curr->getLeftLeafIdx(); I <= Curr->getRightLeafIdx();
336 RepeatedSubstringStarts.
push_back(LeafNodes[
I]->getSuffixIdx());
338 for (
auto &ChildPair : Curr->Children)
339 if (
auto *Leaf = dyn_cast<SuffixTreeLeafNode>(ChildPair.second))
340 RepeatedSubstringStarts.
push_back(Leaf->getSuffixIdx());
344 if (RepeatedSubstringStarts.
size() < 2)
350 for (
unsigned StartIdx : RepeatedSubstringStarts)
This file defines the BumpPtrAllocator interface.
static cl::opt< bool > OutlinerLeafDescendants("outliner-leaf-descendants", cl::init(true), cl::Hidden, cl::desc("Consider all leaf descendants of internal nodes of the suffix " "tree as candidates for outlining (if false, only leaf children " "are considered)"))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static size_t numElementsInSubstring(const SuffixTreeNode *N)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
SuffixTree(const ArrayRef< unsigned > &Str, bool OutlinerLeafDescendants=false)
Construct a suffix tree from a sequence of unsigned integers.
ArrayRef< unsigned > Str
Each element is an integer representing an instruction in the module.
bool OutlinerLeafDescendants
Whether to consider leaf descendants or only leaf children.
This is an optimization pass for GlobalISel generic memory operations.
DenseMap< unsigned, SuffixTreeNode * > Children
The children of this node.
void setLink(SuffixTreeInternalNode *L)
Sets Link to L. Assumes L is not null.
A node in a suffix tree which represents a substring or suffix.
void incrementStartIdx(unsigned Inc)
Advance this node's StartIdx by Inc.
void setConcatLen(unsigned Len)
Set the length of the string from the root to this node to Len.
unsigned getLeftLeafIdx() const
unsigned getRightLeafIdx() const
void setRightLeafIdx(unsigned Idx)
Set the index of the right most leaf node of this node to Idx.
static const unsigned EmptyIdx
Represents an undefined index in the suffix tree.
unsigned getStartIdx() const
void setLeftLeafIdx(unsigned Idx)
Set the index of the left most leaf node of this node to Idx.
SmallVector< unsigned > StartIndices
The start indices of each occurrence.
unsigned Length
The length of the string.