[llvm-commits] [llvm-gcc-4.2] r98407 - in /llvm-gcc-4.2/trunk/gcc: c-common.h c-parser.c cp/parser.c testsuite/g++.apple/block-objectassign.C testsuite/gcc.apple/block-objectassign.c testsuite/gcc.apple/block-struct-return.c

Stuart Hastings stuart at apple.com
Fri Mar 12 17:02:40 PST 2010


Author: stuart
Date: Fri Mar 12 19:02:40 2010
New Revision: 98407

URL: http://llvm.org/viewvc/llvm-project?rev=98407&view=rev
Log:
Repurpose ObjC runtime bit to indicate BLOCK with structure return.  Radar 7735196.  Patch by Fariborz Jahanian!

Added:
    llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-struct-return.c
Modified:
    llvm-gcc-4.2/trunk/gcc/c-common.h
    llvm-gcc-4.2/trunk/gcc/c-parser.c
    llvm-gcc-4.2/trunk/gcc/cp/parser.c
    llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-objectassign.C
    llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-objectassign.c

Modified: llvm-gcc-4.2/trunk/gcc/c-common.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-common.h?rev=98407&r1=98406&r2=98407&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/c-common.h (original)
+++ llvm-gcc-4.2/trunk/gcc/c-common.h Fri Mar 12 19:02:40 2010
@@ -1156,8 +1156,8 @@
      BLOCK_IS_GC =             (1 << 27),
      /* APPLE LOCAL radar 5822844 */
      BLOCK_IS_GLOBAL = 	       (1 << 28),
-     /* APPLE LOCAL radar 5847213 */
-     BLOCK_HAS_DESCRIPTOR =    (1 << 29)
+     /* APPLE LOCAL radar 7735196 */
+     BLOCK_USE_STRET =    (1 << 29)
 };
 
 struct block_sema_info {

Modified: llvm-gcc-4.2/trunk/gcc/c-parser.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-parser.c?rev=98407&r1=98406&r2=98407&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/c-parser.c (original)
+++ llvm-gcc-4.2/trunk/gcc/c-parser.c Fri Mar 12 19:02:40 2010
@@ -9657,7 +9657,7 @@
 /**
  build_block_struct_initlist - builds the initializer list:
  { &_NSConcreteStackBlock or &_NSConcreteGlobalBlock // __isa,
-   BLOCK_HAS_DESCRIPTOR | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL // __flags,
+   BLOCK_USE_STRET | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL // __flags,
    0, // __reserved
    &helper_1, // __FuncPtr,
    &static_descriptor_variable // __descriptor,
@@ -9672,7 +9672,8 @@
 {
   tree initlist, helper_addr;
   tree chain, fields;
-  unsigned int flags = BLOCK_HAS_DESCRIPTOR;
+  /* APPLE LOCAL radar 7735196 */
+  unsigned int flags = 0;
   static tree NSConcreteStackBlock_decl = NULL_TREE;
   static tree NSConcreteGlobalBlock_decl = NULL_TREE;
   tree descriptor_block_decl = build_descriptor_block_decl (block_struct_type, block_impl);
@@ -9682,6 +9683,10 @@
        we have destroy_helper_block/copy_helper_block helper
        routines. */
     flags |= BLOCK_HAS_COPY_DISPOSE;
+  /* APPLE LOCAL begin radar 7735196 */
+  if (block_impl->return_type && aggregate_value_p(block_impl->return_type, 0))
+    flags |= BLOCK_USE_STRET;
+  /* APPLE LOCAL end 7735196 */
 
   fields = TYPE_FIELDS (block_struct_type);
   /* APPLE LOCAL begin radar 6230297 */
@@ -9827,7 +9832,7 @@
  3) build the temporary initialization:
  struct __block_literal_n I = {
    &_NSConcreteStackBlock or &_NSConcreteGlobalBlock // __isa,
-   BLOCK_HAS_DESCRIPTOR | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL // __flags,
+   BLOCK_USE_STRET | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL // __flags,
    0, // __reserved
    &helper_1, // __FuncPtr 
    &static_descriptor_variable // __descriptor,

Modified: llvm-gcc-4.2/trunk/gcc/cp/parser.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/cp/parser.c?rev=98407&r1=98406&r2=98407&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/cp/parser.c (original)
+++ llvm-gcc-4.2/trunk/gcc/cp/parser.c Fri Mar 12 19:02:40 2010
@@ -20871,7 +20871,7 @@
 /**
  build_block_struct_initlist - builds the initializer list:
  { &_NSConcreteStackBlock or &_NSConcreteGlobalBlock // __isa,
-   BLOCK_HAS_DESCRIPTOR | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL // __flags,
+   BLOCK_USE_STRET | BLOCK_HAS_COPY_DISPOSE | BLOCK_IS_GLOBAL // __flags,
    0, // __reserved,
    &helper_1, // __FuncPtr,
    &static_descriptor_variable // __descriptor,
@@ -20888,7 +20888,8 @@
 			     struct block_sema_info *block_impl)
 {
   tree expr, chain, helper_addr;
-  unsigned flags = BLOCK_HAS_DESCRIPTOR;
+  /* APPLE LOCAL radar 7735196 */
+  unsigned flags = 0;
   static tree NSConcreteStackBlock_decl = NULL_TREE;
   static tree NSConcreteGlobalBlock_decl = NULL_TREE;
   VEC(constructor_elt,gc) *impl_v = NULL;
@@ -20904,6 +20905,10 @@
   if (block_impl->BlockImportsCxxObjects)
     flags |= BLOCK_HAS_CXX_OBJ;
   /* APPLE LOCAL end radar 6214617 */
+/* APPLE LOCAL begin radar 7735196 */
+  if (block_impl->return_type && aggregate_value_p(block_impl->return_type, 0))
+    flags |= BLOCK_USE_STRET;
+  /* APPLE LOCAL end 7735196 */
   /* APPLE LOCAL begin radar 6230297 */
   if (!current_function_decl ||
       (block_impl->block_ref_decl_list == NULL_TREE &&

Modified: llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-objectassign.C
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/g%2B%2B.apple/block-objectassign.C?rev=98407&r1=98406&r2=98407&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-objectassign.C (original)
+++ llvm-gcc-4.2/trunk/gcc/testsuite/g++.apple/block-objectassign.C Fri Mar 12 19:02:40 2010
@@ -6,7 +6,6 @@
 
 #include <stdio.h>
 
-#define    BLOCK_HAS_DESCRIPTOR     (1 << 29)
 #define    BLOCK_HAS_COPY_DISPOSE  (1 << 25)
 
 struct Block_descriptor {
@@ -55,10 +54,6 @@
     // should be a copy helper generated with a calls to above routines
     // Lets find out!
     struct Block_layout *bl = (struct Block_layout *)(void *)myBlock;
-    if ((bl->flags & BLOCK_HAS_DESCRIPTOR) != BLOCK_HAS_DESCRIPTOR) {
-        printf("using old runtime layout!\n");
-        return 1;
-    }
     if ((bl->flags & BLOCK_HAS_COPY_DISPOSE) != BLOCK_HAS_COPY_DISPOSE) {
         printf("no copy dispose!!!!\n");
         return 1;

Modified: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-objectassign.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-objectassign.c?rev=98407&r1=98406&r2=98407&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-objectassign.c (original)
+++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-objectassign.c Fri Mar 12 19:02:40 2010
@@ -6,7 +6,6 @@
 
 #include <stdio.h>
 
-#define    BLOCK_HAS_DESCRIPTOR     (1 << 29)
 #define    BLOCK_HAS_COPY_DISPOSE  (1 << 25)
 
 struct Block_descriptor {
@@ -55,10 +54,6 @@
     // should be a copy helper generated with a calls to above routines
     // Lets find out!
     struct Block_layout *bl = (struct Block_layout *)(void *)myBlock;
-    if ((bl->flags & BLOCK_HAS_DESCRIPTOR) != BLOCK_HAS_DESCRIPTOR) {
-        printf("using old runtime layout!\n");
-        return 1;
-    }
     if ((bl->flags & BLOCK_HAS_COPY_DISPOSE) != BLOCK_HAS_COPY_DISPOSE) {
         printf("no copy dispose!!!!\n");
         return 1;

Added: llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-struct-return.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-struct-return.c?rev=98407&view=auto
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-struct-return.c (added)
+++ llvm-gcc-4.2/trunk/gcc/testsuite/gcc.apple/block-struct-return.c Fri Mar 12 19:02:40 2010
@@ -0,0 +1,92 @@
+/* APPLE LOCAL file 7735196 */
+/* { dg-do run { target *-*-darwin[1-2][0-9]* } } */
+/* { dg-options "-fblocks" } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "-m64" } { "" } } */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct bigbig {
+   int array[512];
+   char more[32];
+} BigStruct_t;
+
+BigStruct_t (^global)(void) = ^{ return *(BigStruct_t *)malloc(sizeof(struct bigbig)); };
+
+const char * getBlockSignature(void *);
+ 
+BigStruct_t foo(int param) {
+   BigStruct_t x;
+   BigStruct_t (^f)(int) = ^(int param) {
+     BigStruct_t *result = malloc(sizeof(BigStruct_t));
+     result->array[23] = param;
+     return *result;
+   };
+   getBlockSignature(f);
+   return x;
+}
+
+enum {
+    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
+    BLOCK_HAS_CXX_OBJ =       (1 << 26),
+    BLOCK_IS_GLOBAL =         (1 << 28),
+    BLOCK_USE_STRET =    (1 << 29),
+    BLOCK_HAS_OBJC_TYPE  =    (1 << 30)
+};
+
+struct block_descriptor_big {
+    unsigned long int reserved;
+    unsigned long int size;
+    void (*copy)(void *dst, void *src); // conditional on BLOCK_HAS_COPY_DISPOSE
+    void (*dispose)(void *);            // conditional on BLOCK_HAS_COPY_DISPOSE
+    const char *signature;                  // conditional on BLOCK_HAS_OBJC
+    const char *layout;                 // conditional on BLOCK_HAS_OBJC
+};
+struct block_descriptor_small {
+    unsigned long int reserved;
+    unsigned long int size;
+    const char *signature;              // conditional on BLOCK_HAS_OBJC
+    const char *layout;                 // conditional on BLOCK_HAS_OBJC
+};
+
+struct block_layout_abi { // can't change
+  void *isa;
+  int flags;
+  int reserved; 
+  void (*invoke)(void *, ...);
+  struct block_descriptor_big *descriptor;
+};
+
+const char *getBlockSignature(void *block) {
+   struct block_layout_abi *layout = (struct block_layout_abi *)block;
+   if (layout->flags & BLOCK_HAS_COPY_DISPOSE) 
+      return layout->descriptor->signature;
+   else
+      return ((struct block_descriptor_small *)layout->descriptor)->signature;
+}
+
+int usesStruct(void *block) {
+   struct block_layout_abi *layout = (struct block_layout_abi *)block;
+   int want = BLOCK_USE_STRET;
+   return (layout->flags & want) == want;
+}
+    
+   
+int main(int argc, char *argv[]) {
+   printf("desired global flags: %d\n", BLOCK_USE_STRET | BLOCK_IS_GLOBAL  );
+   printf("desired stack flags: %d\n",  BLOCK_USE_STRET );
+   
+   if (!usesStruct(global))
+     return 1;
+   BigStruct_t x;
+   BigStruct_t (^local)(int) = ^(int param) {
+     BigStruct_t *result = (BigStruct_t *)malloc(sizeof(BigStruct_t));
+     result->array[23] = argc;
+     return *result;
+   };
+   if (!usesStruct(global))
+     return 1;
+   if (usesStruct(^void(int x){ }))
+     return 1;
+   return 0;
+}





More information about the llvm-commits mailing list