[llvm-commits] CVS: poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp

Chris Lattner lattner at cs.uiuc.edu
Mon Nov 1 22:42:31 PST 2004



Changes in directory poolalloc/lib/PoolAllocate:

TransformFunctionBody.cpp updated: 1.30 -> 1.31

---
Log message:

Codegen X = realloc(Y, Size) into X = poolrealloc(PD, Y, Size) instead of

  X = poolalloc(PD, Size);
  memcpy(X, Y, Size);
  poolfree(PD, Y);

This does two things: 
1. It is actually correct.  If the realloc grows the allocation, the old 
   memcpy would read past the end of the input buffer.  This caused 
   Shootout/strcat to fail, which now passes.
2. This allows the poolalloc runtime to implement realloc efficiently,
   though our current one does not do so.



---
Diffs of the changes:  (+31 -26)

Index: poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp
diff -u poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.30 poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.31
--- poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp:1.30	Mon Nov  1 15:03:51 2004
+++ poolalloc/lib/PoolAllocate/TransformFunctionBody.cpp	Tue Nov  2 00:42:21 2004
@@ -165,7 +165,7 @@
   }
 
   // Remove old allocation instruction.
-  I->getParent()->getInstList().erase(I);
+  I->eraseFromParent();
   return Casted;
 }
 
@@ -261,37 +261,42 @@
 
 
 void FuncTransform::visitReallocCall(CallSite CS) {
-  Module *M = CS.getInstruction()->getParent()->getParent()->getParent();
   assert(CS.arg_end()-CS.arg_begin() == 2 && "realloc takes two arguments!");
+  Instruction *I = CS.getInstruction();
+  Value *PH = getPoolHandle(I);
   Value *OldPtr = *CS.arg_begin();
   Value *Size = *(CS.arg_begin()+1);
 
-  BasicBlock::iterator BBI =
-    TransformAllocationInstr(CS.getInstruction(), Size);
-  Value *NewPtr = BBI++;
-
-  // We just turned the call of 'realloc' into the equivalent of malloc.  To
-  // finish realloc, we need to copy the memory from the old block to the new,
-  // then free the old block.
-  const Type *SBPtr = PointerType::get(Type::SByteTy);
-  Function *MemCpy = M->getOrInsertFunction("llvm.memcpy",
-                                            Type::VoidTy, SBPtr, SBPtr,
-                                            Type::UIntTy, Type::UIntTy, 0);
-
-  if (NewPtr->getType() != SBPtr)
-    NewPtr = new CastInst(NewPtr, SBPtr, NewPtr->getName(), BBI);
-  if (OldPtr->getType() != SBPtr)
-    OldPtr = new CastInst(OldPtr, SBPtr, OldPtr->getName(), BBI);
   if (Size->getType() != Type::UIntTy)
-    Size = new CastInst(Size, Type::UIntTy, Size->getName(), BBI);
-  
-  // We know that the memory returned by poolalloc is at least 4 byte aligned.
-  new CallInst(MemCpy, make_vector(NewPtr, OldPtr, Size, 
-                                   ConstantUInt::get(Type::UIntTy, 4), 0),
-               "", BBI);
+    Size = new CastInst(Size, Type::UIntTy, Size->getName(), I);
+
+  static Type *VoidPtrTy = PointerType::get(Type::SByteTy);
+  if (OldPtr->getType() != VoidPtrTy)
+    OldPtr = new CastInst(OldPtr, VoidPtrTy, OldPtr->getName(), I);
+
+  std::string Name = I->getName(); I->setName("");
+  Instruction *V = new CallInst(PAInfo.PoolRealloc, make_vector(PH, OldPtr,
+                                                                Size, 0),
+                                Name, I);
+  Instruction *Casted = V;
+  if (V->getType() != I->getType())
+    Casted = new CastInst(V, I->getType(), V->getName(), I);
+
+  // Update def-use info
+  I->replaceAllUsesWith(Casted);
+
+  // If we are modifying the original function, update the DSGraph.
+  if (!FI.Clone) {
+    // V and Casted now point to whatever the original allocation did.
+    G.getScalarMap().replaceScalar(I, V);
+    if (V != Casted)
+      G.getScalarMap()[Casted] = G.getScalarMap()[V];
+  } else {             // Otherwise, update the NewToOldValueMap
+    UpdateNewToOldValueMap(I, V, V != Casted ? Casted : 0);
+  }
 
-  // Free the old memory now.
-  InsertPoolFreeInstr(OldPtr, BBI);
+  // Remove old allocation instruction.
+  I->eraseFromParent();
 }
 
 





More information about the llvm-commits mailing list