Author: tbrethou Date: Mon Feb 4 01:03:17 2008 New Revision: 46703 URL: http://llvm.org/viewvc/llvm-project?rev=46703&view=rev Log: Patch to not turn gcc's pure/const markings into readonly/readnone if a parameter has a byval attribute.
Modified: llvm-gcc-4.2/branches/release_22/gcc/llvm-types.cpp Modified: llvm-gcc-4.2/branches/release_22/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/release_22/gcc/llvm-types.cpp?rev=46703&r1=46702&r2=46703&view=diff ============================================================================== --- llvm-gcc-4.2/branches/release_22/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/branches/release_22/gcc/llvm-types.cpp Mon Feb 4 01:03:17 2008 @@ -1123,18 +1123,17 @@ // accepts it). But llvm IR does not allow both, so // set only ReadNone. if (flags & ECF_CONST) - // Since they write the return value through a pointer, - // 'sret' functions cannot be 'readnone'. - if (!ABIConverter.isStructReturn()) - RAttributes |= ParamAttr::ReadNone; + RAttributes |= ParamAttr::ReadNone; // Check for 'readonly' function attribute. if (flags & ECF_PURE && !(flags & ECF_CONST)) - // Since they write the return value through a pointer, - // 'sret' functions cannot be 'readonly'. - if (!ABIConverter.isStructReturn()) - RAttributes |= ParamAttr::ReadOnly; + RAttributes |= ParamAttr::ReadOnly; + // Since they write the return value through a pointer, + // 'sret' functions cannot be 'readnone' or 'readonly'. + if (ABIConverter.isStructReturn()) + RAttributes &= ~(ParamAttr::ReadNone|ParamAttr::ReadOnly); + // Compute whether the result needs to be zext or sext'd. RAttributes |= HandleArgumentExtension(TREE_TYPE(type)); @@ -1162,6 +1161,9 @@ LLVM_TARGET_INIT_REGPARM(local_regparam, type); #endif // LLVM_TARGET_ENABLE_REGPARM + // Keep track of whether we see a byval argument. + bool HasByVal = false; + // Check if we have a corresponding decl to inspect. tree DeclArgs = (decl) ? DECL_ARGUMENTS(decl) : NULL; // Loop over all of the arguments, adding them as we go. @@ -1208,13 +1210,27 @@ local_regparam); #endif // LLVM_TARGET_ENABLE_REGPARM - if (Attributes != ParamAttr::None) + if (Attributes != ParamAttr::None) { + HasByVal |= Attributes & ParamAttr::ByVal; Attrs.push_back(ParamAttrsWithIndex::get(ArgTypes.size(), Attributes)); + } if (DeclArgs) DeclArgs = TREE_CHAIN(DeclArgs); } + // If there is a byval argument then it is not safe to mark the function + // 'readnone' or 'readonly': gcc permits a 'const' or 'pure' function to + // write to struct arguments passed by value, but in LLVM this becomes a + // write through the byval pointer argument, which LLVM does not allow for + // readonly/readnone functions. + if (HasByVal && Attrs[0].index == 0) { + uint16_t &RAttrs = Attrs[0].attrs; + RAttrs &= ~(ParamAttr::ReadNone | ParamAttr::ReadOnly); + if (RAttrs == ParamAttr::None) + Attrs.erase(Attrs.begin()); + } + // If the argument list ends with a void type node, it isn't vararg. isVarArg = (Args == 0); assert(RetTy && "Return type not specified!"); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits