Author: baldrick Date: Mon Nov 19 09:06:19 2007 New Revision: 44231 URL: http://llvm.org/viewvc/llvm-project?rev=44231&view=rev Log: Workaround PR1146 by eliminating silly bitcasting in calls due to disagreements over attributes.
Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp 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=44231&r1=44230&r2=44231&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Mon Nov 19 09:06:19 2007 @@ -33,6 +33,7 @@ #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" @@ -2648,20 +2649,31 @@ Value *Callee = Emit(TREE_OPERAND(exp, 0), 0); - if (TREE_OPERAND(exp, 2)) { - // This is a direct call to a function using a static chain. We need to - // change the function type to one with an extra parameter for the chain. - assert(fndecl && "Indirect static chain call!"); - tree function_type = TYPE_MAIN_VARIANT(TREE_TYPE(fndecl)); - tree static_chain = TREE_OPERAND(exp, 2); - - unsigned CallingConv; - const Type *Ty = TheTypeConverter->ConvertFunctionType(function_type, - fndecl, - static_chain, - CallingConv); - Callee = CastToType(Instruction::BitCast, Callee, PointerType::get(Ty)); - } + // 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 Type *Ty = TheTypeConverter->ConvertFunctionType(function_type, + fndecl, + TREE_OPERAND(exp, 2), + CallingConv); + Callee = BitCastToType(IntrinsicInst::StripPointerCasts(Callee), + PointerType::get(Ty)); //EmitCall(exp, DestLoc); Value *Result = EmitCallOf(Callee, exp, DestLoc); @@ -2857,7 +2869,7 @@ ABIConverter.HandleArgument(TREE_TYPE(TREE_VALUE(arg))); } } - + // Compile stuff like: // %tmp = call float (...)* bitcast (float ()* @foo to float (...)*)( ) // to: _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits