forked from OSchip/llvm-project
Add malloc call utility functions. Patch by Victor Hernandez.
llvm-svn: 81426
This commit is contained in:
parent
2ffe029a61
commit
1d9d4bdc99
|
@ -0,0 +1,86 @@
|
|||
//===- llvm/Analysis/MallocHelper.h ---- Identify malloc calls --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This family of functions identifies calls to malloc, bitcasts of malloc
|
||||
// calls, and the types and array sizes associated with them.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_MALLOCHELPER_H
|
||||
#define LLVM_ANALYSIS_MALLOCHELPER_H
|
||||
|
||||
namespace llvm {
|
||||
class BitCastInst;
|
||||
class CallInst;
|
||||
class Instruction;
|
||||
class PointerType;
|
||||
class Twine;
|
||||
class Type;
|
||||
class Value;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// malloc Call Utility Functions.
|
||||
//
|
||||
|
||||
/// isMalloc - Returns true if the the value is either a malloc call or a
|
||||
/// bitcast of the result of a malloc call
|
||||
bool isMalloc(const Value* I);
|
||||
bool isMalloc(Value* I);
|
||||
|
||||
/// extractMallocCall - Returns the corresponding CallInst if the instruction
|
||||
/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we
|
||||
/// ignore InvokeInst here.
|
||||
const CallInst* extractMallocCall(const Value* I);
|
||||
CallInst* extractMallocCall(Value* I);
|
||||
|
||||
/// extractMallocCallFromBitCast - Returns the corresponding CallInst if the
|
||||
/// instruction is a bitcast of the result of a malloc call.
|
||||
const CallInst* extractMallocCallFromBitCast(const Value* I);
|
||||
CallInst* extractMallocCallFromBitCast(Value* I);
|
||||
|
||||
/// isArrayMalloc - Returns the corresponding CallInst if the instruction
|
||||
/// matches the malloc call IR generated by CallInst::CreateMalloc(). This
|
||||
/// means that it is a malloc call with one bitcast use AND the malloc call's
|
||||
/// size argument is:
|
||||
/// 1. a constant not equal to the malloc's allocated type
|
||||
/// or
|
||||
/// 2. the result of a multiplication by the malloc's allocated type
|
||||
/// Otherwise it returns NULL.
|
||||
/// The unique bitcast is needed to determine the type/size of the array
|
||||
/// allocation.
|
||||
CallInst* isArrayMalloc(Value* I);
|
||||
const CallInst* isArrayMalloc(const Value* I);
|
||||
|
||||
/// getMallocType - Returns the PointerType resulting from the malloc call.
|
||||
/// This PointerType is the result type of the call's only bitcast use.
|
||||
/// If there is no unique bitcast use, then return NULL.
|
||||
const PointerType* getMallocType(const CallInst* CI);
|
||||
|
||||
/// getMallocAllocatedType - Returns the Type allocated by malloc call. This
|
||||
/// Type is the result type of the call's only bitcast use. If there is no
|
||||
/// unique bitcast use, then return NULL.
|
||||
const Type* getMallocAllocatedType(const CallInst* CI);
|
||||
|
||||
/// getMallocArraySize - Returns the array size of a malloc call. The array
|
||||
/// size is computated in 1 of 3 ways:
|
||||
/// 1. If the element type if of size 1, then array size is the argument to
|
||||
/// malloc.
|
||||
/// 2. Else if the malloc's argument is a constant, the array size is that
|
||||
/// argument divided by the element type's size.
|
||||
/// 3. Else the malloc argument must be a multiplication and the array size is
|
||||
/// the first operand of the multiplication.
|
||||
/// This function returns constant 1 if:
|
||||
/// 1. The malloc call's allocated type cannot be determined.
|
||||
/// 2. IR wasn't created by a call to CallInst::CreateMalloc() with a non-NULL
|
||||
/// ArraySize.
|
||||
Value* getMallocArraySize(CallInst* CI);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
|
@ -1033,6 +1033,18 @@ public:
|
|||
BasicBlock *InsertAtEnd) {
|
||||
return new(1) CallInst(F, NameStr, InsertAtEnd);
|
||||
}
|
||||
/// CreateMalloc - Generate the IR for a call to malloc:
|
||||
/// 1. Compute the malloc call's argument as the specified type's size,
|
||||
/// possibly multiplied by the array size if the array size is not
|
||||
/// constant 1.
|
||||
/// 2. Call malloc with that argument.
|
||||
/// 3. Bitcast the result of the malloc call to the specified type.
|
||||
static Value *CreateMalloc(Instruction *I,
|
||||
const Type *AllocTy, const Type *IntPtrTy,
|
||||
Value *ArraySize = 0, const Twine &NameStr = "");
|
||||
static Value *CreateMalloc(BasicBlock *InsertAtEnd,
|
||||
const Type *AllocTy, const Type *IntPtrTy,
|
||||
Value *ArraySize = 0, const Twine &NameStr = "");
|
||||
|
||||
~CallInst();
|
||||
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
//===-- MallocHelper.cpp - Functions to identify malloc calls -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This family of functions identifies calls to malloc, bitcasts of malloc
|
||||
// calls, and the types and array sizes associated with them.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Analysis/MallocHelper.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Module.h"
|
||||
using namespace llvm;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// malloc Call Utility Functions.
|
||||
//
|
||||
|
||||
/// isMalloc - Returns true if the the value is either a malloc call or a
|
||||
/// bitcast of the result of a malloc call.
|
||||
bool llvm::isMalloc(Value* I) {
|
||||
return extractMallocCall(I) || extractMallocCallFromBitCast(I);
|
||||
}
|
||||
|
||||
bool llvm::isMalloc(const Value* I) {
|
||||
return extractMallocCall(I) || extractMallocCallFromBitCast(I);
|
||||
}
|
||||
|
||||
static bool isMallocCall(const CallInst *CI) {
|
||||
if (!CI)
|
||||
return false;
|
||||
|
||||
const Module* M = CI->getParent()->getParent()->getParent();
|
||||
Constant *MallocFunc = M->getFunction("malloc");
|
||||
|
||||
if (CI->getOperand(0) != MallocFunc)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// extractMallocCall - Returns the corresponding CallInst if the instruction
|
||||
/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we
|
||||
/// ignore InvokeInst here.
|
||||
const CallInst* llvm::extractMallocCall(const Value* I) {
|
||||
const CallInst *CI = dyn_cast<CallInst>(I);
|
||||
return (isMallocCall(CI)) ? CI : NULL;
|
||||
}
|
||||
|
||||
CallInst* llvm::extractMallocCall(Value* I) {
|
||||
CallInst *CI = dyn_cast<CallInst>(I);
|
||||
return (isMallocCall(CI)) ? CI : NULL;
|
||||
}
|
||||
|
||||
static bool isBitCastOfMallocCall(const BitCastInst* BCI) {
|
||||
if (!BCI)
|
||||
return false;
|
||||
|
||||
return isMallocCall(dyn_cast<CallInst>(BCI->getOperand(0)));
|
||||
}
|
||||
|
||||
/// extractMallocCallFromBitCast - Returns the corresponding CallInst if the
|
||||
/// instruction is a bitcast of the result of a malloc call.
|
||||
CallInst* llvm::extractMallocCallFromBitCast(Value* I) {
|
||||
BitCastInst *BCI = dyn_cast<BitCastInst>(I);
|
||||
return (isBitCastOfMallocCall(BCI)) ? cast<CallInst>(BCI->getOperand(0)) : NULL;
|
||||
}
|
||||
|
||||
const CallInst* llvm::extractMallocCallFromBitCast(const Value* I) {
|
||||
const BitCastInst *BCI = dyn_cast<BitCastInst>(I);
|
||||
return (isBitCastOfMallocCall(BCI)) ? cast<CallInst>(BCI->getOperand(0)) : NULL;
|
||||
}
|
||||
|
||||
static bool isArrayMallocHelper(const CallInst *CI) {
|
||||
if (!CI)
|
||||
return false;
|
||||
|
||||
// Only identify array mallocs for mallocs with 1 bitcast use. The unique
|
||||
// bitcast is needed to determine the type/size of the array allocation.
|
||||
if (!CI->hasOneUse()) return false;
|
||||
|
||||
for (Value::use_const_iterator UI = CI->use_begin(), E = CI->use_end();
|
||||
UI != E; )
|
||||
if (!isa<BitCastInst>(cast<Instruction>(*UI++)))
|
||||
return false;
|
||||
|
||||
// malloc arg
|
||||
Value* MallocArg = CI->getOperand(1);
|
||||
// element size
|
||||
const Type* T = getMallocAllocatedType(CI);
|
||||
if (!T) return false;
|
||||
Constant *ElementSize = ConstantExpr::getSizeOf(T);
|
||||
|
||||
if (isa<ConstantExpr>(MallocArg))
|
||||
return (MallocArg == ElementSize) ? false : true;
|
||||
|
||||
BinaryOperator *BI = dyn_cast<BinaryOperator>(MallocArg);
|
||||
if (!BI)
|
||||
return false;
|
||||
|
||||
if (BI->getOpcode() != Instruction::Mul)
|
||||
return false;
|
||||
|
||||
if (BI->getOperand(1) != ElementSize)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// isArrayMalloc - Returns the corresponding CallInst if the instruction
|
||||
/// matches the malloc call IR generated by CallInst::CreateMalloc(). This
|
||||
/// means that it is a malloc call with one bitcast use AND the malloc call's
|
||||
/// size argument is:
|
||||
/// 1. a constant not equal to the malloc's allocated type
|
||||
/// or
|
||||
/// 2. the result of a multiplication by the malloc's allocated type
|
||||
/// Otherwise it returns NULL.
|
||||
/// The unique bitcast is needed to determine the type/size of the array
|
||||
/// allocation.
|
||||
CallInst* llvm::isArrayMalloc(Value* I) {
|
||||
CallInst *CI = extractMallocCall(I);
|
||||
return (isArrayMallocHelper(CI)) ? CI : NULL;
|
||||
}
|
||||
|
||||
const CallInst* llvm::isArrayMalloc(const Value* I) {
|
||||
const CallInst *CI = extractMallocCall(I);
|
||||
return (isArrayMallocHelper(CI)) ? CI : NULL;
|
||||
}
|
||||
|
||||
/// getMallocType - Returns the PointerType resulting from the malloc call.
|
||||
/// This PointerType is the result type of the call's only bitcast use.
|
||||
/// If there is no unique bitcast use, then return NULL.
|
||||
const PointerType* llvm::getMallocType(const CallInst* CI) {
|
||||
assert(isMalloc(CI) && "GetMallocType and not malloc call");
|
||||
|
||||
const BitCastInst* BCI = NULL;
|
||||
|
||||
// Determine type only if there is only 1 bitcast use of CI.
|
||||
if (CI->hasOneUse())
|
||||
for (Value::use_const_iterator UI = CI->use_begin(), E = CI->use_end();
|
||||
UI != E; )
|
||||
BCI = dyn_cast<BitCastInst>(cast<Instruction>(*UI++));
|
||||
|
||||
return BCI ? reinterpret_cast<const PointerType*>(BCI->getDestTy()) : NULL;
|
||||
}
|
||||
|
||||
/// getMallocAllocatedType - Returns the Type allocated by malloc call. This
|
||||
/// Type is the result type of the call's only bitcast use. If there is no
|
||||
/// unique bitcast use, then return NULL.
|
||||
const Type* llvm::getMallocAllocatedType(const CallInst* CI) {
|
||||
const PointerType* PT = getMallocType(CI);
|
||||
return PT ? PT->getElementType() : NULL;
|
||||
}
|
||||
|
||||
/// isConstantOne - Return true only if val is constant int 1.
|
||||
static bool isConstantOne(Value *val) {
|
||||
return isa<ConstantInt>(val) && cast<ConstantInt>(val)->isOne();
|
||||
}
|
||||
|
||||
/// getMallocArraySize - Returns the array size of a malloc call. The array
|
||||
/// size is computated in 1 of 3 ways:
|
||||
/// 1. If the element type if of size 1, then array size is the argument to
|
||||
/// malloc.
|
||||
/// 2. Else if the malloc's argument is a constant, the array size is that
|
||||
/// argument divided by the element type's size.
|
||||
/// 3. Else the malloc argument must be a multiplication and the array size is
|
||||
/// the first operand of the multiplication.
|
||||
/// This function returns constant 1 if:
|
||||
/// 1. The malloc call's allocated type cannot be determined.
|
||||
/// 2. IR wasn't created by a call to CallInst::CreateMalloc() with a non-NULL
|
||||
/// ArraySize.
|
||||
Value* llvm::getMallocArraySize(CallInst* CI) {
|
||||
// Match CreateMalloc's use of constant 1 array-size for non-array mallocs.
|
||||
if (!isArrayMalloc(CI))
|
||||
return ConstantInt::get(CI->getOperand(1)->getType(), 1);
|
||||
|
||||
Value* MallocArg = CI->getOperand(1);
|
||||
assert(getMallocAllocatedType(CI) && "getMallocArraySize and no type");
|
||||
Constant *ElementSize = ConstantExpr::getSizeOf(getMallocAllocatedType(CI));
|
||||
ElementSize = ConstantExpr::getTruncOrBitCast(cast<Constant>(ElementSize),
|
||||
MallocArg->getType());
|
||||
|
||||
Constant* CO = dyn_cast<Constant>(MallocArg);
|
||||
BinaryOperator* BO = dyn_cast<BinaryOperator>(MallocArg);
|
||||
assert(isConstantOne(ElementSize) || CO || BO &&
|
||||
"getMallocArraySize and malformed malloc IR");
|
||||
|
||||
if (isConstantOne(ElementSize))
|
||||
return MallocArg;
|
||||
|
||||
if (CO)
|
||||
return ConstantExpr::getUDiv(CO, ElementSize);
|
||||
|
||||
assert(BO && "getMallocArraySize not constant but not multiplication either");
|
||||
return BO->getOperand(0);
|
||||
}
|
|
@ -33,13 +33,13 @@ namespace {
|
|||
/// @free calls.
|
||||
///
|
||||
class VISIBILITY_HIDDEN LowerAllocations : public BasicBlockPass {
|
||||
Constant *MallocFunc; // Functions in the module we are processing
|
||||
Constant *FreeFunc; // Initialized by doInitialization
|
||||
Constant *FreeFunc; // Functions in the module we are processing
|
||||
// Initialized by doInitialization
|
||||
bool LowerMallocArgToInteger;
|
||||
public:
|
||||
static char ID; // Pass ID, replacement for typeid
|
||||
explicit LowerAllocations(bool LowerToInt = false)
|
||||
: BasicBlockPass(&ID), MallocFunc(0), FreeFunc(0),
|
||||
: BasicBlockPass(&ID), FreeFunc(0),
|
||||
LowerMallocArgToInteger(LowerToInt) {}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
|
@ -88,10 +88,6 @@ Pass *llvm::createLowerAllocationsPass(bool LowerMallocArgToInteger) {
|
|||
//
|
||||
bool LowerAllocations::doInitialization(Module &M) {
|
||||
const Type *BPTy = PointerType::getUnqual(Type::getInt8Ty(M.getContext()));
|
||||
// Prototype malloc as "char* malloc(...)", because we don't know in
|
||||
// doInitialization whether size_t is int or long.
|
||||
FunctionType *FT = FunctionType::get(BPTy, true);
|
||||
MallocFunc = M.getOrInsertFunction("malloc", FT);
|
||||
FreeFunc = M.getOrInsertFunction("free" , Type::getVoidTy(M.getContext()),
|
||||
BPTy, (Type *)0);
|
||||
return true;
|
||||
|
@ -102,7 +98,7 @@ bool LowerAllocations::doInitialization(Module &M) {
|
|||
//
|
||||
bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) {
|
||||
bool Changed = false;
|
||||
assert(MallocFunc && FreeFunc && "Pass not initialized!");
|
||||
assert(FreeFunc && "Pass not initialized!");
|
||||
|
||||
BasicBlock::InstListType &BBIL = BB.getInstList();
|
||||
|
||||
|
@ -112,50 +108,8 @@ bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) {
|
|||
// Loop over all of the instructions, looking for malloc or free instructions
|
||||
for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) {
|
||||
if (MallocInst *MI = dyn_cast<MallocInst>(I)) {
|
||||
const Type *AllocTy = MI->getType()->getElementType();
|
||||
|
||||
// malloc(type) becomes i8 *malloc(size)
|
||||
Value *MallocArg;
|
||||
if (LowerMallocArgToInteger)
|
||||
MallocArg = ConstantInt::get(Type::getInt64Ty(BB.getContext()),
|
||||
TD.getTypeAllocSize(AllocTy));
|
||||
else
|
||||
MallocArg = ConstantExpr::getSizeOf(AllocTy);
|
||||
MallocArg =
|
||||
ConstantExpr::getTruncOrBitCast(cast<Constant>(MallocArg),
|
||||
IntPtrTy);
|
||||
|
||||
if (MI->isArrayAllocation()) {
|
||||
if (isa<ConstantInt>(MallocArg) &&
|
||||
cast<ConstantInt>(MallocArg)->isOne()) {
|
||||
MallocArg = MI->getOperand(0); // Operand * 1 = Operand
|
||||
} else if (Constant *CO = dyn_cast<Constant>(MI->getOperand(0))) {
|
||||
CO =
|
||||
ConstantExpr::getIntegerCast(CO, IntPtrTy, false /*ZExt*/);
|
||||
MallocArg = ConstantExpr::getMul(CO,
|
||||
cast<Constant>(MallocArg));
|
||||
} else {
|
||||
Value *Scale = MI->getOperand(0);
|
||||
if (Scale->getType() != IntPtrTy)
|
||||
Scale = CastInst::CreateIntegerCast(Scale, IntPtrTy, false /*ZExt*/,
|
||||
"", I);
|
||||
|
||||
// Multiply it by the array size if necessary...
|
||||
MallocArg = BinaryOperator::Create(Instruction::Mul, Scale,
|
||||
MallocArg, "", I);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the call to Malloc.
|
||||
CallInst *MCall = CallInst::Create(MallocFunc, MallocArg, "", I);
|
||||
MCall->setTailCall();
|
||||
|
||||
// Create a cast instruction to convert to the right type...
|
||||
Value *MCast;
|
||||
if (MCall->getType() != Type::getVoidTy(BB.getContext()))
|
||||
MCast = new BitCastInst(MCall, MI->getType(), "", I);
|
||||
else
|
||||
MCast = Constant::getNullValue(MI->getType());
|
||||
Value *MCast = CallInst::CreateMalloc(I, MI->getType(), IntPtrTy,
|
||||
MI->getOperand(0));
|
||||
|
||||
// Replace all uses of the old malloc inst with the cast inst
|
||||
MI->replaceAllUsesWith(MCast);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Operator.h"
|
||||
#include "llvm/Analysis/Dominators.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
@ -440,6 +441,116 @@ bool CallInst::paramHasAttr(unsigned i, Attributes attr) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
/// IsConstantOne - Return true only if val is constant int 1
|
||||
static bool IsConstantOne(Value *val) {
|
||||
assert(val && "IsConstantOne does not work with NULL val");
|
||||
return isa<ConstantInt>(val) && cast<ConstantInt>(val)->isOne();
|
||||
}
|
||||
|
||||
static Value *checkArraySize(Value *Amt, const Type *IntPtrTy) {
|
||||
if (!Amt)
|
||||
Amt = ConstantInt::get(IntPtrTy, 1);
|
||||
else {
|
||||
assert(!isa<BasicBlock>(Amt) &&
|
||||
"Passed basic block into malloc size parameter! Use other ctor");
|
||||
assert(Amt->getType() == IntPtrTy &&
|
||||
"Malloc array size is not an intptr!");
|
||||
}
|
||||
return Amt;
|
||||
}
|
||||
|
||||
static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd,
|
||||
const Type *AllocTy, const Type *IntPtrTy,
|
||||
Value *ArraySize, const Twine &NameStr) {
|
||||
assert((!InsertBefore && InsertAtEnd || InsertBefore && !InsertAtEnd) &&
|
||||
"createMalloc needs only InsertBefore or InsertAtEnd");
|
||||
const PointerType *AllocPtrType = dyn_cast<PointerType>(AllocTy);
|
||||
assert(AllocPtrType && "CreateMalloc passed a non-pointer allocation type");
|
||||
|
||||
ArraySize = checkArraySize(ArraySize, IntPtrTy);
|
||||
|
||||
// malloc(type) becomes i8 *malloc(size)
|
||||
Value *AllocSize = ConstantExpr::getSizeOf(AllocPtrType->getElementType());
|
||||
AllocSize = ConstantExpr::getTruncOrBitCast(cast<Constant>(AllocSize),
|
||||
IntPtrTy);
|
||||
if (!IsConstantOne(ArraySize))
|
||||
if (IsConstantOne(AllocSize)) {
|
||||
AllocSize = ArraySize; // Operand * 1 = Operand
|
||||
} else if (Constant *CO = dyn_cast<Constant>(ArraySize)) {
|
||||
Constant *Scale = ConstantExpr::getIntegerCast(CO, IntPtrTy,
|
||||
false /*ZExt*/);
|
||||
// Malloc arg is constant product of type size and array size
|
||||
AllocSize = ConstantExpr::getMul(Scale, cast<Constant>(AllocSize));
|
||||
} else {
|
||||
Value *Scale = ArraySize;
|
||||
if (Scale->getType() != IntPtrTy)
|
||||
if (InsertBefore)
|
||||
Scale = CastInst::CreateIntegerCast(Scale, IntPtrTy, false /*ZExt*/,
|
||||
"", InsertBefore);
|
||||
else
|
||||
Scale = CastInst::CreateIntegerCast(Scale, IntPtrTy, false /*ZExt*/,
|
||||
"", InsertAtEnd);
|
||||
// Multiply type size by the array size...
|
||||
if (InsertBefore)
|
||||
AllocSize = BinaryOperator::CreateMul(Scale, AllocSize,
|
||||
"", InsertBefore);
|
||||
else
|
||||
AllocSize = BinaryOperator::CreateMul(Scale, AllocSize,
|
||||
"", InsertAtEnd);
|
||||
}
|
||||
|
||||
// Create the call to Malloc.
|
||||
BasicBlock* BB = InsertBefore ? InsertBefore->getParent() : InsertAtEnd;
|
||||
Module* M = BB->getParent()->getParent();
|
||||
const Type *BPTy = PointerType::getUnqual(Type::getInt8Ty(BB->getContext()));
|
||||
// prototype malloc as "void *malloc(size_t)"
|
||||
Constant *MallocFunc = M->getOrInsertFunction("malloc", BPTy,
|
||||
IntPtrTy, NULL);
|
||||
CallInst *MCall = NULL;
|
||||
if (InsertBefore)
|
||||
MCall = CallInst::Create(MallocFunc, AllocSize, NameStr, InsertBefore);
|
||||
else
|
||||
MCall = CallInst::Create(MallocFunc, AllocSize, NameStr, InsertAtEnd);
|
||||
MCall->setTailCall();
|
||||
|
||||
// Create a cast instruction to convert to the right type...
|
||||
const Type* VoidT = Type::getVoidTy(BB->getContext());
|
||||
assert(MCall->getType() != VoidT && "Malloc has void return type");
|
||||
Value *MCast;
|
||||
if (InsertBefore)
|
||||
MCast = new BitCastInst(MCall, AllocPtrType, NameStr, InsertBefore);
|
||||
else
|
||||
MCast = new BitCastInst(MCall, AllocPtrType, NameStr);
|
||||
return MCast;
|
||||
}
|
||||
|
||||
/// CreateMalloc - Generate the IR for a call to malloc:
|
||||
/// 1. Compute the malloc call's argument as the specified type's size,
|
||||
/// possibly multiplied by the array size if the array size is not
|
||||
/// constant 1.
|
||||
/// 2. Call malloc with that argument.
|
||||
/// 3. Bitcast the result of the malloc call to the specified type.
|
||||
Value *CallInst::CreateMalloc(Instruction *InsertBefore,
|
||||
const Type *AllocTy, const Type *IntPtrTy,
|
||||
Value *ArraySize, const Twine &NameStr) {
|
||||
return createMalloc(InsertBefore, NULL, AllocTy,
|
||||
IntPtrTy, ArraySize, NameStr);
|
||||
}
|
||||
|
||||
/// CreateMalloc - Generate the IR for a call to malloc:
|
||||
/// 1. Compute the malloc call's argument as the specified type's size,
|
||||
/// possibly multiplied by the array size if the array size is not
|
||||
/// constant 1.
|
||||
/// 2. Call malloc with that argument.
|
||||
/// 3. Bitcast the result of the malloc call to the specified type.
|
||||
/// Note: This function does not add the bitcast to the basic block, that is the
|
||||
/// responsibility of the caller.
|
||||
Value *CallInst::CreateMalloc(BasicBlock *InsertAtEnd,
|
||||
const Type *AllocTy, const Type *IntPtrTy,
|
||||
Value *ArraySize, const Twine &NameStr) {
|
||||
return createMalloc(NULL, InsertAtEnd, AllocTy,
|
||||
IntPtrTy, ArraySize, NameStr);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// InvokeInst Implementation
|
||||
|
|
Loading…
Reference in New Issue