diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 4 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 46 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.h | 7 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 11 | ||||
-rw-r--r-- | lib/VMCore/Core.cpp | 8 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 20 |
6 files changed, 74 insertions, 22 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 315048c..05b6f7f 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 0ecf847..d90588d 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 '" + @@ -2776,8 +2797,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); @@ -3286,7 +3307,7 @@ bool LLParser::ParseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) { } /// ParsePHI -/// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Valueß ']')* +/// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Value√ü ']')* bool LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) { PATypeHolder Ty(Type::getVoidTy(Context)); Value *Op0, *Op1; @@ -3431,7 +3452,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; @@ -3451,10 +3472,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 3420fcf..43e9bd8 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 f3ab806..be0ec4b 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2046,14 +2046,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/VMCore/Core.cpp b/lib/VMCore/Core.cpp index 1dbf5c4..248127d 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -1636,12 +1636,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 b7acce7..611bf16 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,10 +500,11 @@ static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd, 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 *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; @@ -531,7 +533,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 +547,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); } //===----------------------------------------------------------------------===// |