[llvm] r215953 - NVPTX: Use RAUW instead of reinventing the wheel

Duncan P. N. Exon Smith dexonsmith at apple.com
Mon Aug 18 17:20:02 PDT 2014


Author: dexonsmith
Date: Mon Aug 18 19:20:02 2014
New Revision: 215953

URL: http://llvm.org/viewvc/llvm-project?rev=215953&view=rev
Log:
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.

Modified:
    llvm/trunk/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp

Modified: llvm/trunk/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp?rev=215953&r1=215952&r2=215953&view=diff
==============================================================================
--- llvm/trunk/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp (original)
+++ llvm/trunk/lib/Target/NVPTX/NVPTXGenericToNVVM.cpp Mon Aug 18 19:20:02 2014
@@ -140,20 +140,23 @@ bool GenericToNVVM::runOnModule(Module &
   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;
 }





More information about the llvm-commits mailing list