LLVM API Documentation
00001 //===- lib/Support/IntervalMap.cpp - A sorted interval map ----------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the few non-templated functions in IntervalMap. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/ADT/IntervalMap.h" 00015 00016 namespace llvm { 00017 namespace IntervalMapImpl { 00018 00019 void Path::replaceRoot(void *Root, unsigned Size, IdxPair Offsets) { 00020 assert(!path.empty() && "Can't replace missing root"); 00021 path.front() = Entry(Root, Size, Offsets.first); 00022 path.insert(path.begin() + 1, Entry(subtree(0), Offsets.second)); 00023 } 00024 00025 NodeRef Path::getLeftSibling(unsigned Level) const { 00026 // The root has no siblings. 00027 if (Level == 0) 00028 return NodeRef(); 00029 00030 // Go up the tree until we can go left. 00031 unsigned l = Level - 1; 00032 while (l && path[l].offset == 0) 00033 --l; 00034 00035 // We can't go left. 00036 if (path[l].offset == 0) 00037 return NodeRef(); 00038 00039 // NR is the subtree containing our left sibling. 00040 NodeRef NR = path[l].subtree(path[l].offset - 1); 00041 00042 // Keep right all the way down. 00043 for (++l; l != Level; ++l) 00044 NR = NR.subtree(NR.size() - 1); 00045 return NR; 00046 } 00047 00048 void Path::moveLeft(unsigned Level) { 00049 assert(Level != 0 && "Cannot move the root node"); 00050 00051 // Go up the tree until we can go left. 00052 unsigned l = 0; 00053 if (valid()) { 00054 l = Level - 1; 00055 while (path[l].offset == 0) { 00056 assert(l != 0 && "Cannot move beyond begin()"); 00057 --l; 00058 } 00059 } else if (height() < Level) 00060 // end() may have created a height=0 path. 00061 path.resize(Level + 1, Entry(nullptr, 0, 0)); 00062 00063 // NR is the subtree containing our left sibling. 00064 --path[l].offset; 00065 NodeRef NR = subtree(l); 00066 00067 // Get the rightmost node in the subtree. 00068 for (++l; l != Level; ++l) { 00069 path[l] = Entry(NR, NR.size() - 1); 00070 NR = NR.subtree(NR.size() - 1); 00071 } 00072 path[l] = Entry(NR, NR.size() - 1); 00073 } 00074 00075 NodeRef Path::getRightSibling(unsigned Level) const { 00076 // The root has no siblings. 00077 if (Level == 0) 00078 return NodeRef(); 00079 00080 // Go up the tree until we can go right. 00081 unsigned l = Level - 1; 00082 while (l && atLastEntry(l)) 00083 --l; 00084 00085 // We can't go right. 00086 if (atLastEntry(l)) 00087 return NodeRef(); 00088 00089 // NR is the subtree containing our right sibling. 00090 NodeRef NR = path[l].subtree(path[l].offset + 1); 00091 00092 // Keep left all the way down. 00093 for (++l; l != Level; ++l) 00094 NR = NR.subtree(0); 00095 return NR; 00096 } 00097 00098 void Path::moveRight(unsigned Level) { 00099 assert(Level != 0 && "Cannot move the root node"); 00100 00101 // Go up the tree until we can go right. 00102 unsigned l = Level - 1; 00103 while (l && atLastEntry(l)) 00104 --l; 00105 00106 // NR is the subtree containing our right sibling. If we hit end(), we have 00107 // offset(0) == node(0).size(). 00108 if (++path[l].offset == path[l].size) 00109 return; 00110 NodeRef NR = subtree(l); 00111 00112 for (++l; l != Level; ++l) { 00113 path[l] = Entry(NR, 0); 00114 NR = NR.subtree(0); 00115 } 00116 path[l] = Entry(NR, 0); 00117 } 00118 00119 00120 IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity, 00121 const unsigned *CurSize, unsigned NewSize[], 00122 unsigned Position, bool Grow) { 00123 assert(Elements + Grow <= Nodes * Capacity && "Not enough room for elements"); 00124 assert(Position <= Elements && "Invalid position"); 00125 if (!Nodes) 00126 return IdxPair(); 00127 00128 // Trivial algorithm: left-leaning even distribution. 00129 const unsigned PerNode = (Elements + Grow) / Nodes; 00130 const unsigned Extra = (Elements + Grow) % Nodes; 00131 IdxPair PosPair = IdxPair(Nodes, 0); 00132 unsigned Sum = 0; 00133 for (unsigned n = 0; n != Nodes; ++n) { 00134 Sum += NewSize[n] = PerNode + (n < Extra); 00135 if (PosPair.first == Nodes && Sum > Position) 00136 PosPair = IdxPair(n, Position - (Sum - NewSize[n])); 00137 } 00138 assert(Sum == Elements + Grow && "Bad distribution sum"); 00139 00140 // Subtract the Grow element that was added. 00141 if (Grow) { 00142 assert(PosPair.first < Nodes && "Bad algebra"); 00143 assert(NewSize[PosPair.first] && "Too few elements to need Grow"); 00144 --NewSize[PosPair.first]; 00145 } 00146 00147 #ifndef NDEBUG 00148 Sum = 0; 00149 for (unsigned n = 0; n != Nodes; ++n) { 00150 assert(NewSize[n] <= Capacity && "Overallocated node"); 00151 Sum += NewSize[n]; 00152 } 00153 assert(Sum == Elements && "Bad distribution sum"); 00154 #endif 00155 00156 return PosPair; 00157 } 00158 00159 } // namespace IntervalMapImpl 00160 } // namespace llvm 00161