summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2015-09-02 22:25:07 +0000
committerPhilip Reames <listmail@philipreames.com>2015-09-02 22:25:07 +0000
commit9546f367f7110b17169d628a9fa66310b2c27256 (patch)
treec0a960aeba2bdfe5a67732387fb9bcd20720f6a1 /llvm/lib
parent6906e928122e79a0d024d655b54d84b1d591d2ba (diff)
downloadbcm5719-llvm-9546f367f7110b17169d628a9fa66310b2c27256.tar.gz
bcm5719-llvm-9546f367f7110b17169d628a9fa66310b2c27256.zip
[RewriteStatepointsForGC] Bugfix for change 246133
Fix a bug in change 246133. I didn't handle the case where we had a cycle in the use graph and could add an instruction we were about to erase back on to the worklist. Oddly, I have not been able to write a small test case for this, even with the AssertingVH added. I have confirmed the basic theory for the fix on a large failing example, but all attempts to reduce that to something appropriate for a test case have failed. Differential Revision: http://reviews.llvm.org/D12575 llvm-svn: 246718
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp32
1 files changed, 16 insertions, 16 deletions
diff --git a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
index e4a05bbeadd..7563cea9a04 100644
--- a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
+++ b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
@@ -1024,7 +1024,7 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
// doing as a post process step is easier to reason about for the moment.
DenseMap<Value *, Value *> ReverseMap;
SmallPtrSet<Instruction *, 16> NewInsts;
- SmallSetVector<Instruction *, 16> Worklist;
+ SmallSetVector<AssertingVH<Instruction>, 16> Worklist;
for (auto Item : states) {
Value *V = Item.first;
Value *Base = Item.second.getBase();
@@ -1041,11 +1041,21 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
Worklist.insert(BaseI);
}
}
- auto PushNewUsers = [&](Instruction *I) {
- for (User *U : I->users())
+ auto ReplaceBaseInstWith = [&](Value *BDV, Instruction *BaseI,
+ Value *Replacement) {
+ // Add users which are new instructions (excluding self references)
+ for (User *U : BaseI->users())
if (auto *UI = dyn_cast<Instruction>(U))
- if (NewInsts.count(UI))
+ if (NewInsts.count(UI) && UI != BaseI)
Worklist.insert(UI);
+ // Then do the actual replacement
+ NewInsts.erase(BaseI);
+ ReverseMap.erase(BaseI);
+ BaseI->replaceAllUsesWith(Replacement);
+ BaseI->eraseFromParent();
+ assert(states.count(BDV));
+ assert(states[BDV].isConflict() && states[BDV].getBase() == BaseI);
+ states[BDV] = BDVState(BDVState::Conflict, Replacement);
};
const DataLayout &DL = cast<Instruction>(def)->getModule()->getDataLayout();
while (!Worklist.empty()) {
@@ -1055,22 +1065,12 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
if (auto *BdvI = dyn_cast<Instruction>(Bdv))
if (BaseI->isIdenticalTo(BdvI)) {
DEBUG(dbgs() << "Identical Base: " << *BaseI << "\n");
- PushNewUsers(BaseI);
- BaseI->replaceAllUsesWith(Bdv);
- BaseI->eraseFromParent();
- states[Bdv] = BDVState(BDVState::Conflict, Bdv);
- NewInsts.erase(BaseI);
- ReverseMap.erase(BaseI);
+ ReplaceBaseInstWith(Bdv, BaseI, Bdv);
continue;
}
if (Value *V = SimplifyInstruction(BaseI, DL)) {
DEBUG(dbgs() << "Base " << *BaseI << " simplified to " << *V << "\n");
- PushNewUsers(BaseI);
- BaseI->replaceAllUsesWith(V);
- BaseI->eraseFromParent();
- states[Bdv] = BDVState(BDVState::Conflict, V);
- NewInsts.erase(BaseI);
- ReverseMap.erase(BaseI);
+ ReplaceBaseInstWith(Bdv, BaseI, V);
continue;
}
}
OpenPOWER on IntegriCloud