mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
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. llvm-svn: 84292
This commit is contained in:
parent
00adf339dd
commit
4d7283f82c
@ -25,6 +25,7 @@
|
||||
|
||||
#include "BrainF.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Intrinsics.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include <iostream>
|
||||
@ -78,7 +79,11 @@ void BrainF::header(LLVMContext& C) {
|
||||
|
||||
//%arr = malloc i8, i32 %d
|
||||
ConstantInt *val_mem = ConstantInt::get(C, APInt(32, memtotal));
|
||||
ptr_arr = builder->CreateMalloc(IntegerType::getInt8Ty(C), val_mem, "arr");
|
||||
BasicBlock* BB = builder->GetInsertBlock();
|
||||
const Type* IntPtrTy = IntegerType::getInt32Ty(C);
|
||||
ptr_arr = CallInst::CreateMalloc(BB, IntPtrTy, IntegerType::getInt8Ty(C),
|
||||
val_mem, NULL, "arr");
|
||||
BB->getInstList().push_back(cast<Instruction>(ptr_arr));
|
||||
|
||||
//call void @llvm.memset.i32(i8 *%arr, i8 0, i32 %d, i32 1)
|
||||
{
|
||||
|
@ -1047,7 +1047,7 @@ public:
|
||||
const Twine &Name = "");
|
||||
static Value *CreateMalloc(BasicBlock *InsertAtEnd, const Type *IntPtrTy,
|
||||
const Type *AllocTy, Value *ArraySize = 0,
|
||||
const Twine &Name = "");
|
||||
Function* MallocF = 0, const Twine &Name = "");
|
||||
|
||||
~CallInst();
|
||||
|
||||
@ -1152,6 +1152,11 @@ public:
|
||||
const Value *getCalledValue() const { return Op<0>(); }
|
||||
Value *getCalledValue() { return Op<0>(); }
|
||||
|
||||
/// setCalledFunction - Set the function called
|
||||
void setCalledFunction(Value* Fn) {
|
||||
Op<0>() = Fn;
|
||||
}
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const CallInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)) ||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1,4 +1,6 @@
|
||||
; RUN: opt < %s -globalopt -S | not grep malloc
|
||||
; RUN: opt < %s -globalopt -globaldce -S | not grep malloc
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||
target triple = "i686-apple-darwin8"
|
||||
|
||||
@G = internal global i32* null ; <i32**> [#uses=3]
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
; RUN: opt < %s -globalopt -S | not grep malloc
|
||||
; RUN: opt < %s -globalopt -globaldce -S | not grep malloc
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||
target triple = "i686-apple-darwin8"
|
||||
|
||||
@G = internal global i32* null ; <i32**> [#uses=4]
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
; RUN: opt < %s -indmemrem -S | grep bounce | grep noalias
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||
target triple = "i686-apple-darwin8"
|
||||
|
||||
declare i8* @malloc(i32)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
; test that casted mallocs get converted to malloc of the right type
|
||||
; RUN: opt < %s -instcombine -S | \
|
||||
; RUN: not grep bitcast
|
||||
; RUN: grep bitcast | count 1
|
||||
|
||||
; The target datalayout is important for this test case. We have to tell
|
||||
; instcombine that the ABI alignment for a long is 4-bytes, not 8, otherwise
|
||||
|
@ -102,8 +102,8 @@ define i32* @test12() {
|
||||
%p = malloc [4 x i8] ; <[4 x i8]*> [#uses=1]
|
||||
%c = bitcast [4 x i8]* %p to i32* ; <i32*> [#uses=1]
|
||||
ret i32* %c
|
||||
; CHECK: %p = malloc i32
|
||||
; CHECK: ret i32* %p
|
||||
; CHECK: %malloccall = tail call i8* @malloc(i32 ptrtoint ([4 x i8]* getelementptr ([4 x i8]* null, i32 1) to i32))
|
||||
; CHECK: ret i32* %c
|
||||
}
|
||||
|
||||
define i8* @test13(i64 %A) {
|
||||
@ -274,9 +274,9 @@ define void @test32(double** %tmp) {
|
||||
%tmp8.upgrd.1 = bitcast [16 x i8]* %tmp8 to double* ; <double*> [#uses=1]
|
||||
store double* %tmp8.upgrd.1, double** %tmp
|
||||
ret void
|
||||
; CHECK: %tmp81 = malloc [2 x double]
|
||||
; CHECK: %tmp81.sub = getelementptr inbounds [2 x double]* %tmp81, i64 0, i64 0
|
||||
; CHECK: store double* %tmp81.sub, double** %tmp
|
||||
; CHECK: %malloccall = tail call i8* @malloc(i32 ptrtoint ([16 x i8]* getelementptr ([16 x i8]* null, i32 1) to i32))
|
||||
; CHECK: %tmp8.upgrd.1 = bitcast i8* %malloccall to double*
|
||||
; CHECK: store double* %tmp8.upgrd.1, double** %tmp
|
||||
; CHECK: ret void
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ define i32* @test6() {
|
||||
%B = getelementptr i32* %A, i64 2
|
||||
ret i32* %B
|
||||
; CHECK: @test6
|
||||
; CHECK: getelementptr [4 x i32]* %M, i64 0, i64 2
|
||||
; CHECK: getelementptr i8* %malloccall, i64 8
|
||||
}
|
||||
|
||||
define i32* @test7(i32* %I, i64 %C, i64 %D) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
; RUN: opt < %s -instcombine -S | grep {ret i32 0}
|
||||
; RUN: opt < %s -instcombine -S | not grep malloc
|
||||
; RUN: opt < %s -instcombine -globaldce -S | not grep malloc
|
||||
; PR1201
|
||||
define i32 @main(i32 %argc, i8** %argv) {
|
||||
%c_19 = alloca i8* ; <i8**> [#uses=2]
|
||||
|
@ -1,5 +1,4 @@
|
||||
; RUN: opt < %s -instcombine -S | grep {ret i32 0}
|
||||
; RUN: opt < %s -instcombine -S | not grep malloc
|
||||
; PR1313
|
||||
|
||||
define i32 @test1(i32 %argc, i8* %argv, i8* %envp) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: opt < %s -instcombine -S | grep {malloc.*struct.foo} | count 2
|
||||
; RUN: opt < %s -instcombine -S | not grep load
|
||||
; PR1728
|
||||
|
||||
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
||||
|
Loading…
x
Reference in New Issue
Block a user