diff options
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/Instruction.cpp | 24 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 83 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 10 |
3 files changed, 71 insertions, 46 deletions
diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index 815dd7e..efa80d1 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -16,6 +16,7 @@ #include "llvm/Function.h" #include "llvm/Constants.h" #include "llvm/GlobalVariable.h" +#include "llvm/Module.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/LeakDetector.h" using namespace llvm; @@ -375,6 +376,27 @@ bool Instruction::isCommutative(unsigned op) { } } +// Code here matches isMalloc from MallocHelper, which is not in VMCore. +static bool isMalloc(const Value* I) { + const CallInst *CI = dyn_cast<CallInst>(I); + if (!CI) { + const BitCastInst *BCI = dyn_cast<BitCastInst>(I); + if (!BCI) return false; + + CI = dyn_cast<CallInst>(BCI->getOperand(0)); + } + + 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; +} + bool Instruction::isSafeToSpeculativelyExecute() const { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) if (Constant *C = dyn_cast<Constant>(getOperand(i))) @@ -400,7 +422,7 @@ bool Instruction::isSafeToSpeculativelyExecute() const { case Load: { if (cast<LoadInst>(this)->isVolatile()) return false; - if (isa<AllocationInst>(getOperand(0))) + if (isa<AllocationInst>(getOperand(0)) || isMalloc(getOperand(0))) return true; if (GlobalVariable *GV = dyn_cast<GlobalVariable>(getOperand(0))) return !GV->hasExternalWeakLinkage(); diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index bf0d042..d479d9a 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -460,19 +460,20 @@ static Value *checkArraySize(Value *Amt, const Type *IntPtrTy) { } static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd, - const Type *AllocTy, const Type *IntPtrTy, + const Type *IntPtrTy, const Type *AllocTy, 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"); - + "createMalloc needs either InsertBefore or InsertAtEnd"); + + // malloc(type) becomes: + // bitcast (i8* malloc(typeSize)) to type* + // malloc(type, arraySize) becomes: + // bitcast (i8 *malloc(typeSize*arraySize)) to type* + Value *AllocSize = ConstantExpr::getSizeOf(AllocTy); + AllocSize = ConstantExpr::getTruncOrBitCast(cast<Constant>(AllocSize), + IntPtrTy); 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 @@ -482,47 +483,41 @@ static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd, // 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); + AllocSize = BinaryOperator::CreateMul(ArraySize, AllocSize, + "mallocsize", InsertBefore); else - AllocSize = BinaryOperator::CreateMul(Scale, AllocSize, - "", InsertAtEnd); + AllocSize = BinaryOperator::CreateMul(ArraySize, AllocSize, + "mallocsize", InsertAtEnd); } } + assert(AllocSize->getType() == IntPtrTy && "malloc arg is wrong size"); // 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); + Constant *MallocF = M->getOrInsertFunction("malloc", BPTy, IntPtrTy, NULL); + if (!cast<Function>(MallocF)->doesNotAlias(0)) + cast<Function>(MallocF)->setDoesNotAlias(0); + const PointerType *AllocPtrType = PointerType::getUnqual(AllocTy); CallInst *MCall = NULL; - if (InsertBefore) - MCall = CallInst::Create(MallocFunc, AllocSize, NameStr, InsertBefore); - else - MCall = CallInst::Create(MallocFunc, AllocSize, NameStr, InsertAtEnd); + Value *MCast = 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); + } 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->setTailCall(); - - // Create a cast instruction to convert to the right type... assert(MCall->getType() != Type::getVoidTy(BB->getContext()) && "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; } @@ -532,11 +527,10 @@ static Value *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd, /// 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); +Value *CallInst::CreateMalloc(Instruction *InsertBefore, const Type *IntPtrTy, + const Type *AllocTy, Value *ArraySize, + const Twine &Name) { + return createMalloc(InsertBefore, NULL, IntPtrTy, AllocTy, ArraySize, Name); } /// CreateMalloc - Generate the IR for a call to malloc: @@ -547,11 +541,10 @@ Value *CallInst::CreateMalloc(Instruction *InsertBefore, /// 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); +Value *CallInst::CreateMalloc(BasicBlock *InsertAtEnd, const Type *IntPtrTy, + const Type *AllocTy, Value *ArraySize, + const Twine &Name) { + return createMalloc(NULL, InsertAtEnd, IntPtrTy, AllocTy, ArraySize, Name); } //===----------------------------------------------------------------------===// diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 140e6bd..f1f6e2e 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -1143,6 +1143,16 @@ void Verifier::visitCallInst(CallInst &CI) { if (Function *F = CI.getCalledFunction()) if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) visitIntrinsicFunctionCall(ID, CI); + + // Code here matches isMalloc from MallocHelper, which is not in VMCore. + const Module* M = CI.getParent()->getParent()->getParent(); + Constant *MallocFunc = M->getFunction("malloc"); + + if (CI.getOperand(0) == MallocFunc) { + const PointerType *PTy = + PointerType::getUnqual(Type::getInt8Ty(CI.getParent()->getContext())); + Assert1(CI.getType() == PTy, "Malloc call must return i8*", &CI); + } } void Verifier::visitInvokeInst(InvokeInst &II) { |