diff options
-rw-r--r-- | lib/CodeGen/IntrinsicLowering.cpp | 113 | ||||
-rw-r--r-- | lib/Transforms/IPO/SimplifyLibCalls.cpp | 130 | ||||
-rw-r--r-- | lib/Transforms/Utils/LowerAllocations.cpp | 64 | ||||
-rw-r--r-- | lib/Transforms/Utils/LowerInvoke.cpp | 68 |
4 files changed, 119 insertions, 256 deletions
diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp index 41d48d947e..ba89052572 100644 --- a/lib/CodeGen/IntrinsicLowering.cpp +++ b/lib/CodeGen/IntrinsicLowering.cpp @@ -21,15 +21,14 @@ using namespace llvm; template <class ArgIt> -static Function *EnsureFunctionExists(Module &M, const char *Name, - ArgIt ArgBegin, ArgIt ArgEnd, - const Type *RetTy) { - if (Function *F = M.getNamedFunction(Name)) return F; - // It doesn't already exist in the program, insert a new definition now. +static void EnsureFunctionExists(Module &M, const char *Name, + ArgIt ArgBegin, ArgIt ArgEnd, + const Type *RetTy) { + // Insert a correctly-typed definition now. std::vector<const Type *> ParamTys; for (ArgIt I = ArgBegin; I != ArgEnd; ++I) ParamTys.push_back(I->getType()); - return M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false)); + M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false)); } /// ReplaceCallWith - This function is used when we want to lower an intrinsic @@ -38,53 +37,24 @@ static Function *EnsureFunctionExists(Module &M, const char *Name, /// prototype doesn't match the arguments we expect to pass in. template <class ArgIt> static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, - ArgIt ArgBegin, ArgIt ArgEnd, bool isSigned, - const Type *RetTy, Function *&FCache) { + ArgIt ArgBegin, ArgIt ArgEnd, + const Type *RetTy, Constant *&FCache) { if (!FCache) { // If we haven't already looked up this function, check to see if the // program already contains a function with this name. Module *M = CI->getParent()->getParent()->getParent(); - FCache = M->getNamedFunction(NewFn); - if (!FCache) { - // It doesn't already exist in the program, insert a new definition now. - std::vector<const Type *> ParamTys; - for (ArgIt I = ArgBegin; I != ArgEnd; ++I) - ParamTys.push_back((*I)->getType()); - FCache = M->getOrInsertFunction(NewFn, - FunctionType::get(RetTy, ParamTys, false)); - } - } - - const FunctionType *FT = FCache->getFunctionType(); - std::vector<Value*> Operands; - unsigned ArgNo = 0; - for (ArgIt I = ArgBegin; I != ArgEnd && ArgNo != FT->getNumParams(); - ++I, ++ArgNo) { - Value *Arg = *I; - if (Arg->getType() != FT->getParamType(ArgNo)) { - Instruction::CastOps opcode = CastInst::getCastOpcode(Arg, isSigned, - FT->getParamType(ArgNo), isSigned); - Arg = CastInst::create(opcode, Arg, FT->getParamType(ArgNo), - Arg->getName(), CI); - } - Operands.push_back(Arg); + // Get or insert the definition now. + std::vector<const Type *> ParamTys; + for (ArgIt I = ArgBegin; I != ArgEnd; ++I) + ParamTys.push_back((*I)->getType()); + FCache = M->getOrInsertFunction(NewFn, + FunctionType::get(RetTy, ParamTys, false)); } - // Pass nulls into any additional arguments... - for (; ArgNo != FT->getNumParams(); ++ArgNo) - Operands.push_back(Constant::getNullValue(FT->getParamType(ArgNo))); - std::string Name = CI->getName(); CI->setName(""); - if (FT->getReturnType() == Type::VoidTy) Name.clear(); - CallInst *NewCI = new CallInst(FCache, Operands, Name, CI); - if (!CI->use_empty()) { - Value *V = NewCI; - if (CI->getType() != NewCI->getType()) { - Instruction::CastOps opcode = CastInst::getCastOpcode(NewCI, isSigned, - CI->getType(), isSigned); - V = CastInst::create(opcode, NewCI, CI->getType(), Name, CI); - } - CI->replaceAllUsesWith(V); - } + std::vector<Value*> Operands(ArgBegin, ArgEnd); + CallInst *NewCI = new CallInst(FCache, Operands, CI->getName(), CI); + if (!CI->use_empty()) + CI->replaceAllUsesWith(NewCI); return NewCI; } @@ -286,10 +256,9 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { // by the lowerinvoke pass. In both cases, the right thing to do is to // convert the call to an explicit setjmp or longjmp call. case Intrinsic::setjmp: { - static Function *SetjmpFCache = 0; - static const unsigned castOpcodes[] = { Instruction::BitCast }; + static Constant *SetjmpFCache = 0; Value *V = ReplaceCallWith("setjmp", CI, CI->op_begin()+1, CI->op_end(), - castOpcodes, Type::Int32Ty, SetjmpFCache); + Type::Int32Ty, SetjmpFCache); if (CI->getType() != Type::VoidTy) CI->replaceAllUsesWith(V); break; @@ -300,21 +269,17 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { break; case Intrinsic::longjmp: { - static Function *LongjmpFCache = 0; - static const unsigned castOpcodes[] = - { Instruction::BitCast, 0 }; + static Constant *LongjmpFCache = 0; ReplaceCallWith("longjmp", CI, CI->op_begin()+1, CI->op_end(), - castOpcodes, Type::VoidTy, LongjmpFCache); + Type::VoidTy, LongjmpFCache); break; } case Intrinsic::siglongjmp: { // Insert the call to abort - static Function *AbortFCache = 0; - static const unsigned castOpcodes[] = - { Instruction::BitCast, 0 }; + static Constant *AbortFCache = 0; ReplaceCallWith("abort", CI, CI->op_end(), CI->op_end(), - castOpcodes, Type::VoidTy, AbortFCache); + Type::VoidTy, AbortFCache); break; } case Intrinsic::ctpop_i8: @@ -393,38 +358,38 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { break; // Simply strip out debugging intrinsics case Intrinsic::memcpy_i32: { - static Function *MemcpyFCache = 0; + static Constant *MemcpyFCache = 0; ReplaceCallWith("memcpy", CI, CI->op_begin()+1, CI->op_end()-1, - false, (*(CI->op_begin()+1))->getType(), MemcpyFCache); + (*(CI->op_begin()+1))->getType(), MemcpyFCache); break; } case Intrinsic::memcpy_i64: { - static Function *MemcpyFCache = 0; + static Constant *MemcpyFCache = 0; ReplaceCallWith("memcpy", CI, CI->op_begin()+1, CI->op_end()-1, - false, (*(CI->op_begin()+1))->getType(), MemcpyFCache); + (*(CI->op_begin()+1))->getType(), MemcpyFCache); break; } case Intrinsic::memmove_i32: { - static Function *MemmoveFCache = 0; + static Constant *MemmoveFCache = 0; ReplaceCallWith("memmove", CI, CI->op_begin()+1, CI->op_end()-1, - false, (*(CI->op_begin()+1))->getType(), MemmoveFCache); + (*(CI->op_begin()+1))->getType(), MemmoveFCache); break; } case Intrinsic::memmove_i64: { - static Function *MemmoveFCache = 0; + static Constant *MemmoveFCache = 0; ReplaceCallWith("memmove", CI, CI->op_begin()+1, CI->op_end()-1, - false, (*(CI->op_begin()+1))->getType(), MemmoveFCache); + (*(CI->op_begin()+1))->getType(), MemmoveFCache); break; } case Intrinsic::memset_i32: { - static Function *MemsetFCache = 0; + static Constant *MemsetFCache = 0; ReplaceCallWith("memset", CI, CI->op_begin()+1, CI->op_end()-1, - true, (*(CI->op_begin()+1))->getType(), MemsetFCache); + (*(CI->op_begin()+1))->getType(), MemsetFCache); } case Intrinsic::memset_i64: { - static Function *MemsetFCache = 0; + static Constant *MemsetFCache = 0; ReplaceCallWith("memset", CI, CI->op_begin()+1, CI->op_end()-1, - true, (*(CI->op_begin()+1))->getType(), MemsetFCache); + (*(CI->op_begin()+1))->getType(), MemsetFCache); break; } case Intrinsic::isunordered_f32: @@ -440,15 +405,15 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { break; } case Intrinsic::sqrt_f32: { - static Function *sqrtfFCache = 0; + static Constant *sqrtfFCache = 0; ReplaceCallWith("sqrtf", CI, CI->op_begin()+1, CI->op_end(), - false, Type::FloatTy, sqrtfFCache); + Type::FloatTy, sqrtfFCache); break; } case Intrinsic::sqrt_f64: { - static Function *sqrtFCache = 0; + static Constant *sqrtFCache = 0; ReplaceCallWith("sqrt", CI, CI->op_begin()+1, CI->op_end(), - false, Type::DoubleTy, sqrtFCache); + Type::DoubleTy, sqrtFCache); break; } } diff --git a/lib/Transforms/IPO/SimplifyLibCalls.cpp b/lib/Transforms/IPO/SimplifyLibCalls.cpp index 4d37fbf79a..2c5821ae37 100644 --- a/lib/Transforms/IPO/SimplifyLibCalls.cpp +++ b/lib/Transforms/IPO/SimplifyLibCalls.cpp @@ -222,7 +222,7 @@ public: const Type* getIntPtrType() const { return TD->getIntPtrType(); } /// @brief Return a Function* for the putchar libcall - Function* get_putchar() { + Constant *get_putchar() { if (!putchar_func) putchar_func = M->getOrInsertFunction("putchar", Type::Int32Ty, Type::Int32Ty, NULL); @@ -230,7 +230,7 @@ public: } /// @brief Return a Function* for the puts libcall - Function* get_puts() { + Constant *get_puts() { if (!puts_func) puts_func = M->getOrInsertFunction("puts", Type::Int32Ty, PointerType::get(Type::Int8Ty), @@ -239,7 +239,7 @@ public: } /// @brief Return a Function* for the fputc libcall - Function* get_fputc(const Type* FILEptr_type) { + Constant *get_fputc(const Type* FILEptr_type) { if (!fputc_func) fputc_func = M->getOrInsertFunction("fputc", Type::Int32Ty, Type::Int32Ty, FILEptr_type, NULL); @@ -247,7 +247,7 @@ public: } /// @brief Return a Function* for the fputs libcall - Function* get_fputs(const Type* FILEptr_type) { + Constant *get_fputs(const Type* FILEptr_type) { if (!fputs_func) fputs_func = M->getOrInsertFunction("fputs", Type::Int32Ty, PointerType::get(Type::Int8Ty), @@ -256,7 +256,7 @@ public: } /// @brief Return a Function* for the fwrite libcall - Function* get_fwrite(const Type* FILEptr_type) { + Constant *get_fwrite(const Type* FILEptr_type) { if (!fwrite_func) fwrite_func = M->getOrInsertFunction("fwrite", TD->getIntPtrType(), PointerType::get(Type::Int8Ty), @@ -267,7 +267,7 @@ public: } /// @brief Return a Function* for the sqrt libcall - Function* get_sqrt() { + Constant *get_sqrt() { if (!sqrt_func) sqrt_func = M->getOrInsertFunction("sqrt", Type::DoubleTy, Type::DoubleTy, NULL); @@ -275,7 +275,7 @@ public: } /// @brief Return a Function* for the strlen libcall - Function* get_strcpy() { + Constant *get_strcpy() { if (!strcpy_func) strcpy_func = M->getOrInsertFunction("strcpy", PointerType::get(Type::Int8Ty), @@ -286,7 +286,7 @@ public: } /// @brief Return a Function* for the strlen libcall - Function* get_strlen() { + Constant *get_strlen() { if (!strlen_func) strlen_func = M->getOrInsertFunction("strlen", TD->getIntPtrType(), PointerType::get(Type::Int8Ty), @@ -295,7 +295,7 @@ public: } /// @brief Return a Function* for the memchr libcall - Function* get_memchr() { + Constant *get_memchr() { if (!memchr_func) memchr_func = M->getOrInsertFunction("memchr", PointerType::get(Type::Int8Ty), @@ -306,7 +306,7 @@ public: } /// @brief Return a Function* for the memcpy libcall - Function* get_memcpy() { + Constant *get_memcpy() { if (!memcpy_func) { const Type *SBP = PointerType::get(Type::Int8Ty); const char *N = TD->getIntPtrType() == Type::Int32Ty ? @@ -318,17 +318,17 @@ public: return memcpy_func; } - Function *getUnaryFloatFunction(const char *Name, Function *&Cache) { + Constant *getUnaryFloatFunction(const char *Name, Constant *&Cache) { if (!Cache) Cache = M->getOrInsertFunction(Name, Type::FloatTy, Type::FloatTy, NULL); return Cache; } - Function *get_floorf() { return getUnaryFloatFunction("floorf", floorf_func);} - Function *get_ceilf() { return getUnaryFloatFunction( "ceilf", ceilf_func);} - Function *get_roundf() { return getUnaryFloatFunction("roundf", roundf_func);} - Function *get_rintf() { return getUnaryFloatFunction( "rintf", rintf_func);} - Function *get_nearbyintf() { return getUnaryFloatFunction("nearbyintf", + Constant *get_floorf() { return getUnaryFloatFunction("floorf", floorf_func);} + Constant *get_ceilf() { return getUnaryFloatFunction( "ceilf", ceilf_func);} + Constant *get_roundf() { return getUnaryFloatFunction("roundf", roundf_func);} + Constant *get_rintf() { return getUnaryFloatFunction( "rintf", rintf_func);} + Constant *get_nearbyintf() { return getUnaryFloatFunction("nearbyintf", nearbyintf_func); } private: /// @brief Reset our cached data for a new Module @@ -354,13 +354,13 @@ private: private: /// Caches for function pointers. - Function *putchar_func, *puts_func; - Function *fputc_func, *fputs_func, *fwrite_func; - Function *memcpy_func, *memchr_func; - Function* sqrt_func; - Function *strcpy_func, *strlen_func; - Function *floorf_func, *ceilf_func, *roundf_func; - Function *rintf_func, *nearbyintf_func; + Constant *putchar_func, *puts_func; + Constant *fputc_func, *fputs_func, *fwrite_func; + Constant *memcpy_func, *memchr_func; + Constant *sqrt_func; + Constant *strcpy_func, *strlen_func; + Constant *floorf_func, *ceilf_func, *roundf_func; + Constant *rintf_func, *nearbyintf_func; Module *M; ///< Cached Module TargetData *TD; ///< Cached TargetData }; @@ -564,12 +564,12 @@ public: if (!CSI) { // The second operand is not constant, or not signed. Just lower this to // memchr since we know the length of the string since it is constant. - Function* f = SLC.get_memchr(); + Constant *f = SLC.get_memchr(); std::vector<Value*> args; args.push_back(ci->getOperand(1)); args.push_back(ci->getOperand(2)); args.push_back(ConstantInt::get(SLC.getIntPtrType(), len)); - ci->replaceAllUsesWith( new CallInst(f, args, ci->getName(), ci)); + ci->replaceAllUsesWith(new CallInst(f, args, ci->getName(), ci)); ci->eraseFromParent(); return true; } @@ -1344,13 +1344,10 @@ public: return false; // printf("%s\n",str) -> puts(str) - Function* puts_func = SLC.get_puts(); - if (!puts_func) - return false; std::vector<Value*> args; - args.push_back(CastToCStr(ci->getOperand(2), *ci)); - new CallInst(puts_func,args,ci->getName(),ci); - ci->replaceAllUsesWith(ConstantInt::get(Type::Int32Ty,len)); + new CallInst(SLC.get_puts(), CastToCStr(ci->getOperand(2), *ci), + ci->getName(), ci); + ci->replaceAllUsesWith(ConstantInt::get(Type::Int32Ty, len)); break; } case 'c': @@ -1359,12 +1356,9 @@ public: if (len != 2) return false; - Function* putchar_func = SLC.get_putchar(); - if (!putchar_func) - return false; - CastInst* cast = CastInst::createSExtOrBitCast( + CastInst *Char = CastInst::createSExtOrBitCast( ci->getOperand(2), Type::Int32Ty, CI->getName()+".int", ci); - new CallInst(putchar_func, cast, "", ci); + new CallInst(SLC.get_putchar(), Char, "", ci); ci->replaceAllUsesWith(ConstantInt::get(Type::Int32Ty, 1)); break; } @@ -1424,14 +1418,10 @@ public: // fprintf(file,fmt) -> fwrite(fmt,strlen(fmt),file) const Type* FILEptr_type = ci->getOperand(1)->getType(); - Function* fwrite_func = SLC.get_fwrite(FILEptr_type); - if (!fwrite_func) - return false; // Make sure that the fprintf() and fwrite() functions both take the // same type of char pointer. - if (ci->getOperand(2)->getType() != - fwrite_func->getFunctionType()->getParamType(0)) + if (ci->getOperand(2)->getType() != PointerType::get(Type::Int8Ty)) return false; std::vector<Value*> args; @@ -1439,7 +1429,7 @@ public: args.push_back(ConstantInt::get(SLC.getIntPtrType(),len)); args.push_back(ConstantInt::get(SLC.getIntPtrType(),1)); args.push_back(ci->getOperand(1)); - new CallInst(fwrite_func,args,ci->getName(),ci); + new CallInst(SLC.get_fwrite(FILEptr_type), args, ci->getName(), ci); ci->replaceAllUsesWith(ConstantInt::get(Type::Int32Ty,len)); ci->eraseFromParent(); return true; @@ -1465,26 +1455,19 @@ public: if (getConstantStringLength(ci->getOperand(3), len, &CA)) { // fprintf(file,"%s",str) -> fwrite(str,strlen(str),1,file) const Type* FILEptr_type = ci->getOperand(1)->getType(); - Function* fwrite_func = SLC.get_fwrite(FILEptr_type); - if (!fwrite_func) - return false; std::vector<Value*> args; args.push_back(CastToCStr(ci->getOperand(3), *ci)); - args.push_back(ConstantInt::get(SLC.getIntPtrType(),len)); - args.push_back(ConstantInt::get(SLC.getIntPtrType(),1)); + args.push_back(ConstantInt::get(SLC.getIntPtrType(), len)); + args.push_back(ConstantInt::get(SLC.getIntPtrType(), 1)); args.push_back(ci->getOperand(1)); - new CallInst(fwrite_func,args,ci->getName(),ci); - ci->replaceAllUsesWith(ConstantInt::get(Type::Int32Ty,len)); + new CallInst(SLC.get_fwrite(FILEptr_type), args, ci->getName(), ci); + ci->replaceAllUsesWith(ConstantInt::get(Type::Int32Ty, len)); } else { // fprintf(file,"%s",str) -> fputs(str,file) const Type* FILEptr_type = ci->getOperand(1)->getType(); - Function* fputs_func = SLC.get_fputs(FILEptr_type); - if (!fputs_func) - return false; - std::vector<Value*> args; - args.push_back(CastToCStr(ci->getOperand(3), *ci)); - args.push_back(ci->getOperand(1)); - new CallInst(fputs_func,args,ci->getName(),ci); + new CallInst(SLC.get_fputs(FILEptr_type), + CastToCStr(ci->getOperand(3), *ci), + ci->getOperand(1), ci->getName(),ci); ci->replaceAllUsesWith(ConstantInt::get(Type::Int32Ty,len)); } break; @@ -1493,12 +1476,9 @@ public: { // fprintf(file,"%c",c) -> fputc(c,file) const Type* FILEptr_type = ci->getOperand(1)->getType(); - Function* fputc_func = SLC.get_fputc(FILEptr_type); - if (!fputc_func) - return false; CastInst* cast = CastInst::createSExtOrBitCast( ci->getOperand(3), Type::Int32Ty, CI->getName()+".int", ci); - new CallInst(fputc_func,cast,ci->getOperand(1),"",ci); + new CallInst(SLC.get_fputc(FILEptr_type), cast,ci->getOperand(1),"",ci); ci->replaceAllUsesWith(ConstantInt::get(Type::Int32Ty,1)); break; } @@ -1563,15 +1543,12 @@ public: len++; // sprintf(str,fmt) -> llvm.memcpy(str,fmt,strlen(fmt),1) - Function* memcpy_func = SLC.get_memcpy(); - if (!memcpy_func) - return false; std::vector<Value*> args; args.push_back(ci->getOperand(1)); args.push_back(ci->getOperand(2)); args.push_back(ConstantInt::get(SLC.getIntPtrType(),len)); args.push_back(ConstantInt::get(Type::Int32Ty,1)); - new CallInst(memcpy_func,args,"",ci); + new CallInst(SLC.get_memcpy(), args, "", ci); ci->replaceAllUsesWith(ConstantInt::get(Type::Int32Ty,len)); ci->eraseFromParent(); return true; @@ -1592,12 +1569,8 @@ public: switch (CI->getZExtValue()) { case 's': { // sprintf(dest,"%s",str) -> llvm.memcpy(dest, str, strlen(str)+1, 1) - Function* strlen_func = SLC.get_strlen(); - Function* memcpy_func = SLC.get_memcpy(); - if (!strlen_func || !memcpy_func) - return false; - - Value *Len = new CallInst(strlen_func, CastToCStr(ci->getOperand(3), *ci), + Value *Len = new CallInst(SLC.get_strlen(), + CastToCStr(ci->getOperand(3), *ci), ci->getOperand(3)->getName()+".len", ci); Value *Len1 = BinaryOperator::createAdd(Len, ConstantInt::get(Len->getType(), 1), @@ -1610,7 +1583,7 @@ public: args.push_back(CastToCStr(ci->getOperand(3), *ci)); args.push_back(Len1); args.push_back(ConstantInt::get(Type::Int32Ty,1)); - new CallInst(memcpy_func, args, "", ci); + new CallInst(SLC.get_memcpy(), args, "", ci); // The strlen result is the unincremented number of bytes in the string. if (!ci->use_empty()) { @@ -1676,29 +1649,24 @@ public: { // fputs(s,F) -> fputc(s[0],F) (if s is constant and strlen(s) == 1) const Type* FILEptr_type = ci->getOperand(2)->getType(); - Function* fputc_func = SLC.get_fputc(FILEptr_type); - if (!fputc_func) - return false; LoadInst* loadi = new LoadInst(ci->getOperand(1), ci->getOperand(1)->getName()+".byte",ci); CastInst* casti = new SExtInst(loadi, Type::Int32Ty, loadi->getName()+".int", ci); - new CallInst(fputc_func,casti,ci->getOperand(2),"",ci); + new CallInst(SLC.get_fputc(FILEptr_type), casti, + ci->getOperand(2), "", ci); break; } default: { // fputs(s,F) -> fwrite(s,1,len,F) (if s is constant and strlen(s) > 1) const Type* FILEptr_type = ci->getOperand(2)->getType(); - Function* fwrite_func = SLC.get_fwrite(FILEptr_type); - if (!fwrite_func) - return false; std::vector<Value*> parms; parms.push_back(ci->getOperand(1)); parms.push_back(ConstantInt::get(SLC.getIntPtrType(),len)); parms.push_back(ConstantInt::get(SLC.getIntPtrType(),1)); parms.push_back(ci->getOperand(2)); - new CallInst(fwrite_func,parms,"",ci); + new CallInst(SLC.get_fwrite(FILEptr_type), parms, "", ci); break; } } @@ -1860,7 +1828,7 @@ public: case Type::Int64TyID : CTTZName = "llvm.cttz.i64"; break; } - Function *F = SLC.getModule()->getOrInsertFunction(CTTZName, ArgType, + Constant *F = SLC.getModule()->getOrInsertFunction(CTTZName, ArgType, ArgType, NULL); Value *V = CastInst::createIntegerCast(TheCall->getOperand(1), ArgType, false/*ZExt*/, "tmp", TheCall); @@ -1921,7 +1889,7 @@ struct UnaryDoubleFPOptimizer : public LibCallOptimization { /// when the target supports the destination function and where there can be /// no precision loss. static bool ShrinkFunctionToFloatVersion(CallInst *CI, SimplifyLibCalls &SLC, - Function *(SimplifyLibCalls::*FP)()){ + Constant *(SimplifyLibCalls::*FP)()){ if (CastInst *Cast = dyn_cast<CastInst>(CI->getOperand(1))) if (Cast->getOperand(0)->getType() == Type::FloatTy) { Value *New = new CallInst((SLC.*FP)(), Cast->getOperand(0), diff --git a/lib/Transforms/Utils/LowerAllocations.cpp b/lib/Transforms/Utils/LowerAllocations.cpp index a842139714..00f89ffc3d 100644 --- a/lib/Transforms/Utils/LowerAllocations.cpp +++ b/lib/Transforms/Utils/LowerAllocations.cpp @@ -32,8 +32,8 @@ namespace { /// %free calls. /// class VISIBILITY_HIDDEN LowerAllocations : public BasicBlockPass { - Function *MallocFunc; // Functions in the module we are processing - Function *FreeFunc; // Initialized by doInitialization + Constant *MallocFunc; // Functions in the module we are processing + Constant *FreeFunc; // Initialized by doInitialization bool LowerMallocArgToInteger; public: LowerAllocations(bool LowerToInt = false) @@ -84,19 +84,12 @@ FunctionPass *llvm::createLowerAllocationsPass(bool LowerMallocArgToInteger) { // This function is always successful. // bool LowerAllocations::doInitialization(Module &M) { - const Type *SBPTy = PointerType::get(Type::Int8Ty); - MallocFunc = M.getNamedFunction("malloc"); - FreeFunc = M.getNamedFunction("free"); - - if (MallocFunc == 0) { - // Prototype malloc as "void* malloc(...)", because we don't know in - // doInitialization whether size_t is int or long. - FunctionType *FT = FunctionType::get(SBPTy,std::vector<const Type*>(),true); - MallocFunc = M.getOrInsertFunction("malloc", FT); - } - if (FreeFunc == 0) - FreeFunc = M.getOrInsertFunction("free" , Type::VoidTy, SBPTy, (Type *)0); - + const Type *BPTy = PointerType::get(Type::Int8Ty); + // Prototype malloc as "char* malloc(...)", because we don't know in + // doInitialization whether size_t is int or long. + FunctionType *FT = FunctionType::get(BPTy, std::vector<const Type*>(), true); + MallocFunc = M.getOrInsertFunction("malloc", FT); + FreeFunc = M.getOrInsertFunction("free" , Type::VoidTy, BPTy, (Type *)0); return true; } @@ -145,27 +138,8 @@ bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) { } } - const FunctionType *MallocFTy = MallocFunc->getFunctionType(); - std::vector<Value*> MallocArgs; - - if (MallocFTy->getNumParams() > 0 || MallocFTy->isVarArg()) { - if (MallocFTy->isVarArg()) { - if (MallocArg->getType() != IntPtrTy) - MallocArg = CastInst::createIntegerCast(MallocArg, IntPtrTy, - false /*ZExt*/, "", I); - } else if (MallocFTy->getNumParams() > 0 && - MallocFTy->getParamType(0) != Type::Int32Ty) - MallocArg = CastInst::createIntegerCast( - MallocArg, MallocFTy->getParamType(0), false/*ZExt*/, "",I); - MallocArgs.push_back(MallocArg); - } - - // If malloc is prototyped to take extra arguments, pass nulls. - for (unsigned i = 1; i < MallocFTy->getNumParams(); ++i) - MallocArgs.push_back(Constant::getNullValue(MallocFTy->getParamType(i))); - - // Create the call to Malloc... - CallInst *MCall = new CallInst(MallocFunc, MallocArgs, "", I); + // Create the call to Malloc. + CallInst *MCall = new CallInst(MallocFunc, MallocArg, "", I); MCall->setTailCall(); // Create a cast instruction to convert to the right type... @@ -181,23 +155,11 @@ bool LowerAllocations::runOnBasicBlock(BasicBlock &BB) { Changed = true; ++NumLowered; } else if (FreeInst *FI = dyn_cast<FreeInst>(I)) { - const FunctionType *FreeFTy = FreeFunc->getFunctionType(); - std::vector<Value*> FreeArgs; - - if (FreeFTy->getNumParams() > 0 || FreeFTy->isVarArg()) { - Value *MCast = FI->getOperand(0); - if (FreeFTy->getNumParams() > 0 && - FreeFTy->getParamType(0) != MCast->getType()) - MCast = new BitCastInst(MCast, FreeFTy->getParamType(0), "", I); - FreeArgs.push_back(MCast); - } - - // If malloc is prototyped to take extra arguments, pass nulls. - for (unsigned i = 1; i < FreeFTy->getNumParams(); ++i) - FreeArgs.push_back(Constant::getNullValue(FreeFTy->getParamType(i))); + Value *PtrCast = new BitCastInst(FI->getOperand(0), + PointerType::get(Type::Int8Ty), "", I); // Insert a call to the free function... - (new CallInst(FreeFunc, FreeArgs, "", I))->setTailCall(); + (new CallInst(FreeFunc, PtrCast, "", I))->setTailCall(); // Delete the old free instruction I = --BBIL.erase(I); diff --git a/lib/Transforms/Utils/LowerInvoke.cpp b/lib/Transforms/Utils/LowerInvoke.cpp index 20f5671686..a027743bda 100644 --- a/lib/Transforms/Utils/LowerInvoke.cpp +++ b/lib/Transforms/Utils/LowerInvoke.cpp @@ -60,15 +60,15 @@ static cl::opt<bool> ExpensiveEHSupport("enable-correct-eh-support", namespace { class VISIBILITY_HIDDEN LowerInvoke : public FunctionPass { // Used for both models. - Function *WriteFn; - Function *AbortFn; + Constant *WriteFn; + Constant *AbortFn; Value *AbortMessage; unsigned AbortMessageLength; // Used for expensive EH support. const Type *JBLinkTy; GlobalVariable *JBListHead; - Function *SetJmpFn, *LongJmpFn; + Constant *SetJmpFn, *LongJmpFn; // We peek in TLI to grab the target's jmp_buf size and alignment const TargetLowering *TLI; @@ -87,7 +87,7 @@ namespace { } private: - void createAbortMessage(); + void createAbortMessage(Module *M); void writeAbortMessage(Instruction *IB); bool insertCheapEHSupport(Function &F); void splitLiveRangesLiveAcrossInvokes(std::vector<InvokeInst*> &Invokes); @@ -148,29 +148,12 @@ bool LowerInvoke::doInitialization(Module &M) { // We need the 'write' and 'abort' functions for both models. AbortFn = M.getOrInsertFunction("abort", Type::VoidTy, (Type *)0); - - // Unfortunately, 'write' can end up being prototyped in several different - // ways. If the user defines a three (or more) operand function named 'write' - // we will use their prototype. We _do not_ want to insert another instance - // of a write prototype, because we don't know that the funcresolve pass will - // run after us. If there is a definition of a write function, but it's not - // suitable for our uses, we just don't emit write calls. If there is no - // write prototype at all, we just add one. - if (Function *WF = M.getNamedFunction("write")) { - if (WF->getFunctionType()->getNumParams() > 3 || - WF->getFunctionType()->isVarArg()) - WriteFn = WF; - else - WriteFn = 0; - } else { - WriteFn = M.getOrInsertFunction("write", Type::VoidTy, Type::Int32Ty, - VoidPtrTy, Type::Int32Ty, (Type *)0); - } + WriteFn = M.getOrInsertFunction("write", Type::VoidTy, Type::Int32Ty, + VoidPtrTy, Type::Int32Ty, (Type *)0); return true; } -void LowerInvoke::createAbortMessage() { - Module &M = *WriteFn->getParent(); +void LowerInvoke::createAbortMessage(Module *M) { if (ExpensiveEHSupport) { // The abort message for expensive EH support tells the user that the // program 'unwound' without an 'invoke' instruction. @@ -180,7 +163,7 @@ void LowerInvoke::createAbortMessage() { GlobalVariable *MsgGV = new GlobalVariable(Msg->getType(), true, GlobalValue::InternalLinkage, - Msg, "abortmsg", &M); + Msg, "abortmsg", M); std::vector<Constant*> GEPIdx(2, Constant::getNullValue(Type::Int32Ty)); AbortMessage = ConstantExpr::getGetElementPtr(MsgGV, GEPIdx); } else { @@ -193,7 +176,7 @@ void LowerInvoke::createAbortMessage() { GlobalVariable *MsgGV = new GlobalVariable(Msg->getType(), true, GlobalValue::InternalLinkage, - Msg, "abortmsg", &M); + Msg, "abortmsg", M); std::vector<Constant*> GEPIdx(2, Constant::getNullValue(Type::Int32Ty)); AbortMessage = ConstantExpr::getGetElementPtr(MsgGV, GEPIdx); } @@ -201,30 +184,15 @@ void LowerInvoke::createAbortMessage() { void LowerInvoke::writeAbortMessage(Instruction *IB) { - if (WriteFn) { - if (AbortMessage == 0) createAbortMessage(); - - // These are the arguments we WANT... - std::vector<Value*> Args; - Args.push_back(ConstantInt::get(Type::Int32Ty, 2)); - Args.push_back(AbortMessage); - Args.push_back(ConstantInt::get(Type::Int32Ty, AbortMessageLength)); - - // If the actual declaration of write disagrees, insert casts as - // appropriate. - const FunctionType *FT = WriteFn->getFunctionType(); - unsigned NumArgs = FT->getNumParams(); - for (unsigned i = 0; i != 3; ++i) - if (i < NumArgs && FT->getParamType(i) != Args[i]->getType()) - if (Args[i]->getType()->isInteger()) - Args[i] = ConstantExpr::getIntegerCast(cast<Constant>(Args[i]), - FT->getParamType(i), true); - else - Args[i] = ConstantExpr::getBitCast(cast<Constant>(Args[i]), - FT->getParamType(i)); - - (new CallInst(WriteFn, Args, "", IB))->setTailCall(); - } + if (AbortMessage == 0) + createAbortMessage(IB->getParent()->getParent()->getParent()); + + // These are the arguments we WANT... + std::vector<Value*> Args; + Args.push_back(ConstantInt::get(Type::Int32Ty, 2)); + Args.push_back(AbortMessage); + Args.push_back(ConstantInt::get(Type::Int32Ty, AbortMessageLength)); + (new CallInst(WriteFn, Args, "", IB))->setTailCall(); } bool LowerInvoke::insertCheapEHSupport(Function &F) { |