22 assert(
N &&
"Got a null node?");
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() {
92 SuffixTreeNode *CurrNode = Root;
95 unsigned CurrNodeLen = 0;
96 ToVisit.
push_back({CurrNode, CurrNodeLen});
97 while (!ToVisit.
empty()) {
98 std::tie(CurrNode, CurrNodeLen) = ToVisit.
pop_back_val();
102 for (
auto &ChildPair : InternalNode->Children) {
103 assert(ChildPair.second &&
"Node had a null child!");
110 LeafNode->setSuffixIdx(
Str.size() - CurrNodeLen);
114void SuffixTree::setLeafNodes() {
121 unsigned LeafCounter = 0;
125 DenseMap<SuffixTreeInternalNode *,
126 std::pair<SuffixTreeNode *, SuffixTreeNode *>>
130 while (!ToVisit.
empty()) {
134 auto I = ChildrenMap.find(CurrInternalNode);
135 if (
I == ChildrenMap.end()) {
140 auto J = CurrInternalNode->Children.begin();
141 if (J != CurrInternalNode->Children.end()) {
143 SuffixTreeNode *FirstChild = J->second;
144 SuffixTreeNode *LastChild =
nullptr;
145 for (; J != CurrInternalNode->Children.end(); ++J) {
146 LastChild = J->second;
149 ChildrenMap[CurrInternalNode] = {FirstChild, LastChild};
155 auto [FirstChild, LastChild] =
I->second;
164 "LeftLeafIdx should not be larger than RightLeafIdx");
173 LeafNodes.push_back(CurrLeafNode);
178unsigned SuffixTree::extend(
unsigned EndIdx,
unsigned SuffixesToAdd) {
179 SuffixTreeInternalNode *NeedsLink =
nullptr;
181 while (SuffixesToAdd > 0) {
184 if (Active.Len == 0) {
189 assert(Active.Idx <= EndIdx &&
"Start index can't be after end index!");
192 unsigned FirstChar =
Str[Active.Idx];
195 if (
auto It = Active.Node->Children.find(FirstChar);
196 It == Active.Node->Children.end()) {
198 insertLeaf(*Active.Node, EndIdx, FirstChar);
203 NeedsLink->
setLink(Active.Node);
209 SuffixTreeNode *NextNode = It->second;
215 if (Active.Len >= SubstringLen) {
219 "Expected an internal node?");
220 Active.Idx += SubstringLen;
221 Active.Len -= SubstringLen;
228 unsigned LastChar =
Str[EndIdx];
235 if (NeedsLink && !Active.Node->isRoot()) {
236 NeedsLink->
setLink(Active.Node);
258 SuffixTreeInternalNode *SplitNode = insertInternalNode(
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();
303 SmallVector<unsigned> RepeatedSubstringStarts;
306 while (!InternalNodesToVisit.empty()) {
307 RepeatedSubstringStarts.
clear();
308 auto *Curr = InternalNodesToVisit.pop_back_val();
312 unsigned Length = Curr->getConcatLen();
316 for (
auto &ChildPair : Curr->Children)
318 if (
auto *InternalChild =
320 InternalNodesToVisit.push_back(InternalChild);
332 if (OutlinerLeafDescendants) {
333 for (
unsigned I = Curr->getLeftLeafIdx();
I <= Curr->getRightLeafIdx();
335 RepeatedSubstringStarts.
push_back(LeafNodes[
I]->getSuffixIdx());
337 for (
auto &ChildPair : Curr->Children)
339 RepeatedSubstringStarts.
push_back(Leaf->getSuffixIdx());
343 if (RepeatedSubstringStarts.
size() < 2)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the BumpPtrAllocator interface.
static size_t numElementsInSubstring(const SuffixTreeNode *N)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
void push_back(const T &Elt)
LLVM_ABI 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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
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.
LLVM_ABI void incrementStartIdx(unsigned Inc)
Advance this node's StartIdx by Inc.
LLVM_ABI void setConcatLen(unsigned Len)
Set the length of the string from the root to this node to Len.
LLVM_ABI unsigned getLeftLeafIdx() const
LLVM_ABI unsigned getRightLeafIdx() const
LLVM_ABI 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.
LLVM_ABI unsigned getStartIdx() const
LLVM_ABI void setLeftLeafIdx(unsigned Idx)
Set the index of the left most leaf node of this node to Idx.