From 6b863256e442f8d1df4dcbd1325ad132380de828 Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Tue, 19 Aug 2014 00:20:02 +0000 Subject: [PATCH] NVPTX: Use RAUW instead of reinventing the wheel This code had a homemade RAUW that was incorrect when a user was a constant: instead of calling `replaceUsersWithOnConstant()` it would incorrectly update the operand in-place, invalidating `LLVMContextImpl::ExprConstants`. RAUW does the job better. The ValueHandle that `GVMap` is holding onto needs to be removed first, so this commit also removes each variable from the map on-the-fly. Since deletions from `ExprConstants` use a linear search that compares directly on the pointer value (instead of using the key), there isn't an obvious way to expose this with a testcase. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215953 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/NVPTX/NVPTXGenericToNVVM.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp b/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp index faa9fdb424b..58fa95b54ac 100644 --- a/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp +++ b/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp @@ -140,20 +140,23 @@ bool GenericToNVVM::runOnModule(Module &M) { for (GVMapTy::iterator I = GVMap.begin(), E = GVMap.end(); I != E;) { GlobalVariable *GV = I->first; GlobalVariable *NewGV = I->second; - ++I; + + // Remove GV from the map so that it can be RAUWed. Note that + // DenseMap::erase() won't invalidate any iterators but this one. + auto Next = std::next(I); + GVMap.erase(I); + I = Next; + Constant *BitCastNewGV = ConstantExpr::getPointerCast(NewGV, GV->getType()); // At this point, the remaining uses of GV should be found only in global // variable initializers, as other uses have been already been removed // while walking through the instructions in function definitions. - for (Value::use_iterator UI = GV->use_begin(), UE = GV->use_end(); - UI != UE;) - (UI++)->set(BitCastNewGV); + GV->replaceAllUsesWith(BitCastNewGV); std::string Name = GV->getName(); - GV->removeDeadConstantUsers(); GV->eraseFromParent(); NewGV->setName(Name); } - GVMap.clear(); + assert(GVMap.empty() && "Expected it to be empty by now"); return true; }