OSDN Git Service

Change the interface to Module::getOrInsertFunction to be easier to use,to resolve...
authorChris Lattner <sabre@nondot.org>
Sun, 7 Jan 2007 08:12:01 +0000 (08:12 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 7 Jan 2007 08:12:01 +0000 (08:12 +0000)
This simplifies many clients also

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32989 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/IntrinsicLowering.cpp
lib/Transforms/IPO/SimplifyLibCalls.cpp
lib/Transforms/Utils/LowerAllocations.cpp
lib/Transforms/Utils/LowerInvoke.cpp

index 41d48d9..ba89052 100644 (file)
 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;
   }
   }
index 4d37fbf..2c5821a 100644 (file)
@@ -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),
index a842139..00f89ff 100644 (file)
@@ -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);
index 20f5671..a027743 100644 (file)
@@ -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) {