Index: llvm/include/llvm/Support/SuffixTree.h =================================================================== --- llvm/include/llvm/Support/SuffixTree.h +++ llvm/include/llvm/Support/SuffixTree.h @@ -17,6 +17,11 @@ #include "llvm/Support/Allocator.h" #include +#ifndef NDEBUG +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#endif + namespace llvm { /// Represents an undefined index in the suffix tree. @@ -38,6 +43,10 @@ /// in \p Link. Each leaf node stores the start index of its respective /// suffix in \p SuffixIdx. struct SuffixTreeNode { + // The ID of the node +#ifndef NDEBUG + uint64_t ID = 0; +#endif /// The children of this node. /// @@ -137,6 +146,9 @@ class SuffixTree { public: /// Each element is an integer representing an instruction in the module. + /// + /// If the developer want to build a valid suffix tree, the last number of + /// array should be unique llvm::ArrayRef Str; /// A repeated substring in the tree. @@ -234,6 +246,8 @@ /// \param Str The string to construct the suffix tree for. SuffixTree(const std::vector &Str); + const SuffixTreeNode *getRoot() const { return Root; } + /// Iterator for finding all repeated substrings in the suffix tree. struct RepeatedSubstringIterator { private: @@ -345,6 +359,41 @@ iterator end() { return iterator(nullptr); } }; +#ifndef NDEBUG + +inline raw_ostream &operator<<(raw_ostream &OS, const SuffixTree &Tree) { + std::vector Worklist; + Worklist.push_back(Tree.getRoot()); + while (!Worklist.empty()) { + const SuffixTreeNode *Node = Worklist.back(); + Worklist.pop_back(); + + if (!Node) + continue; + + std::string NodeType = "Internal"; + if (Node->isRoot()) { + NodeType = "Root"; + } else if (Node->isLeaf()) { + NodeType = "Leaf"; + } + + std::string EndIdxValue = + Node->EndIdx ? std::to_string(*Node->EndIdx) : "$"; + OS << "Node[" << NodeType << "#" << std::to_string(Node->ID) + << "]: StartIdx=" << Node->StartIdx << ", EndIdx=" << EndIdxValue; + OS << ", Childrens = ["; + for (auto &ChildPair : Node->Children) { + OS << ChildPair.second->ID << ","; + Worklist.push_back(ChildPair.second); + } + OS << "]\n"; + } + return OS; +} + +#endif + } // namespace llvm #endif // LLVM_SUPPORT_SUFFIXTREE_H Index: llvm/lib/CodeGen/MachineOutliner.cpp =================================================================== --- llvm/lib/CodeGen/MachineOutliner.cpp +++ llvm/lib/CodeGen/MachineOutliner.cpp @@ -514,6 +514,9 @@ InstructionMapper &Mapper, std::vector &FunctionList) { FunctionList.clear(); SuffixTree ST(Mapper.UnsignedVec); +#ifndef NDEBUG + LLVM_DEBUG(dbgs() << "Dumping SuffixTree:\n" << ST << "\n"); +#endif // First, find all of the repeated substrings in the tree of minimum length // 2. Index: llvm/lib/Support/SuffixTree.cpp =================================================================== --- llvm/lib/Support/SuffixTree.cpp +++ llvm/lib/Support/SuffixTree.cpp @@ -75,6 +75,9 @@ // Current node being visited. SuffixTreeNode *CurrNode = Root; +#ifndef NDEBUG + uint64_t CurID = 0; +#endif // Sum of the lengths of the nodes down the path to the current one. unsigned CurrNodeLen = 0; ToVisit.push_back({CurrNode, CurrNodeLen}); @@ -82,6 +85,9 @@ std::tie(CurrNode, CurrNodeLen) = ToVisit.back(); ToVisit.pop_back(); CurrNode->ConcatLen = CurrNodeLen; +#ifndef NDEBUG + CurrNode->ID = CurID++; +#endif for (auto &ChildPair : CurrNode->Children) { assert(ChildPair.second && "Node had a null child!"); ToVisit.push_back(