[llvm-commits] [llvm-gcc-4.0] r46457 - /llvm-gcc-4.0/trunk/gcc/llvm-types.cpp
Duncan Sands
baldrick at free.fr
Mon Jan 28 11:57:01 PST 2008
Author: baldrick
Date: Mon Jan 28 13:57:01 2008
New Revision: 46457
URL: http://llvm.org/viewvc/llvm-project?rev=46457&view=rev
Log:
Backport the patch turning off readnone/readonly
when there is a byval parameter from 4.2.
Modified:
llvm-gcc-4.0/trunk/gcc/llvm-types.cpp
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=46457&r1=46456&r2=46457&view=diff
==============================================================================
--- llvm-gcc-4.0/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.0/trunk/gcc/llvm-types.cpp Mon Jan 28 13:57:01 2008
@@ -1043,17 +1043,16 @@
// Check for 'readnone' function attribute.
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)
- // Since they write the return value through a pointer,
- // 'sret' functions cannot be 'readonly'.
- if (!ABIConverter.isStructReturn())
- RAttributes |= ParamAttr::ReadOnly;
+ if (flags & ECF_PURE && !(flags & ECF_CONST))
+ 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));
@@ -1082,6 +1081,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.
@@ -1128,13 +1130,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!");
More information about the llvm-commits
mailing list