diff options
-rw-r--r-- | examples/BrainF/BrainF.cpp | 7 | ||||
-rw-r--r-- | include/llvm/Instructions.h | 7 | ||||
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 4 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 44 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.h | 7 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 11 | ||||
-rw-r--r-- | lib/Transforms/IPO/IndMemRemoval.cpp | 37 | ||||
-rw-r--r-- | lib/Transforms/IPO/RaiseAllocations.cpp | 118 | ||||
-rw-r--r-- | lib/Transforms/Scalar/Reassociate.cpp | 3 | ||||
-rw-r--r-- | lib/VMCore/Core.cpp | 8 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 40 | ||||
-rw-r--r-- | test/Transforms/GlobalOpt/malloc-promote-2.ll | 4 | ||||
-rw-r--r-- | test/Transforms/GlobalOpt/malloc-promote-3.ll | 4 | ||||
-rw-r--r-- | test/Transforms/IndMemRem/2009-01-24-Noalias.ll | 2 | ||||
-rw-r--r-- | test/Transforms/InstCombine/cast-malloc.ll | 2 | ||||
-rw-r--r-- | test/Transforms/InstCombine/cast.ll | 10 | ||||
-rw-r--r-- | test/Transforms/InstCombine/getelementptr.ll | 2 | ||||
-rw-r--r-- | test/Transforms/InstCombine/malloc-free-delete.ll | 2 | ||||
-rw-r--r-- | test/Transforms/InstCombine/malloc2.ll | 1 | ||||
-rw-r--r-- | test/Transforms/InstCombine/malloc3.ll | 2 |
20 files changed, 155 insertions, 160 deletions
diff --git a/examples/BrainF/BrainF.cpp b/examples/BrainF/BrainF.cpp index 5cf2b883bc..c64b87f2f3 100644 --- a/examples/BrainF/BrainF.cpp +++ b/examples/BrainF/BrainF.cpp @@ -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) { diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index b28fcbb951..d9e59ed3a2 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -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) { diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 0e9f1a05fe..6d660111ac 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 1e1ddf07d2..001d56d538 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 97bf2f309f..5dd6a2e700 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 4eb12c69eb..fe4556f0a2 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 e7884ec634..9bd5a92772 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 4c1f26d50d..deb4405754 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 e6ffac251b..9160654c3d 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 bff308727f..5b8295f60d 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 f3d15cb2b8..4ff253a7db 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); } //===----------------------------------------------------------------------===// diff --git a/test/Transforms/GlobalOpt/malloc-promote-2.ll b/test/Transforms/GlobalOpt/malloc-promote-2.ll index 0d03835cf5..d3d225260a 100644 --- a/test/Transforms/GlobalOpt/malloc-promote-2.ll +++ b/test/Transforms/GlobalOpt/malloc-promote-2.ll @@ -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] diff --git a/test/Transforms/GlobalOpt/malloc-promote-3.ll b/test/Transforms/GlobalOpt/malloc-promote-3.ll index d4ee4e861c..a920b61150 100644 --- a/test/Transforms/GlobalOpt/malloc-promote-3.ll +++ b/test/Transforms/GlobalOpt/malloc-promote-3.ll @@ -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] diff --git a/test/Transforms/IndMemRem/2009-01-24-Noalias.ll b/test/Transforms/IndMemRem/2009-01-24-Noalias.ll index b6d98031b7..043291e756 100644 --- a/test/Transforms/IndMemRem/2009-01-24-Noalias.ll +++ b/test/Transforms/IndMemRem/2009-01-24-Noalias.ll @@ -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) diff --git a/test/Transforms/InstCombine/cast-malloc.ll b/test/Transforms/InstCombine/cast-malloc.ll index 3754032cc2..43a1489277 100644 --- a/test/Transforms/InstCombine/cast-malloc.ll +++ b/test/Transforms/InstCombine/cast-malloc.ll @@ -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 diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll index 9835d657c9..c5266f3b86 100644 --- a/test/Transforms/InstCombine/cast.ll +++ b/test/Transforms/InstCombine/cast.ll @@ -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 } diff --git a/test/Transforms/InstCombine/getelementptr.ll b/test/Transforms/InstCombine/getelementptr.ll index ffaa6afa85..285e0ba602 100644 --- a/test/Transforms/InstCombine/getelementptr.ll +++ b/test/Transforms/InstCombine/getelementptr.ll @@ -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) { diff --git a/test/Transforms/InstCombine/malloc-free-delete.ll b/test/Transforms/InstCombine/malloc-free-delete.ll index 2ed5ec6996..fd91e447bd 100644 --- a/test/Transforms/InstCombine/malloc-free-delete.ll +++ b/test/Transforms/InstCombine/malloc-free-delete.ll @@ -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] diff --git a/test/Transforms/InstCombine/malloc2.ll b/test/Transforms/InstCombine/malloc2.ll index 102422ee5f..cc1506b6b1 100644 --- a/test/Transforms/InstCombine/malloc2.ll +++ b/test/Transforms/InstCombine/malloc2.ll @@ -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) { diff --git a/test/Transforms/InstCombine/malloc3.ll b/test/Transforms/InstCombine/malloc3.ll index cd407ffb02..f1c0cae15a 100644 --- a/test/Transforms/InstCombine/malloc3.ll +++ b/test/Transforms/InstCombine/malloc3.ll @@ -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" |