llvm.org GIT mirror llvm / 6a9291a
Fix http://llvm.org/PR5160, to let CallbackVHs modify other ValueHandles on the same Value without breaking things. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83861 91177308-0d34-0410-b5e6-96231b3b80d8 Jeffrey Yasskin 10 years ago
3 changed file(s) with 137 addition(s) and 28 deletion(s). Raw diff Collapse all Expand all
110110 HandleBaseKind getKind() const { return PrevPair.getInt(); }
111111 void setPrevPtr(ValueHandleBase **Ptr) { PrevPair.setPointer(Ptr); }
112112
113 /// AddToExistingUseList - Add this ValueHandle to the use list for VP,
114 /// where List is known to point into the existing use list.
113 /// AddToExistingUseList - Add this ValueHandle to the use list for VP, where
114 /// List is the address of either the head of the list or a Next node within
115 /// the existing use list.
115116 void AddToExistingUseList(ValueHandleBase **List);
117
118 /// AddToExistingUseListAfter - Add this ValueHandle to the use list after
119 /// Node.
120 void AddToExistingUseListAfter(ValueHandleBase *Node);
116121
117122 /// AddToUseList - Add this ValueHandle to the use list for VP.
118123 void AddToUseList();
410410 }
411411 }
412412
413 void ValueHandleBase::AddToExistingUseListAfter(ValueHandleBase *List) {
414 assert(List && "Must insert after existing node");
415
416 Next = List->Next;
417 setPrevPtr(&List->Next);
418 List->Next = this;
419 if (Next)
420 Next->setPrevPtr(&Next);
421 }
422
413423 /// AddToUseList - Add this ValueHandle to the use list for VP.
414424 void ValueHandleBase::AddToUseList() {
415425 assert(VP && "Null pointer doesn't have a use list!");
489499 ValueHandleBase *Entry = pImpl->ValueHandles[V];
490500 assert(Entry && "Value bit set but no entries exist");
491501
492 while (Entry) {
493 // Advance pointer to avoid invalidation.
494 ValueHandleBase *ThisNode = Entry;
495 Entry = Entry->Next;
496
497 switch (ThisNode->getKind()) {
502 // We use a local ValueHandleBase as an iterator so that
503 // ValueHandles can add and remove themselves from the list without
504 // breaking our iteration. This is not really an AssertingVH; we
505 // just have to give ValueHandleBase some kind.
506 for (ValueHandleBase Iterator(Assert, *Entry); Entry; Entry = Iterator.Next) {
507 Iterator.RemoveFromUseList();
508 Iterator.AddToExistingUseListAfter(Entry);
509 assert(Entry->Next == &Iterator && "Loop invariant broken.");
510
511 switch (Entry->getKind()) {
498512 case Assert:
499 #ifndef NDEBUG // Only in -g mode...
500 errs() << "While deleting: " << *V->getType() << " %" << V->getNameStr()
501 << "\n";
502 #endif
503 llvm_unreachable("An asserting value handle still pointed to this"
504 " value!");
513 break;
505514 case Tracking:
506515 // Mark that this value has been deleted by setting it to an invalid Value
507516 // pointer.
508 ThisNode->operator=(DenseMapInfo::getTombstoneKey());
517 Entry->operator=(DenseMapInfo::getTombstoneKey());
509518 break;
510519 case Weak:
511520 // Weak just goes to null, which will unlink it from the list.
512 ThisNode->operator=(0);
521 Entry->operator=(0);
513522 break;
514523 case Callback:
515524 // Forward to the subclass's implementation.
516 static_cast(ThisNode)->deleted();
525 static_cast(Entry)->deleted();
517526 break;
518527 }
519528 }
520529
521 // All callbacks and weak references should be dropped by now.
522 assert(!V->HasValueHandle && "All references to V were not removed?");
530 // All callbacks, weak references, and assertingVHs should be dropped by now.
531 if (V->HasValueHandle) {
532 #ifndef NDEBUG // Only in +Asserts mode...
533 errs() << "While deleting: " << *V->getType() << " %" << V->getNameStr()
534 << "\n";
535 if (pImpl->ValueHandles[V]->getKind() == Assert)
536 llvm_unreachable("An asserting value handle still pointed to this"
537 " value!");
538
539 #endif
540 llvm_unreachable("All references to V were not removed?");
541 }
523542 }
524543
525544
534553
535554 assert(Entry && "Value bit set but no entries exist");
536555
537 while (Entry) {
538 // Advance pointer to avoid invalidation.
539 ValueHandleBase *ThisNode = Entry;
540 Entry = Entry->Next;
541
542 switch (ThisNode->getKind()) {
556 // We use a local ValueHandleBase as an iterator so that
557 // ValueHandles can add and remove themselves from the list without
558 // breaking our iteration. This is not really an AssertingVH; we
559 // just have to give ValueHandleBase some kind.
560 for (ValueHandleBase Iterator(Assert, *Entry); Entry; Entry = Iterator.Next) {
561 Iterator.RemoveFromUseList();
562 Iterator.AddToExistingUseListAfter(Entry);
563 assert(Entry->Next == &Iterator && "Loop invariant broken.");
564
565 switch (Entry->getKind()) {
543566 case Assert:
544567 // Asserting handle does not follow RAUW implicitly.
545568 break;
552575 // FALLTHROUGH
553576 case Weak:
554577 // Weak goes to the new value, which will unlink it from Old's list.
555 ThisNode->operator=(New);
578 Entry->operator=(New);
556579 break;
557580 case Callback:
558581 // Forward to the subclass's implementation.
559 static_cast(ThisNode)->allUsesReplacedWith(New);
582 static_cast(Entry)->allUsesReplacedWith(New);
560583 break;
561584 }
562585 }
1010
1111 #include "llvm/Constants.h"
1212 #include "llvm/Instructions.h"
13 #include "llvm/ADT/OwningPtr.h"
1314
1415 #include "gtest/gtest.h"
1516
326327 BitcastUser->getOperand(0));
327328 }
328329
329 }
330 TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
331 // When a CallbackVH modifies other ValueHandles in its callbacks,
332 // that shouldn't interfere with non-modified ValueHandles receiving
333 // their appropriate callbacks.
334 //
335 // We create the active CallbackVH in the middle of a palindromic
336 // arrangement of other VHs so that the bad behavior would be
337 // triggered in whichever order callbacks run.
338
339 class DestroyingVH : public CallbackVH {
340 public:
341 OwningPtr ToClear[2];
342 DestroyingVH(Value *V) {
343 ToClear[0].reset(new WeakVH(V));
344 setValPtr(V);
345 ToClear[1].reset(new WeakVH(V));
346 }
347 virtual void deleted() {
348 ToClear[0].reset();
349 ToClear[1].reset();
350 CallbackVH::deleted();
351 }
352 virtual void allUsesReplacedWith(Value *) {
353 ToClear[0].reset();
354 ToClear[1].reset();
355 }
356 };
357
358 {
359 WeakVH ShouldBeVisited1(BitcastV.get());
360 DestroyingVH C(BitcastV.get());
361 WeakVH ShouldBeVisited2(BitcastV.get());
362
363 BitcastV->replaceAllUsesWith(ConstantV);
364 EXPECT_EQ(ConstantV, static_cast(ShouldBeVisited1));
365 EXPECT_EQ(ConstantV, static_cast(ShouldBeVisited2));
366 }
367
368 {
369 WeakVH ShouldBeVisited1(BitcastV.get());
370 DestroyingVH C(BitcastV.get());
371 WeakVH ShouldBeVisited2(BitcastV.get());
372
373 BitcastV.reset();
374 EXPECT_EQ(NULL, static_cast(ShouldBeVisited1));
375 EXPECT_EQ(NULL, static_cast(ShouldBeVisited2));
376 }
377 }
378
379 TEST_F(ValueHandle, AssertingVHCheckedLast) {
380 // If a CallbackVH exists to clear out a group of AssertingVHs on
381 // Value deletion, the CallbackVH should get a chance to do so
382 // before the AssertingVHs assert.
383
384 class ClearingVH : public CallbackVH {
385 public:
386 AssertingVH *ToClear[2];
387 ClearingVH(Value *V,
388 AssertingVH &A0, AssertingVH &A1)
389 : CallbackVH(V) {
390 ToClear[0] = &A0;
391 ToClear[1] = &A1;
392 }
393
394 virtual void deleted() {
395 *ToClear[0] = 0;
396 *ToClear[1] = 0;
397 CallbackVH::deleted();
398 }
399 };
400
401 AssertingVH A1, A2;
402 A1 = BitcastV.get();
403 ClearingVH C(BitcastV.get(), A1, A2);
404 A2 = BitcastV.get();
405 // C.deleted() should run first, clearing the two AssertingVHs,
406 // which should prevent them from asserting.
407 BitcastV.reset();
408 }
409
410 }