22 assert(
N &&
"Got a null node?");
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);
55 unsigned StartIdx,
unsigned Edge) {
56 assert(StartIdx <= LeafEndIdx &&
"String can't start after it ends!");
57 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())
78 N->setConcatLen(Parent->
getConcatLen() + (EndIdx - StartIdx + 1));
89void SuffixTree::setLeafNodes() {
96 unsigned LeafCounter = 0;
100 DenseMap<SuffixTreeInternalNode *,
101 std::pair<SuffixTreeNode *, SuffixTreeNode *>>
105 while (!ToVisit.
empty()) {
109 auto I = ChildrenMap.find(CurrInternalNode);
110 if (
I == ChildrenMap.end()) {
115 auto J = CurrInternalNode->Children.begin();
116 if (J != CurrInternalNode->Children.end()) {
118 SuffixTreeNode *FirstChild = J->second;
119 SuffixTreeNode *LastChild =
nullptr;
120 for (; J != CurrInternalNode->Children.end(); ++J) {
121 LastChild = J->second;
124 ChildrenMap[CurrInternalNode] = {FirstChild, LastChild};
130 auto [FirstChild, LastChild] =
I->second;
139 "LeftLeafIdx should not be larger than RightLeafIdx");
148 LeafNodes.push_back(CurrLeafNode);
153unsigned SuffixTree::extend(
unsigned EndIdx,
unsigned SuffixesToAdd) {
154 SuffixTreeInternalNode *NeedsLink =
nullptr;
156 while (SuffixesToAdd > 0) {
159 if (Active.Len == 0) {
164 assert(Active.Idx <= EndIdx &&
"Start index can't be after end index!");
167 unsigned FirstChar =
Str[Active.Idx];
170 if (
auto It = Active.Node->Children.find(FirstChar);
171 It == Active.Node->Children.end()) {
173 insertLeaf(*Active.Node, EndIdx, FirstChar);
178 NeedsLink->
setLink(Active.Node);
184 SuffixTreeNode *NextNode = It->second;
190 if (Active.Len >= SubstringLen) {
194 "Expected an internal node?");
195 Active.Idx += SubstringLen;
196 Active.Len -= SubstringLen;
203 unsigned LastChar =
Str[EndIdx];
210 if (NeedsLink && !Active.Node->isRoot()) {
211 NeedsLink->
setLink(Active.Node);
233 SuffixTreeInternalNode *SplitNode = insertInternalNode(
235 NextNode->
getStartIdx() + Active.Len - 1, FirstChar);
239 insertLeaf(*SplitNode, EndIdx, LastChar);
250 NeedsLink = SplitNode;
257 if (Active.Node->isRoot()) {
258 if (Active.Len > 0) {
260 Active.Idx = EndIdx - SuffixesToAdd + 1;
264 Active.Node = Active.Node->getLink();
268 return SuffixesToAdd;
271void SuffixTree::RepeatedSubstringIterator::advance() {
274 RS = RepeatedSubstring();
278 SmallVector<unsigned> RepeatedSubstringStarts;
281 while (!InternalNodesToVisit.empty()) {
282 RepeatedSubstringStarts.
clear();
283 auto *Curr = InternalNodesToVisit.pop_back_val();
287 unsigned Length = Curr->getConcatLen();
291 for (
auto &ChildPair : Curr->Children)
293 if (
auto *InternalChild =
295 InternalNodesToVisit.push_back(InternalChild);
307 if (OutlinerLeafDescendants) {
308 for (
unsigned I = Curr->getLeftLeafIdx();
I <= Curr->getRightLeafIdx();
310 RepeatedSubstringStarts.
push_back(LeafNodes[
I]->getSuffixIdx());
312 for (
auto &ChildPair : Curr->Children)
314 RepeatedSubstringStarts.
push_back(Leaf->getSuffixIdx());
318 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)
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.
@ End
Run the machine verifier once, at the end of the pipeline.
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 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.
LLVM_ABI unsigned getConcatLen() const
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.