44 static SourceDelta
get(
unsigned Loc,
int D) {
62 friend class DeltaTreeInteriorNode;
68 enum { WidthFactor = 8 };
71 SourceDelta Values[2 * WidthFactor - 1];
75 unsigned char NumValuesUsed = 0;
86 DeltaTreeNode(
bool isLeaf =
true) : IsLeaf(isLeaf) {}
88 bool isLeaf()
const {
return IsLeaf; }
89 int getFullDelta()
const {
return FullDelta; }
90 bool isFull()
const {
return NumValuesUsed == 2 * WidthFactor - 1; }
92 unsigned getNumValuesUsed()
const {
return NumValuesUsed; }
94 const SourceDelta &getValue(
unsigned i)
const {
95 assert(i < NumValuesUsed &&
"Invalid value #");
99 SourceDelta &getValue(
unsigned i) {
100 assert(i < NumValuesUsed &&
"Invalid value #");
108 bool DoInsertion(
unsigned FileIndex,
int Delta, InsertResult *InsertRes);
110 void DoSplit(InsertResult &InsertRes);
114 void RecomputeFullDeltaLocally();
121class DeltaTreeInteriorNode :
public DeltaTreeNode {
122 friend class DeltaTreeNode;
124 DeltaTreeNode *
Children[2 * WidthFactor];
126 ~DeltaTreeInteriorNode() {
127 for (
unsigned i = 0, e = NumValuesUsed + 1; i !=
e; ++i)
128 Children[i]->Destroy();
132 DeltaTreeInteriorNode() : DeltaTreeNode(
false ) {}
134 DeltaTreeInteriorNode(
const InsertResult &
IR)
135 : DeltaTreeNode(
false ) {
138 Values[0] =
IR.Split;
140 IR.LHS->getFullDelta() +
IR.RHS->getFullDelta() +
IR.Split.Delta;
144 const DeltaTreeNode *getChild(
unsigned i)
const {
145 assert(i < getNumValuesUsed() + 1 &&
"Invalid child");
149 DeltaTreeNode *getChild(
unsigned i) {
150 assert(i < getNumValuesUsed() + 1 &&
"Invalid child");
154 static bool classof(
const DeltaTreeNode *
N) {
return !
N->isLeaf(); }
160void DeltaTreeNode::Destroy() {
164 delete cast<DeltaTreeInteriorNode>(
this);
169void DeltaTreeNode::RecomputeFullDeltaLocally() {
170 int NewFullDelta = 0;
171 for (
unsigned i = 0, e = getNumValuesUsed(); i !=
e; ++i)
172 NewFullDelta += Values[i].Delta;
173 if (
auto *IN = dyn_cast<DeltaTreeInteriorNode>(
this))
174 for (
unsigned i = 0, e = getNumValuesUsed() + 1; i !=
e; ++i)
175 NewFullDelta += IN->getChild(i)->getFullDelta();
176 FullDelta = NewFullDelta;
183bool DeltaTreeNode::DoInsertion(
unsigned FileIndex,
int Delta,
184 InsertResult *InsertRes) {
189 unsigned i = 0,
e = getNumValuesUsed();
190 while (i != e && FileIndex > getValue(i).FileLoc)
195 if (i != e && getValue(i).FileLoc == FileIndex) {
200 Values[i].Delta += Delta;
211 memmove(&Values[i + 1], &Values[i],
sizeof(Values[0]) * (e - i));
212 Values[i] = SourceDelta::get(FileIndex, Delta);
219 assert(InsertRes &&
"No result location specified");
222 if (InsertRes->Split.FileLoc > FileIndex)
223 InsertRes->LHS->DoInsertion(FileIndex, Delta,
nullptr );
225 InsertRes->RHS->DoInsertion(FileIndex, Delta,
nullptr );
230 auto *IN = cast<DeltaTreeInteriorNode>(
this);
231 if (!IN->Children[i]->DoInsertion(FileIndex, Delta, InsertRes))
241 memmove(&IN->Children[i + 2], &IN->Children[i + 1],
242 (e - i) *
sizeof(IN->Children[0]));
243 IN->Children[i] = InsertRes->LHS;
244 IN->Children[i + 1] = InsertRes->RHS;
247 memmove(&Values[i + 1], &Values[i], (e - i) *
sizeof(Values[0]));
248 Values[i] = InsertRes->Split;
256 IN->Children[i] = InsertRes->LHS;
257 DeltaTreeNode *SubRHS = InsertRes->RHS;
258 SourceDelta SubSplit = InsertRes->Split;
264 DeltaTreeInteriorNode *InsertSide;
265 if (SubSplit.FileLoc < InsertRes->Split.FileLoc)
266 InsertSide = cast<DeltaTreeInteriorNode>(InsertRes->LHS);
268 InsertSide = cast<DeltaTreeInteriorNode>(InsertRes->RHS);
275 e = InsertSide->getNumValuesUsed();
276 while (i != e && SubSplit.FileLoc > InsertSide->getValue(i).FileLoc)
282 memmove(&InsertSide->Children[i + 2], &InsertSide->Children[i + 1],
283 (e - i) *
sizeof(IN->Children[0]));
284 InsertSide->Children[i + 1] = SubRHS;
287 memmove(&InsertSide->Values[i + 1], &InsertSide->Values[i],
288 (e - i) *
sizeof(Values[0]));
289 InsertSide->Values[i] = SubSplit;
290 ++InsertSide->NumValuesUsed;
291 InsertSide->FullDelta += SubSplit.Delta + SubRHS->getFullDelta();
298void DeltaTreeNode::DoSplit(InsertResult &InsertRes) {
299 assert(isFull() &&
"Why split a non-full node?");
307 DeltaTreeNode *NewNode;
308 if (
auto *IN = dyn_cast<DeltaTreeInteriorNode>(
this)) {
311 DeltaTreeInteriorNode *
New =
new DeltaTreeInteriorNode();
312 memcpy(&
New->Children[0], &IN->Children[WidthFactor],
313 WidthFactor *
sizeof(IN->Children[0]));
317 NewNode =
new DeltaTreeNode();
321 memcpy(&NewNode->Values[0], &Values[WidthFactor],
322 (WidthFactor - 1) *
sizeof(Values[0]));
325 NewNode->NumValuesUsed = NumValuesUsed = WidthFactor - 1;
328 NewNode->RecomputeFullDeltaLocally();
329 RecomputeFullDeltaLocally();
331 InsertRes.LHS =
this;
332 InsertRes.RHS = NewNode;
333 InsertRes.Split = Values[WidthFactor - 1];
345static void VerifyTree(
const DeltaTreeNode *
N) {
346 const auto *IN = dyn_cast<DeltaTreeInteriorNode>(
N);
351 for (
unsigned i = 0, e =
N->getNumValuesUsed(); i != e; ++i) {
353 assert(
N->getValue(i - 1).FileLoc <
N->getValue(i).FileLoc);
354 FullDelta +=
N->getValue(i).Delta;
356 assert(FullDelta ==
N->getFullDelta());
363 for (
unsigned i = 0, e = IN->getNumValuesUsed(); i != e; ++i) {
364 const SourceDelta &IVal =
N->getValue(i);
365 const DeltaTreeNode *IChild = IN->getChild(i);
367 assert(IN->getValue(i - 1).FileLoc < IVal.FileLoc);
368 FullDelta += IVal.Delta;
369 FullDelta += IChild->getFullDelta();
372 assert(IChild->getValue(IChild->getNumValuesUsed() - 1).FileLoc <
376 assert(IN->getChild(i + 1)->getValue(0).FileLoc > IVal.FileLoc);
380 FullDelta += IN->getChild(IN->getNumValuesUsed())->getFullDelta();
382 assert(FullDelta ==
N->getFullDelta());
386static DeltaTreeNode *
getRoot(
void *Root) {
return (DeltaTreeNode *)Root; }
393 "Can only copy empty tree");
394 Root =
new DeltaTreeNode();
403 const DeltaTreeNode *Node =
getRoot(Root);
412 unsigned NumValsGreater = 0;
413 for (
unsigned e = Node->getNumValuesUsed(); NumValsGreater != e;
415 const SourceDelta &Val = Node->getValue(NumValsGreater);
417 if (Val.FileLoc >= FileIndex)
424 const auto *IN = dyn_cast<DeltaTreeInteriorNode>(Node);
430 for (
unsigned i = 0; i != NumValsGreater; ++i)
431 Result += IN->getChild(i)->getFullDelta();
436 if (NumValsGreater != Node->getNumValuesUsed() &&
437 Node->getValue(NumValsGreater).FileLoc == FileIndex)
438 return Result + IN->getChild(NumValsGreater)->getFullDelta();
442 Node = IN->getChild(NumValsGreater);
451 assert(Delta &&
"Adding a noop?");
452 DeltaTreeNode *MyRoot =
getRoot(Root);
454 DeltaTreeNode::InsertResult InsertRes;
455 if (MyRoot->DoInsertion(FileIndex, Delta, &InsertRes)) {
456 Root =
new DeltaTreeInteriorNode(InsertRes);
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static DeltaTreeNode * getRoot(void *Root)
Legalize the Machine IR a function s Machine IR
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
DeltaTree - a multiway search tree (BTree) structure with some fancy features.
void AddDelta(unsigned FileIndex, int Delta)
AddDelta - When a change is made that shifts around the text buffer, this method is used to record th...
int getDeltaAt(unsigned FileIndex) const
getDeltaAt - Return the accumulated delta at the specified file offset.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)