diff options
author | Chris Lattner <sabre@nondot.org> | 2002-05-24 20:29:18 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2002-05-24 20:29:18 +0000 |
commit | 47e0f3a8a0b1f280457f807e4bbc6bbaa593e687 (patch) | |
tree | 0f559c8c0ecb14f50d249367a41c78343ebee445 /lib | |
parent | 7e9ee756a38036e4f1fc2438bf50cb17142eadbd (diff) | |
download | external_llvm-47e0f3a8a0b1f280457f807e4bbc6bbaa593e687.zip external_llvm-47e0f3a8a0b1f280457f807e4bbc6bbaa593e687.tar.gz external_llvm-47e0f3a8a0b1f280457f807e4bbc6bbaa593e687.tar.bz2 |
Support programs that do not #include <malloc.h> 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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/IPO/RaiseAllocations.cpp | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/lib/Transforms/IPO/RaiseAllocations.cpp b/lib/Transforms/IPO/RaiseAllocations.cpp index 9b56f6a..5dc1254 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<const Type*>(), 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<const Type*>(),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<CallInst>(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<PointerType>(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; |