aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorVictor Hernandez <vhernandez@apple.com>2009-10-17 00:00:19 +0000
committerVictor Hernandez <vhernandez@apple.com>2009-10-17 00:00:19 +0000
commit13ad5aaaff8a446758b402fd5e9aea22f5bc5682 (patch)
tree02a18132aa0c90ad96e5aafeaea17439bb9cb5c2 /lib
parent8db42d2b1ce05e69b67f37c4e56a0f987a0c01d7 (diff)
downloadexternal_llvm-13ad5aaaff8a446758b402fd5e9aea22f5bc5682.zip
external_llvm-13ad5aaaff8a446758b402fd5e9aea22f5bc5682.tar.gz
external_llvm-13ad5aaaff8a446758b402fd5e9aea22f5bc5682.tar.bz2
Autoupgrade malloc insts to malloc calls.
Update testcases that rely on malloc insts being present. Also prematurely remove MallocInst handling from IndMemRemoval and RaiseAllocations to help pass tests in this incremental step. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84292 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AsmParser/LLLexer.cpp4
-rw-r--r--lib/AsmParser/LLParser.cpp44
-rw-r--r--lib/AsmParser/LLParser.h7
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp11
-rw-r--r--lib/Transforms/IPO/IndMemRemoval.cpp37
-rw-r--r--lib/Transforms/IPO/RaiseAllocations.cpp118
-rw-r--r--lib/Transforms/Scalar/Reassociate.cpp3
-rw-r--r--lib/VMCore/Core.cpp8
-rw-r--r--lib/VMCore/Instructions.cpp40
9 files changed, 126 insertions, 146 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 0e9f1a0..6d66011 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -602,6 +602,9 @@ lltok::Kind LLLexer::LexIdentifier() {
// Scan CurPtr ahead, seeing if there is just whitespace before the newline.
if (JustWhitespaceNewLine(CurPtr))
return lltok::kw_zeroext;
+ } else if (Len == 6 && !memcmp(StartChar, "malloc", 6)) {
+ // Autoupgrade malloc instruction
+ return lltok::kw_malloc;
}
// Keywords for instructions.
@@ -641,7 +644,6 @@ lltok::Kind LLLexer::LexIdentifier() {
INSTKEYWORD(unwind, Unwind);
INSTKEYWORD(unreachable, Unreachable);
- INSTKEYWORD(malloc, Malloc);
INSTKEYWORD(alloca, Alloca);
INSTKEYWORD(free, Free);
INSTKEYWORD(load, Load);
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 1e1ddf0..001d56d 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -69,6 +69,27 @@ bool LLParser::Run() {
/// ValidateEndOfModule - Do final validity and sanity checks at the end of the
/// module.
bool LLParser::ValidateEndOfModule() {
+ // Update auto-upgraded malloc calls from "autoupgrade_malloc" to "malloc".
+ if (MallocF) {
+ MallocF->setName("malloc");
+ // If setName() does not set the name to "malloc", then there is already a
+ // declaration of "malloc". In that case, iterate over all calls to MallocF
+ // and get them to call the declared "malloc" instead.
+ if (MallocF->getName() != "malloc") {
+ Function* realMallocF = M->getFunction("malloc");
+ for (User::use_iterator UI = MallocF->use_begin(), UE= MallocF->use_end();
+ UI != UE; ) {
+ User* user = *UI;
+ UI++;
+ if (CallInst *Call = dyn_cast<CallInst>(user))
+ Call->setCalledFunction(realMallocF);
+ }
+ if (!realMallocF->doesNotAlias(0)) realMallocF->setDoesNotAlias(0);
+ MallocF->eraseFromParent();
+ MallocF = NULL;
+ }
+ }
+
if (!ForwardRefTypes.empty())
return Error(ForwardRefTypes.begin()->second.second,
"use of undefined type named '" +
@@ -2783,8 +2804,8 @@ bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
case lltok::kw_call: return ParseCall(Inst, PFS, false);
case lltok::kw_tail: return ParseCall(Inst, PFS, true);
// Memory.
- case lltok::kw_alloca:
- case lltok::kw_malloc: return ParseAlloc(Inst, PFS, KeywordVal);
+ case lltok::kw_alloca: return ParseAlloc(Inst, PFS);
+ case lltok::kw_malloc: return ParseAlloc(Inst, PFS, BB, false);
case lltok::kw_free: return ParseFree(Inst, PFS);
case lltok::kw_load: return ParseLoad(Inst, PFS, false);
case lltok::kw_store: return ParseStore(Inst, PFS, false);
@@ -3445,7 +3466,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
/// ::= 'malloc' Type (',' TypeAndValue)? (',' OptionalInfo)?
/// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)?
bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
- unsigned Opc) {
+ BasicBlock* BB, bool isAlloca) {
PATypeHolder Ty(Type::getVoidTy(Context));
Value *Size = 0;
LocTy SizeLoc;
@@ -3466,10 +3487,21 @@ bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
if (Size && Size->getType() != Type::getInt32Ty(Context))
return Error(SizeLoc, "element count must be i32");
- if (Opc == Instruction::Malloc)
- Inst = new MallocInst(Ty, Size, Alignment);
- else
+ if (isAlloca)
Inst = new AllocaInst(Ty, Size, Alignment);
+ else {
+ // Autoupgrade old malloc instruction to malloc call.
+ const Type* IntPtrTy = Type::getInt32Ty(Context);
+ const Type* Int8PtrTy = PointerType::getUnqual(Type::getInt8Ty(Context));
+ if (!MallocF)
+ // Prototype malloc as "void *autoupgrade_malloc(int32)".
+ MallocF = cast<Function>(M->getOrInsertFunction("autoupgrade_malloc",
+ Int8PtrTy, IntPtrTy, NULL));
+ // "autoupgrade_malloc" updated to "malloc" in ValidateEndOfModule().
+
+ Inst = cast<Instruction>(CallInst::CreateMalloc(BB, IntPtrTy, Ty,
+ Size, MallocF));
+ }
return false;
}
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 97bf2f3..5dd6a2e 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -75,9 +75,11 @@ namespace llvm {
std::map<std::string, std::pair<GlobalValue*, LocTy> > ForwardRefVals;
std::map<unsigned, std::pair<GlobalValue*, LocTy> > ForwardRefValIDs;
std::vector<GlobalValue*> NumberedVals;
+ Function* MallocF;
public:
LLParser(MemoryBuffer *F, SourceMgr &SM, SMDiagnostic &Err, Module *m) :
- Context(m->getContext()), Lex(F, SM, Err, m->getContext()), M(m) {}
+ Context(m->getContext()), Lex(F, SM, Err, m->getContext()),
+ M(m), MallocF(NULL) {}
bool Run();
LLVMContext& getContext() { return Context; }
@@ -276,7 +278,8 @@ namespace llvm {
bool ParseShuffleVector(Instruction *&I, PerFunctionState &PFS);
bool ParsePHI(Instruction *&I, PerFunctionState &PFS);
bool ParseCall(Instruction *&I, PerFunctionState &PFS, bool isTail);
- bool ParseAlloc(Instruction *&I, PerFunctionState &PFS, unsigned Opc);
+ bool ParseAlloc(Instruction *&I, PerFunctionState &PFS,
+ BasicBlock *BB = 0, bool isAlloca = true);
bool ParseFree(Instruction *&I, PerFunctionState &PFS);
bool ParseLoad(Instruction *&I, PerFunctionState &PFS, bool isVolatile);
bool ParseStore(Instruction *&I, PerFunctionState &PFS, bool isVolatile);
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 4eb12c6..fe4556f 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -2044,14 +2044,21 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
}
case bitc::FUNC_CODE_INST_MALLOC: { // MALLOC: [instty, op, align]
+ // Autoupgrade malloc instruction to malloc call.
if (Record.size() < 3)
return Error("Invalid MALLOC record");
const PointerType *Ty =
dyn_cast_or_null<PointerType>(getTypeByID(Record[0]));
Value *Size = getFnValueByID(Record[1], Type::getInt32Ty(Context));
- unsigned Align = Record[2];
if (!Ty || !Size) return Error("Invalid MALLOC record");
- I = new MallocInst(Ty->getElementType(), Size, (1 << Align) >> 1);
+ if (!CurBB) return Error("Invalid malloc instruction with no BB");
+ const Type* Int32Ty = IntegerType::getInt32Ty(CurBB->getContext());
+ if (Size->getType() != Int32Ty)
+ Size = CastInst::CreateIntegerCast(Size, Int32Ty, false /*ZExt*/,
+ "", CurBB);
+ Value* Malloc = CallInst::CreateMalloc(CurBB, Int32Ty,
+ Ty->getElementType(), Size, NULL);
+ I = cast<Instruction>(Malloc);
InstructionList.push_back(I);
break;
}
diff --git a/lib/Transforms/IPO/IndMemRemoval.cpp b/lib/Transforms/IPO/IndMemRemoval.cpp
index e7884ec..9bd5a92 100644
--- a/lib/Transforms/IPO/IndMemRemoval.cpp
+++ b/lib/Transforms/IPO/IndMemRemoval.cpp
@@ -24,6 +24,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Target/TargetData.h"
using namespace llvm;
STATISTIC(NumBounceSites, "Number of sites modified");
@@ -66,20 +67,28 @@ bool IndMemRemPass::runOnModule(Module &M) {
}
if (Function* F = M.getFunction("malloc")) {
if (F->isDeclaration() && F->arg_size() == 1 && !F->use_empty()) {
- Function* FN = Function::Create(F->getFunctionType(),
- GlobalValue::LinkOnceAnyLinkage,
- "malloc_llvm_bounce", &M);
- FN->setDoesNotAlias(0);
- BasicBlock* bb = BasicBlock::Create(M.getContext(), "entry",FN);
- Instruction* c = CastInst::CreateIntegerCast(
- FN->arg_begin(), Type::getInt32Ty(M.getContext()), false, "c", bb);
- Instruction* a = new MallocInst(Type::getInt8Ty(M.getContext()),
- c, "m", bb);
- ReturnInst::Create(M.getContext(), a, bb);
- ++NumBounce;
- NumBounceSites += F->getNumUses();
- F->replaceAllUsesWith(FN);
- changed = true;
+ TargetData* TD = getAnalysisIfAvailable<TargetData>();
+ if (TD) {
+ Function* FN = Function::Create(F->getFunctionType(),
+ GlobalValue::LinkOnceAnyLinkage,
+ "malloc_llvm_bounce", &M);
+ F->replaceAllUsesWith(FN);
+ FN->setDoesNotAlias(0);
+ BasicBlock* bb = BasicBlock::Create(M.getContext(), "entry", FN);
+ const Type* IntPtrTy = TD->getIntPtrType(M.getContext());
+ Value* c = FN->arg_begin();
+ if (FN->arg_begin()->getType() != IntPtrTy)
+ c = CastInst::CreateIntegerCast(FN->arg_begin(), IntPtrTy, false,
+ "c", bb);
+ Value* a = CallInst::CreateMalloc(bb, IntPtrTy,
+ Type::getInt8Ty(M.getContext()),
+ c, NULL, "m");
+ bb->getInstList().push_back(cast<Instruction>(a));
+ ReturnInst::Create(M.getContext(), a, bb);
+ ++NumBounce;
+ NumBounceSites += F->getNumUses();
+ changed = true;
+ }
}
}
return changed;
diff --git a/lib/Transforms/IPO/RaiseAllocations.cpp b/lib/Transforms/IPO/RaiseAllocations.cpp
index 4c1f26d..deb4405 100644
--- a/lib/Transforms/IPO/RaiseAllocations.cpp
+++ b/lib/Transforms/IPO/RaiseAllocations.cpp
@@ -1,4 +1,4 @@
-//===- RaiseAllocations.cpp - Convert @malloc & @free calls to insts ------===//
+//===- RaiseAllocations.cpp - Convert @free calls to insts ------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the RaiseAllocations pass which convert malloc and free
-// calls to malloc and free instructions.
+// This file defines the RaiseAllocations pass which convert free calls to free
+// instructions.
//
//===----------------------------------------------------------------------===//
@@ -29,19 +29,19 @@ using namespace llvm;
STATISTIC(NumRaised, "Number of allocations raised");
namespace {
- // RaiseAllocations - Turn @malloc and @free calls into the appropriate
+ // RaiseAllocations - Turn @free calls into the appropriate
// instruction.
//
class VISIBILITY_HIDDEN RaiseAllocations : public ModulePass {
- Function *MallocFunc; // Functions in the module we are processing
- Function *FreeFunc; // Initialized by doPassInitializationVirt
+ Function *FreeFunc; // Functions in the module we are processing
+ // Initialized by doPassInitializationVirt
public:
static char ID; // Pass identification, replacement for typeid
RaiseAllocations()
- : ModulePass(&ID), MallocFunc(0), FreeFunc(0) {}
+ : ModulePass(&ID), FreeFunc(0) {}
// doPassInitialization - For the raise allocations pass, this finds a
- // declaration for malloc and free if they exist.
+ // declaration for free if it exists.
//
void doInitialization(Module &M);
@@ -61,50 +61,16 @@ ModulePass *llvm::createRaiseAllocationsPass() {
}
-// If the module has a symbol table, they might be referring to the malloc and
-// free functions. If this is the case, grab the method pointers that the
-// module is using.
+// If the module has a symbol table, they might be referring to the free
+// function. If this is the case, grab the method pointers that the module is
+// using.
//
-// Lookup @malloc and @free in the symbol table, for later use. If they don't
+// Lookup @free in the symbol table, for later use. If they don't
// exist, or are not external, we do not worry about converting calls to that
// function into the appropriate instruction.
//
void RaiseAllocations::doInitialization(Module &M) {
- // Get Malloc and free prototypes if they exist!
- MallocFunc = M.getFunction("malloc");
- if (MallocFunc) {
- const FunctionType* TyWeHave = MallocFunc->getFunctionType();
-
- // Get the expected prototype for malloc
- const FunctionType *Malloc1Type =
- FunctionType::get(Type::getInt8PtrTy(M.getContext()),
- std::vector<const Type*>(1,
- Type::getInt64Ty(M.getContext())), false);
-
- // Chck to see if we got the expected malloc
- if (TyWeHave != Malloc1Type) {
- // Check to see if the prototype is wrong, giving us i8*(i32) * malloc
- // This handles the common declaration of: 'void *malloc(unsigned);'
- const FunctionType *Malloc2Type =
- FunctionType::get(PointerType::getUnqual(
- Type::getInt8Ty(M.getContext())),
- std::vector<const Type*>(1,
- Type::getInt32Ty(M.getContext())), false);
- if (TyWeHave != Malloc2Type) {
- // Check to see if the prototype is missing, giving us
- // i8*(...) * malloc
- // This handles the common declaration of: 'void *malloc();'
- const FunctionType *Malloc3Type =
- FunctionType::get(PointerType::getUnqual(
- Type::getInt8Ty(M.getContext())),
- true);
- if (TyWeHave != Malloc3Type)
- // Give up
- MallocFunc = 0;
- }
- }
- }
-
+ // Get free prototype if it exists!
FreeFunc = M.getFunction("free");
if (FreeFunc) {
const FunctionType* TyWeHave = FreeFunc->getFunctionType();
@@ -138,72 +104,18 @@ void RaiseAllocations::doInitialization(Module &M) {
}
// Don't mess with locally defined versions of these functions...
- if (MallocFunc && !MallocFunc->isDeclaration()) MallocFunc = 0;
if (FreeFunc && !FreeFunc->isDeclaration()) FreeFunc = 0;
}
// run - Transform calls into instructions...
//
bool RaiseAllocations::runOnModule(Module &M) {
- // Find the malloc/free prototypes...
+ // Find the free prototype...
doInitialization(M);
bool Changed = false;
- // First, process all of the malloc calls...
- if (MallocFunc) {
- std::vector<User*> Users(MallocFunc->use_begin(), MallocFunc->use_end());
- std::vector<Value*> EqPointers; // Values equal to MallocFunc
- while (!Users.empty()) {
- User *U = Users.back();
- Users.pop_back();
-
- if (Instruction *I = dyn_cast<Instruction>(U)) {
- CallSite CS = CallSite::get(I);
- if (CS.getInstruction() && !CS.arg_empty() &&
- (CS.getCalledFunction() == MallocFunc ||
- std::find(EqPointers.begin(), EqPointers.end(),
- CS.getCalledValue()) != EqPointers.end())) {
-
- Value *Source = *CS.arg_begin();
-
- // If no prototype was provided for malloc, we may need to cast the
- // source size.
- if (Source->getType() != Type::getInt32Ty(M.getContext()))
- Source =
- CastInst::CreateIntegerCast(Source,
- Type::getInt32Ty(M.getContext()),
- false/*ZExt*/,
- "MallocAmtCast", I);
-
- MallocInst *MI = new MallocInst(Type::getInt8Ty(M.getContext()),
- Source, "", I);
- MI->takeName(I);
- I->replaceAllUsesWith(MI);
-
- // If the old instruction was an invoke, add an unconditional branch
- // before the invoke, which will become the new terminator.
- if (InvokeInst *II = dyn_cast<InvokeInst>(I))
- BranchInst::Create(II->getNormalDest(), I);
-
- // Delete the old call site
- I->eraseFromParent();
- Changed = true;
- ++NumRaised;
- }
- } else if (GlobalValue *GV = dyn_cast<GlobalValue>(U)) {
- Users.insert(Users.end(), GV->use_begin(), GV->use_end());
- EqPointers.push_back(GV);
- } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
- if (CE->isCast()) {
- Users.insert(Users.end(), CE->use_begin(), CE->use_end());
- EqPointers.push_back(CE);
- }
- }
- }
- }
-
- // Next, process all free calls...
+ // Process all free calls...
if (FreeFunc) {
std::vector<User*> Users(FreeFunc->use_begin(), FreeFunc->use_end());
std::vector<Value*> EqPointers; // Values equal to FreeFunc
diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp
index e6ffac2..9160654 100644
--- a/lib/Transforms/Scalar/Reassociate.cpp
+++ b/lib/Transforms/Scalar/Reassociate.cpp
@@ -29,6 +29,7 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
#include "llvm/Pass.h"
+#include "llvm/Analysis/MallocHelper.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Debug.h"
@@ -121,7 +122,7 @@ static bool isUnmovableInstruction(Instruction *I) {
if (I->getOpcode() == Instruction::PHI ||
I->getOpcode() == Instruction::Alloca ||
I->getOpcode() == Instruction::Load ||
- I->getOpcode() == Instruction::Malloc ||
+ I->getOpcode() == Instruction::Malloc || isMalloc(I) ||
I->getOpcode() == Instruction::Invoke ||
(I->getOpcode() == Instruction::Call &&
!isa<DbgInfoIntrinsic>(I)) ||
diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp
index bff3087..5b8295f 100644
--- a/lib/VMCore/Core.cpp
+++ b/lib/VMCore/Core.cpp
@@ -1699,12 +1699,16 @@ LLVMValueRef LLVMBuildNot(LLVMBuilderRef B, LLVMValueRef V, const char *Name) {
LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
const char *Name) {
- return wrap(unwrap(B)->CreateMalloc(unwrap(Ty), 0, Name));
+ const Type* IntPtrT = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext());
+ return wrap(CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), IntPtrT,
+ unwrap(Ty), 0, 0, Twine(Name)));
}
LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
LLVMValueRef Val, const char *Name) {
- return wrap(unwrap(B)->CreateMalloc(unwrap(Ty), unwrap(Val), Name));
+ const Type* IntPtrT = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext());
+ return wrap(CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), IntPtrT,
+ unwrap(Ty), unwrap(Val), 0, Twine(Name)));
}
LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef B, LLVMTypeRef Ty,
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index f3d15cb..4ff253a 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -462,7 +462,8 @@ static Value *checkArraySize(Value *Amt, const Type *IntPtrTy) {
static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd,
const Type *IntPtrTy, const Type *AllocTy,
- Value *ArraySize, const Twine &NameStr) {
+ Value *ArraySize, Function* MallocF,
+ const Twine &NameStr) {
assert(((!InsertBefore && InsertAtEnd) || (InsertBefore && !InsertAtEnd)) &&
"createMalloc needs either InsertBefore or InsertAtEnd");
@@ -499,27 +500,34 @@ static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd,
BasicBlock* BB = InsertBefore ? InsertBefore->getParent() : InsertAtEnd;
Module* M = BB->getParent()->getParent();
const Type *BPTy = Type::getInt8PtrTy(BB->getContext());
- // prototype malloc as "void *malloc(size_t)"
- Constant *MallocF = M->getOrInsertFunction("malloc", BPTy, IntPtrTy, NULL);
- if (!cast<Function>(MallocF)->doesNotAlias(0))
- cast<Function>(MallocF)->setDoesNotAlias(0);
+ if (!MallocF)
+ // prototype malloc as "void *malloc(size_t)"
+ MallocF = cast<Function>(M->getOrInsertFunction("malloc", BPTy,
+ IntPtrTy, NULL));
+ if (!MallocF->doesNotAlias(0)) MallocF->setDoesNotAlias(0);
const PointerType *AllocPtrType = PointerType::getUnqual(AllocTy);
CallInst *MCall = NULL;
- Value *MCast = NULL;
+ Value *Result = NULL;
if (InsertBefore) {
MCall = CallInst::Create(MallocF, AllocSize, "malloccall", InsertBefore);
- // Create a cast instruction to convert to the right type...
- MCast = new BitCastInst(MCall, AllocPtrType, NameStr, InsertBefore);
+ Result = MCall;
+ if (Result->getType() != AllocPtrType)
+ // Create a cast instruction to convert to the right type...
+ Result = new BitCastInst(MCall, AllocPtrType, NameStr, InsertBefore);
} else {
- MCall = CallInst::Create(MallocF, AllocSize, "malloccall", InsertAtEnd);
- // Create a cast instruction to convert to the right type...
- MCast = new BitCastInst(MCall, AllocPtrType, NameStr);
+ MCall = CallInst::Create(MallocF, AllocSize, "malloccall");
+ Result = MCall;
+ if (Result->getType() != AllocPtrType) {
+ InsertAtEnd->getInstList().push_back(MCall);
+ // Create a cast instruction to convert to the right type...
+ Result = new BitCastInst(MCall, AllocPtrType, NameStr);
+ }
}
MCall->setTailCall();
assert(MCall->getType() != Type::getVoidTy(BB->getContext()) &&
"Malloc has void return type");
- return MCast;
+ return Result;
}
/// CreateMalloc - Generate the IR for a call to malloc:
@@ -531,7 +539,8 @@ static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd,
Value *CallInst::CreateMalloc(Instruction *InsertBefore, const Type *IntPtrTy,
const Type *AllocTy, Value *ArraySize,
const Twine &Name) {
- return createMalloc(InsertBefore, NULL, IntPtrTy, AllocTy, ArraySize, Name);
+ return createMalloc(InsertBefore, NULL, IntPtrTy, AllocTy,
+ ArraySize, NULL, Name);
}
/// CreateMalloc - Generate the IR for a call to malloc:
@@ -544,8 +553,9 @@ Value *CallInst::CreateMalloc(Instruction *InsertBefore, const Type *IntPtrTy,
/// responsibility of the caller.
Value *CallInst::CreateMalloc(BasicBlock *InsertAtEnd, const Type *IntPtrTy,
const Type *AllocTy, Value *ArraySize,
- const Twine &Name) {
- return createMalloc(NULL, InsertAtEnd, IntPtrTy, AllocTy, ArraySize, Name);
+ Function* MallocF, const Twine &Name) {
+ return createMalloc(NULL, InsertAtEnd, IntPtrTy, AllocTy,
+ ArraySize, MallocF, Name);
}
//===----------------------------------------------------------------------===//