From 47e0f3a8a0b1f280457f807e4bbc6bbaa593e687 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 24 May 2002 20:29:18 +0000 Subject: Support programs that do not #include or give a full prototype for malloc and free. Lots of crufty benchmarks are using stuff like: char *malloc(); void free(); to forward declare malloc and free. Now we recognize and raise these forms git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2740 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/RaiseAllocations.cpp | 45 ++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) (limited to 'lib/Transforms/IPO/RaiseAllocations.cpp') diff --git a/lib/Transforms/IPO/RaiseAllocations.cpp b/lib/Transforms/IPO/RaiseAllocations.cpp index 9b56f6a84d..5dc1254db9 100644 --- a/lib/Transforms/IPO/RaiseAllocations.cpp +++ b/lib/Transforms/IPO/RaiseAllocations.cpp @@ -71,6 +71,22 @@ bool RaiseAllocations::doInitialization(Module *M) { MallocFunc = M->getFunction("malloc", MallocType); FreeFunc = M->getFunction("free" , FreeType); + // Check to see if the prototype is missing, giving us sbyte*(...) * malloc + // This handles the common declaration of: 'char *malloc();' + if (MallocFunc == 0) { + MallocType = FunctionType::get(PointerType::get(Type::SByteTy), + std::vector(), true); + MallocFunc = M->getFunction("malloc", MallocType); + } + + // Check to see if the prototype was forgotten, giving us void (...) * free + // This handles the common forward declaration of: 'void free();' + if (FreeFunc == 0) { + FreeType = FunctionType::get(Type::VoidTy, std::vector(),true); + FreeFunc = M->getFunction("free", FreeType); + } + + // Don't mess with locally defined versions of these functions... if (MallocFunc && !MallocFunc->isExternal()) MallocFunc = 0; if (FreeFunc && !FreeFunc->isExternal()) FreeFunc = 0; @@ -89,15 +105,38 @@ bool RaiseAllocations::runOnBasicBlock(BasicBlock *BB) { if (CallInst *CI = dyn_cast(I)) { if (CI->getCalledValue() == MallocFunc) { // Replace call to malloc? const Type *PtrSByte = PointerType::get(Type::SByteTy); - MallocInst *MallocI = new MallocInst(PtrSByte, CI->getOperand(1), - CI->getName()); + Value *Source = CI->getOperand(1); + + // If no prototype was provided for malloc, we may need to cast the + // source size. + if (Source->getType() != Type::UIntTy) { + CastInst *New = new CastInst(Source, Type::UIntTy, "MallocAmtCast"); + BI = BIL.insert(BI, New)+1; + Source = New; + } + + MallocInst *MallocI = new MallocInst(PtrSByte, Source, CI->getName()); + CI->setName(""); ReplaceInstWithInst(BIL, BI, MallocI); Changed = true; ++NumRaised; continue; // Skip the ++BI } else if (CI->getCalledValue() == FreeFunc) { // Replace call to free? - ReplaceInstWithInst(BIL, BI, new FreeInst(CI->getOperand(1))); + // If no prototype was provided for free, we may need to cast the + // source pointer. This should be really uncommon, but it's neccesary + // just in case we are dealing with wierd code like this: + // free((long)ptr); + // + Value *Source = CI->getOperand(1); + if (!isa(Source->getType())) { + CastInst *New = new CastInst(Source, PointerType::get(Type::SByteTy), + "FreePtrCast"); + BI = BIL.insert(BI, New)+1; + Source = New; + } + + ReplaceInstWithInst(BIL, BI, new FreeInst(Source)); Changed = true; continue; // Skip the ++BI ++NumRaised; -- cgit v1.2.3