[llvm-commits] [llvm-gcc-4.0] r46704 - /llvm-gcc-4.0/branches/release_22/gcc/llvm-types.cpp

Tanya Lattner tonic at nondot.org
Sun Feb 3 23:16:42 PST 2008


Author: tbrethou
Date: Mon Feb  4 01:16:40 2008
New Revision: 46704

URL: http://llvm.org/viewvc/llvm-project?rev=46704&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.0/branches/release_22/gcc/llvm-types.cpp

Modified: llvm-gcc-4.0/branches/release_22/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/branches/release_22/gcc/llvm-types.cpp?rev=46704&r1=46703&r2=46704&view=diff

==============================================================================
--- llvm-gcc-4.0/branches/release_22/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.0/branches/release_22/gcc/llvm-types.cpp Mon Feb  4 01:16:40 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