[llvm-commits] [llvm-gcc-4.2] r44360 - in /llvm-gcc-4.2/trunk/gcc: llvm-backend.cpp llvm-convert.cpp llvm-internal.h llvm-types.cpp

Duncan Sands baldrick at free.fr
Tue Nov 27 05:23:48 PST 2007


Author: baldrick
Date: Tue Nov 27 07:23:48 2007
New Revision: 44360

URL: http://llvm.org/viewvc/llvm-project?rev=44360&view=rev
Log:
Fix PR1146: function attributes go on functions
and function calls, not on function types.  This
is an updated version of Reid Spencer's original
patch.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-internal.h
    llvm-gcc-4.2/trunk/gcc/llvm-types.cpp

Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=44360&r1=44359&r2=44360&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Tue Nov 27 07:23:48 2007
@@ -1022,10 +1022,13 @@
     Function *FnEntry = TheModule->getFunction(Name);
     if (FnEntry == 0) {
       unsigned CC;
+      const ParamAttrsList *PAL;
       const FunctionType *Ty = 
-        TheTypeConverter->ConvertFunctionType(TREE_TYPE(decl), decl, NULL, CC);
+        TheTypeConverter->ConvertFunctionType(TREE_TYPE(decl), decl, NULL,
+                                              CC, PAL);
       FnEntry = new Function(Ty, Function::ExternalLinkage, Name, TheModule);
       FnEntry->setCallingConv(CC);
+      FnEntry->setParamAttrs(PAL);
 
       // Check for external weak linkage
       if (DECL_EXTERNAL(decl) && DECL_WEAK(decl))

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=44360&r1=44359&r2=44360&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Nov 27 07:23:48 2007
@@ -33,7 +33,6 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/InlineAsm.h"
 #include "llvm/Instructions.h"
-#include "llvm/IntrinsicInst.h" // FIXME: Remove once PR1146 is done.
 #include "llvm/Module.h"
 #include "llvm/Analysis/ConstantFolding.h"
 #include "llvm/Support/MathExtras.h"
@@ -526,7 +525,8 @@
   tree static_chain = cfun->static_chain_decl;
   const FunctionType *FTy;
   unsigned CallingConv;
-  
+  const ParamAttrsList *PAL;
+
   // If the function has no arguments and is varargs (...), turn it into a
   // non-varargs function by scanning the param list for the function.  This
   // allows C functions declared as "T foo() {}" to be treated like 
@@ -536,7 +536,7 @@
     FTy = TheTypeConverter->ConvertArgListToFnType(TREE_TYPE(TREE_TYPE(FnDecl)),
                                                    DECL_ARGUMENTS(FnDecl),
                                                    static_chain,
-                                                   CallingConv);
+                                                   CallingConv, PAL);
 #ifdef TARGET_ADJUST_LLVM_CC
     TARGET_ADJUST_LLVM_CC(CallingConv, TREE_TYPE(FnDecl));
 #endif
@@ -545,7 +545,7 @@
     FTy = TheTypeConverter->ConvertFunctionType(TREE_TYPE(FnDecl),
                                                 FnDecl,
                                                 static_chain,
-                                                CallingConv);
+                                                CallingConv, PAL);
   }
   
   // If we've already seen this function and created a prototype, and if the
@@ -581,7 +581,8 @@
     Fn = new Function(FTy, Function::ExternalLinkage, Name, TheModule);
     assert(Fn->getName() == Name && "Preexisting fn with the same name!");
     Fn->setCallingConv(CallingConv);
-    
+    Fn->setParamAttrs(PAL);
+
     // If a previous proto existed with the wrong type, replace any uses of it
     // with the actual function and delete the proto.
     if (FnEntry) {
@@ -2166,34 +2167,25 @@
 
   Value *Callee = Emit(TREE_OPERAND(exp, 0), 0);
 
-  // Avoid this kind of thing while waiting for PR1146 to be fixed:
-  //
-  //   call void bitcast (void (i32* noalias , i32*)* @_Z3fooPiPVi
-  //     to void (i32*, i32*)*)( i32* %x, i32* %y )
-  //
-  // The problem is that some attributes like noalias are only stored in the
-  // GCC function declaration and are not available from the function type.
-  // Converting the function type to LLVM results in an LLVM function type
-  // without the attributes.  The function declaration however is turned into
-  // an LLVM function type with the attributes present.  The discrepancy in
-  // the types results in the bitcast.  The solution is to bitcast back to the
-  // type of the function declaration.  Once PR1146 is done this logic will only
-  // be needed for nested functions (-> TREE_OPERAND(exp, 2) is not NULL) - they
-  // get an extra parameter.
   assert(TREE_TYPE (TREE_OPERAND (exp, 0)) &&
          TREE_CODE(TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
          && "Not calling a function pointer?");
   tree function_type = TREE_TYPE(TREE_TYPE (TREE_OPERAND (exp, 0)));
   unsigned CallingConv;
+  const ParamAttrsList *PAL;
+
   const Type *Ty = TheTypeConverter->ConvertFunctionType(function_type,
                                                          fndecl,
                                                          TREE_OPERAND(exp, 2),
-                                                         CallingConv);
-  Callee = BitCastToType(IntrinsicInst::StripPointerCasts(Callee),
-                         PointerType::get(Ty));
+                                                         CallingConv, PAL);
+
+  // If this is a direct call to a function using a static chain then we need
+  // to ensure the function type is the one just calculated: it has an extra
+  // parameter for the chain.
+  Callee = BitCastToType(Callee, PointerType::get(Ty));
 
   //EmitCall(exp, DestLoc);
-  Value *Result = EmitCallOf(Callee, exp, DestLoc);
+  Value *Result = EmitCallOf(Callee, exp, DestLoc, PAL);
 
   // If the function has the volatile bit set, then it is a "noreturn" function.
   // Output an unreachable instruction right after the function to prevent LLVM
@@ -2214,7 +2206,6 @@
     tree CallExpression;
     SmallVector<Value*, 16> &CallOperands;
     CallingConv::ID &CallingConvention;
-    bool isStructRet;
     LLVMBuilder &Builder;
     const MemRef *DestLoc;
     std::vector<Value*> LocStack;
@@ -2225,7 +2216,6 @@
       : CallExpression(exp), CallOperands(ops), CallingConvention(cc),
         Builder(b), DestLoc(destloc) {
       CallingConvention = CallingConv::C;
-      isStructRet = false;
 #ifdef TARGET_ADJUST_LLVM_CC
       tree ftype;
       if (tree fdecl = get_callee_fndecl(exp)) {
@@ -2271,9 +2261,6 @@
     /// function.
     void HandleAggregateShadowArgument(const PointerType *PtrArgTy,
                                        bool RetPtr) {
-      // Make sure this call is marked as 'struct return'.
-      isStructRet = true;
-
       // We need to pass a buffer to return into.  If the caller uses the
       // result, DestLoc will be set.  If it ignores it, it could be unset,
       // in which case we need to create a dummy buffer.
@@ -2318,7 +2305,8 @@
 /// EmitCallOf - Emit a call to the specified callee with the operands specified
 /// in the CALL_EXP 'exp'.  If the result of the call is a scalar, return the
 /// result, otherwise store it in DestLoc.
-Value *TreeToLLVM::EmitCallOf(Value *Callee, tree exp, const MemRef *DestLoc) {
+Value *TreeToLLVM::EmitCallOf(Value *Callee, tree exp, const MemRef *DestLoc,
+                              const ParamAttrsList *PAL) {
   // Determine if we need to generate an invoke instruction (instead of a simple
   // call) and if so, what the exception destination will be.
   BasicBlock *LandingPad = 0;
@@ -2428,11 +2416,13 @@
   if (!LandingPad) {
     Call = Builder.CreateCall(Callee, CallOperands.begin(), CallOperands.end());
     cast<CallInst>(Call)->setCallingConv(CallingConvention);
+    cast<CallInst>(Call)->setParamAttrs(PAL);
   } else {
     BasicBlock *NextBlock = new BasicBlock("invcont");
     Call = Builder.CreateInvoke(Callee, NextBlock, LandingPad,
                                 CallOperands.begin(), CallOperands.end());
     cast<InvokeInst>(Call)->setCallingConv(CallingConvention);
+    cast<InvokeInst>(Call)->setParamAttrs(PAL);
     EmitBlock(NextBlock);
   }
   
@@ -3920,7 +3910,7 @@
         Intrinsic::getDeclaration(TheModule, IntrinsicID);
     }
 
-    Result = EmitCallOf(TargetBuiltinCache[FnCode], exp, DestLoc);
+    Result = EmitCallOf(TargetBuiltinCache[FnCode], exp, DestLoc, 0);
     return true;
   }
   

Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=44360&r1=44359&r2=44360&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Tue Nov 27 07:23:48 2007
@@ -151,11 +151,12 @@
   
   /// ConvertFunctionType - Convert the specified FUNCTION_TYPE or METHOD_TYPE
   /// tree to an LLVM type.  This does the same thing that ConvertType does, but
-  /// it also returns the function's LLVM calling convention.
+  /// it also returns the function's LLVM calling convention and attributes.
   const FunctionType *ConvertFunctionType(tree_node *type,
                                           tree_node *decl,
                                           tree_node *static_chain,
-                                          unsigned &CallingConv);
+                                          unsigned &CallingConv,
+                                          const ParamAttrsList *&PAL);
   
   /// ConvertArgListToFnType - Given a DECL_ARGUMENTS list on an GCC tree,
   /// return the LLVM type corresponding to the function.  This is useful for
@@ -163,7 +164,8 @@
   const FunctionType *ConvertArgListToFnType(tree_node *retty,
                                              tree_node *arglist,
                                              tree_node *static_chain,
-                                             unsigned &CallingConv);
+                                             unsigned &CallingConv,
+                                             const ParamAttrsList *&PAL);
   
 private:
   const Type *ConvertRECORD(tree_node *type, tree_node *orig_type);
@@ -463,7 +465,8 @@
   Value *EmitADDR_EXPR(tree_node *exp);
   Value *EmitOBJ_TYPE_REF(tree_node *exp);
   Value *EmitCALL_EXPR(tree_node *exp, const MemRef *DestLoc);
-  Value *EmitCallOf(Value *Callee, tree_node *exp, const MemRef *DestLoc);
+  Value *EmitCallOf(Value *Callee, tree_node *exp, const MemRef *DestLoc,
+                    const ParamAttrsList *PAL);
   Value *EmitMODIFY_EXPR(tree_node *exp, const MemRef *DestLoc);
   Value *EmitNOP_EXPR(tree_node *exp, const MemRef *DestLoc);
   Value *EmitCONVERT_EXPR(tree_node *exp, const MemRef *DestLoc);

Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=44360&r1=44359&r2=44360&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Tue Nov 27 07:23:48 2007
@@ -215,14 +215,13 @@
 /// takes PATypeHolders.
 static FunctionType *GetFunctionType(const PATypeHolder &Res,
                                      std::vector<PATypeHolder> &ArgTys,
-                                     bool isVarArg,
-                                     const ParamAttrsList *Attrs) {
+                                     bool isVarArg) {
   std::vector<const Type*> ArgTysP;
   ArgTysP.reserve(ArgTys.size());
   for (unsigned i = 0, e = ArgTys.size(); i != e; ++i)
     ArgTysP.push_back(ArgTys[i]);
   
-  return FunctionType::get(Res, ArgTysP, isVarArg, Attrs);
+  return FunctionType::get(Res, ArgTysP, isVarArg);
 }
 
 //===----------------------------------------------------------------------===//
@@ -840,10 +839,10 @@
       
     // No declaration to pass through, passing NULL.
     unsigned CallingConv;
-    return TypeDB.setType(type, ConvertFunctionType(type, 
-                                                    NULL, 
-                                                    NULL, 
-                                                    CallingConv));
+    const ParamAttrsList *PAL;
+
+    return TypeDB.setType(type, ConvertFunctionType(type, NULL, NULL,
+                                                    CallingConv, PAL));
   }
   case ARRAY_TYPE: {
     if (const Type *Ty = GET_TYPE_LLVM(type))
@@ -973,7 +972,7 @@
 /// specified result type for the function.
 const FunctionType *TypeConverter::
 ConvertArgListToFnType(tree ReturnType, tree Args, tree static_chain,
-                       unsigned &CallingConv) {
+                       unsigned &CallingConv, const ParamAttrsList *&PAL) {
   std::vector<PATypeHolder> ArgTys;
   PATypeHolder RetTy(Type::VoidTy);
   
@@ -995,17 +994,16 @@
   for (; Args && TREE_TYPE(Args) != void_type_node; Args = TREE_CHAIN(Args))
     ABIConverter.HandleArgument(TREE_TYPE(Args));
 
-  ParamAttrsList *PAL = 0;
+  PAL = 0;
   if (!Attrs.empty())
     PAL = ParamAttrsList::get(Attrs);
 
-  return GetFunctionType(RetTy, ArgTys, false, PAL);
+  return GetFunctionType(RetTy, ArgTys, false);
 }
 
-const FunctionType *TypeConverter::ConvertFunctionType(tree type,
-                                                       tree decl,
-                                                       tree static_chain,
-                                                       unsigned &CallingConv) {
+const FunctionType *TypeConverter::
+ConvertFunctionType(tree type, tree decl, tree static_chain,
+                    unsigned &CallingConv, const ParamAttrsList *&PAL) {
   PATypeHolder RetTy = Type::VoidTy;
   std::vector<PATypeHolder> ArgTypes;
   bool isVarArg = false;
@@ -1149,12 +1147,12 @@
   assert(RetTy && "Return type not specified!");
 
   // Only instantiate the parameter attributes if we got some.
-  ParamAttrsList *PAL = 0;
+  PAL = 0;
   if (!Attrs.empty())
     PAL = ParamAttrsList::get(Attrs);
 
   // Finally, make the function type
-  return GetFunctionType(RetTy, ArgTypes, isVarArg, PAL);
+  return GetFunctionType(RetTy, ArgTypes, isVarArg);
 }
 
 //===----------------------------------------------------------------------===//





More information about the llvm-commits mailing list