[arm] Tweak C++ guard variables

Paul Brook paul@codesourcery.com
Thu Jun 24 18:45:00 GMT 2004


The patch below changes guard variables for static one-time construction in 
line with the arm c++ eabi.
It consists of two changes:
- The guard variable is a (32-bit) int, not long long.
- It sets/tests the least significant bit, rather than the first byte.

Technically the g++ and libstdc++ changes are independent because the compiler 
doesn't use the helper function, but it makes sense to keep them in sync.

I've enabled the changes unconditionally (on arm targets). I'm not sure if 
this is desirable, or if they should only be enables when an eabi based abi 
is used.

I'm also going to be making similar changes for array cookies.

Tested on i686-linux and cross to arm-none-elf.
Ok?

Paul

2004-06-24  Paul Brook  <paul@codesourcery.com>

gcc/
	* target-def.h (TARGET_CXX_GUARD_TYPE, TARGET_CXX_GUARD_MASK_BIT,
	TARGET_CXX): Define.
	(TARGET_INITIALIZER): Use TARGET_CXX.
	* target.h (struct gcc_target): Add struct cxx.
	* targhooks.h (default_cxx_guard_type): Add prototype.
	* targhooks.c (default_cxx_guard_type): New function.
	* config/arm/arm.c (TARGET_CXX_GUARD_TYPE, TARGET_CXX_GUARD_MASK_BIT):
	Define.
	(arm_cxx_guard_type, arm_cxx_guard_mask_bit): New functions.
gcc/cp/
	* decl2.c (get_guard): Call targetm.cxx.guard_type.
	(get_guard_bits, get_guard_cond): Call targetm.cxx.guard_mask_bit.
libstdc++/
	* libsupc++/cxxabi.h: Define __ARM_EABI__
	(__guard): Use it.
	* libsupc++/guard.h (__cxa_guard_acquire, __cxa_guard_release): Ditto.

Index: gcc/target-def.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/target-def.h,v
retrieving revision 1.80
diff -u -p -r1.80 target-def.h
--- gcc/target-def.h	20 Jun 2004 08:34:44 -0000	1.80
+++ gcc/target-def.h	24 Jun 2004 13:08:15 -0000
@@ -390,6 +390,22 @@ Foundation, 59 Temple Place - Suite 330,
 #define TARGET_HANDLE_PRAGMA_EXTERN_PREFIX 0
 #endif
 
+
+/* C++ specific.  */
+#ifndef TARGET_CXX_GUARD_TYPE
+#define TARGET_CXX_GUARD_TYPE default_cxx_guard_type
+#endif
+
+#ifndef TARGET_CXX_GUARD_MASK_BIT
+#define TARGET_CXX_GUARD_MASK_BIT hook_bool_void_false
+#endif
+
+#define TARGET_CXX		\
+  {				\
+    TARGET_CXX_GUARD_TYPE,	\
+    TARGET_CXX_GUARD_MASK_BIT	\
+  }
+
 /* The whole shebang.  */
 #define TARGET_INITIALIZER			\
 {						\
@@ -435,6 +451,7 @@ Foundation, 59 Temple Place - Suite 330,
   TARGET_BUILTIN_SETJMP_FRAME_VALUE,		\
   TARGET_MD_ASM_CLOBBERS,			\
   TARGET_CALLS,					\
+  TARGET_CXX,					\
   TARGET_HAVE_NAMED_SECTIONS,			\
   TARGET_HAVE_CTORS_DTORS,			\
   TARGET_HAVE_TLS,				\
Index: gcc/target.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/target.h,v
retrieving revision 1.92
diff -u -p -r1.92 target.h
--- gcc/target.h	20 Jun 2004 08:34:44 -0000	1.92
+++ gcc/target.h	24 Jun 2004 14:14:53 -0000
@@ -476,6 +476,14 @@ struct gcc_target
 				   tree *post_p);
   } calls;
 
+  /* Functions specific to the C++ frontend.  */
+  struct cxx {
+    /* Return the integer type used for guard variables.  */
+    tree (*guard_type) (void);
+    /* Return true if only the low bit of the guard should be tested.  */
+    bool (*guard_mask_bit) (void);
+  } cxx;
+
   /* Leave the boolean fields at the end.  */
 
   /* True if arbitrary sections are supported.  */
Index: gcc/targhooks.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/targhooks.c,v
retrieving revision 2.21
diff -u -p -r2.21 targhooks.c
--- gcc/targhooks.c	24 Jun 2004 06:10:35 -0000	2.21
+++ gcc/targhooks.c	24 Jun 2004 14:21:46 -0000
@@ -135,3 +135,11 @@ hook_bool_CUMULATIVE_ARGS_true (CUMULATI
 {
   return true;
 }
+
+
+/* The generic C++ ABI specifies this is a 64-bit value.  */
+tree
+default_cxx_guard_type (void)
+{
+  return long_long_integer_type_node;
+}
Index: gcc/targhooks.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/targhooks.h,v
retrieving revision 2.12
diff -u -p -r2.12 targhooks.h
--- gcc/targhooks.h	2 Mar 2004 22:32:26 -0000	2.12
+++ gcc/targhooks.h	24 Jun 2004 11:54:05 -0000
@@ -32,3 +32,4 @@ extern bool hook_bool_CUMULATIVE_ARGS_fa
 extern bool default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);
 
 extern bool hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS *);
+extern tree default_cxx_guard_type (void);
Index: gcc/config/arm/arm.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.366
diff -u -p -r1.366 arm.c
--- gcc/config/arm/arm.c	24 Jun 2004 11:01:56 -0000	1.366
+++ gcc/config/arm/arm.c	24 Jun 2004 13:21:09 -0000
@@ -162,6 +162,9 @@ static bool arm_promote_prototypes (tree
 static bool arm_default_short_enums (void);
 static bool arm_align_anon_bitfield (void);
 
+static tree arm_cxx_guard_type (void);
+static bool arm_cxx_guard_mask_bit (void);
+
 
 /* Initialize the GCC target structure.  */
 #ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
@@ -264,6 +267,12 @@ static bool arm_align_anon_bitfield (voi
 #undef TARGET_ALIGN_ANON_BITFIELD
 #define TARGET_ALIGN_ANON_BITFIELD arm_align_anon_bitfield
 
+#undef TARGET_CXX_GUARD_TYPE
+#define TARGET_CXX_GUARD_TYPE arm_cxx_guard_type
+
+#undef TARGET_CXX_GUARD_MASK_BIT
+#define TARGET_CXX_GUARD_MASK_BIT arm_cxx_guard_mask_bit
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Obstack for minipool constant handling.  */
@@ -14506,3 +14515,15 @@ arm_align_anon_bitfield (void)
 {
   return TARGET_AAPCS_BASED;
 }
+
+static tree
+arm_cxx_guard_type (void)
+{
+  return integer_type_node;
+}
+
+static bool
+arm_cxx_guard_mask_bit (void)
+{
+  return TRUE;
+}
Index: gcc/cp/decl2.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/cp/decl2.c,v
retrieving revision 1.719
diff -u -p -r1.719 decl2.c
--- gcc/cp/decl2.c	24 Jun 2004 06:48:43 -0000	1.719
+++ gcc/cp/decl2.c	24 Jun 2004 13:25:38 -0000
@@ -1823,7 +1823,7 @@ get_guard (tree decl)
 
       /* We use a type that is big enough to contain a mutex as well
 	 as an integer counter.  */
-      guard_type = long_long_integer_type_node;
+      guard_type = targetm.cxx.guard_type ();
       guard = build_decl (VAR_DECL, sname, guard_type);
       
       /* The guard should have the same linkage as what it guards.  */
@@ -1847,15 +1847,18 @@ get_guard (tree decl)
 static tree
 get_guard_bits (tree guard)
 {
-  /* We only set the first byte of the guard, in order to leave room
-     for a mutex in the high-order bits.  */
-  guard = build1 (ADDR_EXPR, 
-		  build_pointer_type (TREE_TYPE (guard)),
-		  guard);
-  guard = build1 (NOP_EXPR, 
-		  build_pointer_type (char_type_node), 
-		  guard);
-  guard = build1 (INDIRECT_REF, char_type_node, guard);
+  if (!targetm.cxx.guard_mask_bit ())
+    {
+      /* We only set the first byte of the guard, in order to leave room
+	 for a mutex in the high-order bits.  */
+      guard = build1 (ADDR_EXPR, 
+		      build_pointer_type (TREE_TYPE (guard)),
+		      guard);
+      guard = build1 (NOP_EXPR, 
+		      build_pointer_type (char_type_node), 
+		      guard);
+      guard = build1 (INDIRECT_REF, char_type_node, guard);
+    }
 
   return guard;
 }
@@ -1870,6 +1873,16 @@ get_guard_cond (tree guard)
 
   /* Check to see if the GUARD is zero.  */
   guard = get_guard_bits (guard);
+
+  /* Mask off all but the low bit.  */
+  if (targetm.cxx.guard_mask_bit ())
+    {
+      guard_value = integer_one_node;
+      if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
+	guard_value = convert (TREE_TYPE (guard), guard_value);
+	guard = cp_build_binary_op (BIT_AND_EXPR, guard, guard_value);
+    }
+
   guard_value = integer_zero_node;
   if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
     guard_value = convert (TREE_TYPE (guard), guard_value);
Index: libstdc++-v3/libsupc++/cxxabi.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/libstdc++-v3/libsupc++/cxxabi.h,v
retrieving revision 1.16
diff -u -p -r1.16 cxxabi.h
--- libstdc++-v3/libsupc++/cxxabi.h	22 May 2004 21:07:28 -0000	1.16
+++ libstdc++-v3/libsupc++/cxxabi.h	24 Jun 2004 14:32:52 -0000
@@ -44,6 +44,11 @@
 
 #include <stddef.h>
  
+/* ??? We should probably define this in the compiler.  */
+#if defined(__arm__) && !defined(__ARM_EABI__)
+#define __ARM_EABI__
+#endif
+
 #ifdef __cplusplus
 namespace __cxxabiv1
 {  
@@ -105,7 +110,11 @@ namespace __cxxabiv1
 		    void (*__dealloc) (void*, size_t));
 
   // The ABI requires a 64-bit type.
+#ifdef __ARM_EABI__
+  typedef int __guard;
+#else
   __extension__ typedef int __guard __attribute__((mode (__DI__)));
+#endif
 
   int 
   __cxa_guard_acquire(__guard*);
Index: libstdc++-v3/libsupc++/guard.cc
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/libstdc++-v3/libsupc++/guard.cc,v
retrieving revision 1.1
diff -u -p -r1.1 guard.cc
--- libstdc++-v3/libsupc++/guard.cc	25 Nov 2002 23:17:31 -0000	1.1
+++ libstdc++-v3/libsupc++/guard.cc	24 Jun 2004 13:13:36 -0000
@@ -35,13 +35,21 @@ namespace __cxxabiv1 
   extern "C"
   int __cxa_guard_acquire (__guard *g) 
   {
+#ifdef __ARM_EABI__
+    return !(*g & 1);
+#else
     return !*(char *)(g);
+#endif
   }
 
   extern "C"
   void __cxa_guard_release (__guard *g)
   {
+#ifdef __ARM_EABI__
+    *g = 1;
+#else
     *(char *)g = 1;
+#endif
   }
 
   extern "C"



More information about the Libstdc++ mailing list