Author: baldrick Date: Tue Nov 27 07:23:49 2007 New Revision: 44361 URL: http://llvm.org/viewvc/llvm-project?rev=44361&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.0/trunk/gcc/llvm-backend.cpp llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp llvm-gcc-4.0/trunk/gcc/llvm-internal.h llvm-gcc-4.0/trunk/gcc/llvm-types.cpp Modified: llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp?rev=44361&r1=44360&r2=44361&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Tue Nov 27 07:23:49 2007 @@ -1000,10 +1000,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.0/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp?rev=44361&r1=44360&r2=44361&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Tue Nov 27 07:23:49 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" @@ -500,7 +499,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 @@ -510,7 +510,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 @@ -519,7 +519,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 @@ -555,7 +555,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) { @@ -2649,34 +2650,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 @@ -2697,7 +2689,6 @@ tree CallExpression; SmallVector<Value*, 16> &CallOperands; CallingConv::ID &CallingConvention; - bool isStructRet; LLVMBuilder &Builder; const MemRef *DestLoc; std::vector<Value*> LocStack; @@ -2708,7 +2699,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)) { @@ -2754,9 +2744,6 @@ /// function. void HandleAggregateShadowArgument(const PointerType *PtrArgTy, bool RetPtr) { - // Make sure this call is marked as 'struct return'. - isStructRet = true; - // If the front-end has already made the argument explicit, don't do it // again. if (CALL_EXPR_HAS_RETURN_SLOT_ADDR(CallExpression)) @@ -2807,7 +2794,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 *UnwindBlock = 0; @@ -2897,11 +2885,13 @@ if (!UnwindBlock) { 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, UnwindBlock, CallOperands.begin(), CallOperands.end()); cast<InvokeInst>(Call)->setCallingConv(CallingConvention); + cast<InvokeInst>(Call)->setParamAttrs(PAL); // Lazily create an unwind block for this scope, which we can emit a fixup // branch in. @@ -4361,7 +4351,7 @@ Intrinsic::getDeclaration(TheModule, IntrinsicID); } - Result = EmitCallOf(TargetBuiltinCache[FnCode], exp, DestLoc); + Result = EmitCallOf(TargetBuiltinCache[FnCode], exp, DestLoc, 0); return true; } Modified: llvm-gcc-4.0/trunk/gcc/llvm-internal.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-internal.h?rev=44361&r1=44360&r2=44361&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-internal.h (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-internal.h Tue Nov 27 07:23:49 2007 @@ -138,11 +138,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 @@ -150,7 +151,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); @@ -534,7 +536,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.0/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-types.cpp?rev=44361&r1=44360&r2=44361&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-types.cpp Tue Nov 27 07:23:49 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); } //===----------------------------------------------------------------------===// @@ -812,10 +811,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)) @@ -938,7 +937,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); @@ -960,17 +959,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; @@ -1114,12 +1112,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); } //===----------------------------------------------------------------------===// _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits