This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[named-addr-spaces-branch][PATCH, committed] Work on conversions of named address space pointers


This patch adds the ability of the backend to say whether you can convert from
one named address to another.  It also makes sure that TYPE_ADDR is correct for
arrays in a named address space, and allows me to remove a lot of the calls to
strip_array_types.  I still have a failure in cache64.c, so it is not the final
set of patches.

2008-11-26  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* targhooks.h (default_addr_space_can_convert_p): New
	declaration.
	(default_addr_space_nop_convert_p): Ditto.

	* targhooks.c (default_addr_space_can_convert_p): New default
	target hook for named address spaces.
	(default_addr_space_nop_convert_p): Ditto.

	* tree.c (build_pointer_type): Remove strip_array_types call.
	(build_array_type): Set the address space in the ARRAY_TYPE node.

	* tree.h (TYPE_QUALS): Remote strip_array_types call.

	* target.h (struct addr_space): Add target hooks for determining
	if you can convert from a pointer in one named address to another
	named address, and if the conversion is a NOP.

	* c-objc-common (c_initialize_diagnostics): Delete
	strip_array_types call from TYPE_ADDR_SPACE macro.

	* dwarf2out.c (modified_type_die): Delete strip_array_types call
	from TYPE_ADDR_SPACE macro.

	* emit-rtl.c (set__mem_attributes_minus_bitpos): Delete
	strip_array_types call from TYPE_ADDR_SPACE macro.

	* c-decl.c (start_decl): Delete strip_array_types call from
	TYPE_ADDR_SPACE macro.
	(grokdeclarator): If an array is in a named address space, use a
	qualified type that marks the address space.

	* print-tree.c (print_node_brief): Print non-zero address spaces.
	(print_node): Ditto.

	* target-def.h (TARGET_ADDR_SPACE_CAN_CONVERT_P): New target hook.
	(TARGET_ADDR_SPACE_NOP_CONVERT_P): Ditto.
	(TARGET_ADDR_SPACE_HOOKS): Add new hooks.

	* c-parser.c (c_parser_postfix_expression_after_paren_): Delete
	strip_array_types call from TYPE_ADDR_SPACE macro.

	* config/spu/spu.c (spu_addr_space_can_convert_p): New target hook
	for named address space support.
	(spu_addr_space_nop_convert_p): Ditto.
	(ea_symbol_ref): Delete strip_array_types call from
	TYPE_ADDR_SPACE macro.

	* convert (convert_to_pointer): Check if the backend allows
	converting a pointer from one named address to another named
	address, and if it does allow the conversion, whether the
	conversion is a NOP or real conversion.  Rewrite conversion of
	integer to pointer for named address spaces.
	(convert_to_integer): Rewrite named address space conversion code
	to adhere to GNU coding standards.

	* doc/tm.texi (TARGET_ADDR_SPACE_CAN_CONVERT_P): Document new
	hook.
	(TARGET_ADDR_SPACE_NOP_CONVERT_P): Ditto.

Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 142168)
+++ gcc/doc/tm.texi	(working copy)
@@ -9650,6 +9650,19 @@ targets that do not support named addres
 of this hook will cause the compiler to abort.
 @end deftypefn
 
+@deftypefn {Target Hook} {bool} TARGET_ADDR_SPACE_CAN_CONVERT_P (addr_space_t @var{from}, addr_space_t @var{to})
+Define this to return whether a pointer which points to the @var{from}
+named address space can be converted to a pointer which points to the
+@var{to} named address space.
+@end deftypefn
+
+@deftypefn {Target Hook} {bool} TARGET_ADDR_SPACE_NOP_CONVERT_P (addr_space_t @var{from}, addr_space_t @var{to})
+Define this to return whether converting a pointer which points to the
+@var{from} named address space to a pointer which points to the
+@var{to} named address space can be done as a simple copy or if a real
+conversion needs to be done.
+@end deftypefn
+
 @deftypefn {Target Hook} {rtx} TARGET_ADDR_SPACE_CONVERT (rtx @var{op}, enum machine_mode @var{mode}, addr_space_t @var{from}, addr_space_t @var{to})
 Define this to convert the pointer expression represented by the RTL
 @var{op} that points to the named address space @var{from} to a new
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c	(revision 142168)
+++ gcc/targhooks.c	(working copy)
@@ -721,6 +721,24 @@ default_addr_space_name (addr_space_t ad
   gcc_unreachable ();
 }
 
+/* The default hook for determining whether you can convert from one address
+   space to another.  */
+
+bool
+default_addr_space_can_convert_p (addr_space_t to_addr, addr_space_t from_addr)
+{
+  return to_addr == from_addr;
+}
+
+/* The default hook for determining whether convert from one address space to
+   another is a NOP.  */
+
+bool
+default_addr_space_nop_convert_p (addr_space_t to_addr, addr_space_t from_addr)
+{
+  return to_addr == from_addr;
+}
+
 /* The default hook for TARGET_ADDR_SPACE_CONVERT. This hook should never be
    called for targets with only a generic address space.  */
 
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h	(revision 142168)
+++ gcc/targhooks.h	(working copy)
@@ -108,4 +108,6 @@ extern const char *default_addr_space_na
 extern unsigned char default_addr_space_number (const_tree);
 extern rtx default_addr_space_convert (rtx, enum machine_mode, addr_space_t,
 				       addr_space_t);
+extern bool default_addr_space_can_convert_p (addr_space_t, addr_space_t);
+extern bool default_addr_space_nop_convert_p (addr_space_t, addr_space_t);
 extern tree default_addr_space_section_name (addr_space_t);
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 142168)
+++ gcc/tree.c	(working copy)
@@ -5572,7 +5572,7 @@ build_pointer_type_for_mode (tree to_typ
 tree
 build_pointer_type (tree to_type)
 {
-  addr_space_t addr_space = TYPE_ADDR_SPACE (strip_array_types (to_type));
+  addr_space_t addr_space = TYPE_ADDR_SPACE (to_type);
   enum machine_mode mode = targetm.addr_space.pointer_mode (addr_space);
   return build_pointer_type_for_mode (to_type, mode, false);
 }
@@ -5781,6 +5781,7 @@ build_array_type (tree elt_type, tree in
   t = make_node (ARRAY_TYPE);
   TREE_TYPE (t) = elt_type;
   TYPE_DOMAIN (t) = index_type;
+  TYPE_ADDR_SPACE (t) = TYPE_ADDR_SPACE (elt_type);
   
   if (index_type == 0)
     {
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 142168)
+++ gcc/tree.h	(working copy)
@@ -2208,7 +2208,7 @@ struct tree_block GTY(())
   ((TYPE_READONLY (NODE) * TYPE_QUAL_CONST)			\
    | (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE)		\
    | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT)		\
-   | (ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (strip_array_types (NODE)))))
+   | (ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (NODE))))
 
 /* These flags are available for each language front end to use internally.  */
 #define TYPE_LANG_FLAG_0(NODE) (TYPE_CHECK (NODE)->type.lang_flag_0)
Index: gcc/target.h
===================================================================
--- gcc/target.h	(revision 142168)
+++ gcc/target.h	(working copy)
@@ -673,6 +673,14 @@ struct gcc_target
     /* Function to map an address space to a small number.  */
     addr_space_t (* number) (const_tree);
 
+    /* True if it is legal to convert a pointer of one address space to
+       another.  */
+    bool (* can_convert_p) (addr_space_t, addr_space_t);
+
+    /* True if converting a pointer of one address space to another is just a
+       NOP.  */
+    bool (* nop_convert_p) (addr_space_t, addr_space_t);
+
     /* Function to convert an rtl expression from one address space to
        another.  */
     rtx (* convert) (rtx, enum machine_mode, addr_space_t, addr_space_t);
Index: gcc/c-objc-common.c
===================================================================
--- gcc/c-objc-common.c	(revision 142168)
+++ gcc/c-objc-common.c	(working copy)
@@ -187,8 +187,7 @@ c_initialize_diagnostics (diagnostic_con
 int
 c_types_compatible_p (tree x, tree y)
 {
-  if (TYPE_ADDR_SPACE (strip_array_types (x))
-      != TYPE_ADDR_SPACE (strip_array_types (y)))
+  if (TYPE_ADDR_SPACE (x) != TYPE_ADDR_SPACE (y))
     return false;
 
   return comptypes (TYPE_MAIN_VARIANT (x), TYPE_MAIN_VARIANT (y));
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 142168)
+++ gcc/dwarf2out.c	(working copy)
@@ -9563,7 +9563,7 @@ modified_type_die (tree type, int is_con
       add_AT_unsigned (mod_type_die, DW_AT_byte_size,
 		       simple_type_size_in_bits (type) / BITS_PER_UNIT);
       item_type = TREE_TYPE (type);
-      if (TYPE_ADDR_SPACE (strip_array_types (item_type)))
+      if (TYPE_ADDR_SPACE (item_type))
 	add_AT_unsigned (mod_type_die, DW_AT_address_class,
 			 TYPE_ADDR_SPACE (item_type));
     }
@@ -9573,7 +9573,7 @@ modified_type_die (tree type, int is_con
       add_AT_unsigned (mod_type_die, DW_AT_byte_size,
 		       simple_type_size_in_bits (type) / BITS_PER_UNIT);
       item_type = TREE_TYPE (type);
-      if (TYPE_ADDR_SPACE (strip_array_types (item_type)))
+      if (TYPE_ADDR_SPACE (item_type))
 	add_AT_unsigned (mod_type_die, DW_AT_address_class,
 			 TYPE_ADDR_SPACE (item_type));
     }
Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c	(revision 142206)
+++ gcc/c-decl.c	(working copy)
@@ -3294,7 +3294,7 @@ start_decl (struct c_declarator *declara
 
   if (TREE_CODE (decl) == VAR_DECL
       && TREE_TYPE (decl) != error_mark_node
-      && (addrspace = TYPE_ADDR_SPACE (strip_array_types (TREE_TYPE (decl))))
+      && (addrspace = TYPE_ADDR_SPACE (TREE_TYPE (decl)))
       && (declspecs->storage_class == csc_static
 	  || (declspecs->storage_class == csc_none
 	      && !current_function_scope)
@@ -4480,7 +4480,14 @@ grokdeclarator (const struct c_declarato
 	       it, but here we want to make sure we don't ever
 	       modify the shared type, so we gcc_assert (itype)
 	       below.  */
-	      type = build_array_type (type, itype);
+	      {
+		addr_space_t as = DECODE_QUAL_ADDR_SPACE (type_quals);
+		if (as && as != TYPE_ADDR_SPACE (type))
+		  type = build_qualified_type (type,
+					       ENCODE_QUAL_ADDR_SPACE (as));
+
+		type = build_array_type (type, itype);
+	      }
 
 	    if (type != error_mark_node)
 	      {
Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c	(revision 142168)
+++ gcc/emit-rtl.c	(working copy)
@@ -1758,7 +1758,7 @@ set_mem_attributes_minus_bitpos (rtx ref
   /* Now set the attributes we computed above.  */
   MEM_ATTRS (ref)
     = get_mem_attrs (alias, expr, offset, size, align,
-		     TYPE_ADDR_SPACE (strip_array_types (type)),
+		     TYPE_ADDR_SPACE (type),
 		     GET_MODE (ref));
 
   /* If this is already known to be a scalar or aggregate, we are done.  */
Index: gcc/print-tree.c
===================================================================
--- gcc/print-tree.c	(revision 142168)
+++ gcc/print-tree.c	(working copy)
@@ -110,6 +110,8 @@ print_node_brief (FILE *file, const char
 	    fprintf (file, " %s",
 		     IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))));
 	}
+      if (TYPE_ADDR_SPACE (node))
+	fprintf (file, " address-space-%d", TYPE_ADDR_SPACE (node));
     }
   if (TREE_CODE (node) == IDENTIFIER_NODE)
     fprintf (file, " %s", IDENTIFIER_POINTER (node));
@@ -299,6 +301,9 @@ print_node (FILE *file, const char *pref
   else if (TYPE_P (node) && TYPE_SIZES_GIMPLIFIED (node))
     fputs (" sizes-gimplified", file);
 
+  if (TYPE_P (node) && TYPE_ADDR_SPACE (node))
+    fprintf (file, " address-space-%d", TYPE_ADDR_SPACE (node));
+
   if (TREE_ADDRESSABLE (node))
     fputs (" addressable", file);
   if (TREE_THIS_VOLATILE (node))
Index: gcc/target-def.h
===================================================================
--- gcc/target-def.h	(revision 142168)
+++ gcc/target-def.h	(working copy)
@@ -469,6 +469,14 @@
 #define TARGET_ADDR_SPACE_NUMBER default_addr_space_number
 #endif
 
+#ifndef TARGET_ADDR_SPACE_CAN_CONVERT_P
+#define TARGET_ADDR_SPACE_CAN_CONVERT_P default_addr_space_can_convert_p
+#endif
+
+#ifndef TARGET_ADDR_SPACE_NOP_CONVERT_P
+#define TARGET_ADDR_SPACE_NOP_CONVERT_P default_addr_space_nop_convert_p
+#endif
+
 #ifndef TARGET_ADDR_SPACE_CONVERT
 #define TARGET_ADDR_SPACE_CONVERT default_addr_space_convert
 #endif
@@ -486,6 +494,8 @@
     TARGET_ADDR_SPACE_POINTER_MODE,		\
     TARGET_ADDR_SPACE_NAME,			\
     TARGET_ADDR_SPACE_NUMBER,			\
+    TARGET_ADDR_SPACE_CAN_CONVERT_P,		\
+    TARGET_ADDR_SPACE_NOP_CONVERT_P,		\
     TARGET_ADDR_SPACE_CONVERT,			\
     TARGET_ADDR_SPACE_VALID_P,			\
     TARGET_ADDR_SPACE_SECTION_NAME,		\
Index: gcc/c-parser.c
===================================================================
--- gcc/c-parser.c	(revision 142168)
+++ gcc/c-parser.c	(working copy)
@@ -5547,7 +5547,7 @@ c_parser_postfix_expression_after_paren_
   maybe_warn_string_init (type, init);
 
   if (type != error_mark_node
-      && TYPE_ADDR_SPACE (strip_array_types (type))
+      && TYPE_ADDR_SPACE (type)
       && current_function_decl)
     {
       error ("compound literal qualified by address-space qualifier");
Index: gcc/config/spu/spu.c
===================================================================
--- gcc/config/spu/spu.c	(revision 142206)
+++ gcc/config/spu/spu.c	(working copy)
@@ -222,6 +222,14 @@ static unsigned char spu_addr_space_numb
 #undef TARGET_ADDR_SPACE_NUMBER
 #define TARGET_ADDR_SPACE_NUMBER spu_addr_space_number
 
+static bool spu_addr_space_can_convert_p (addr_space_t, addr_space_t);
+#undef TARGET_ADDR_SPACE_CAN_CONVERT_P
+#define TARGET_ADDR_SPACE_CAN_CONVERT_P spu_addr_space_can_convert_p
+
+static bool spu_addr_space_nop_convert_p (addr_space_t, addr_space_t);
+#undef TARGET_ADDR_SPACE_NOP_CONVERT_P
+#define TARGET_ADDR_SPACE_NOP_CONVERT_P spu_addr_space_nop_convert_p
+
 static rtx spu_addr_space_convert (rtx, enum machine_mode, addr_space_t,
 				   addr_space_t);
 #undef TARGET_ADDR_SPACE_CONVERT
@@ -3481,7 +3489,7 @@ ea_symbol_ref (rtx *px, void *data ATTRI
   return (GET_CODE (x) == SYMBOL_REF
  	  && (decl = SYMBOL_REF_DECL (x)) != 0
  	  && TREE_CODE (decl) == VAR_DECL
- 	  && TYPE_ADDR_SPACE (strip_array_types (TREE_TYPE (decl))));
+ 	  && TYPE_ADDR_SPACE (TREE_TYPE (decl)));
 }
 
 /* We accept:
@@ -6618,6 +6626,28 @@ spu_addr_space_name (addr_space_t addrsp
   gcc_unreachable ();
 }
 
+/* Determine if you can convert one address to another.  */
+
+static bool
+spu_addr_space_can_convert_p (addr_space_t from,
+			      addr_space_t to)
+{
+  gcc_assert (from == ADDR_SPACE_GENERIC || from == ADDR_SPACE_EA);
+  gcc_assert (to == ADDR_SPACE_GENERIC || to == ADDR_SPACE_EA);
+  return true;
+}
+
+/* Determine if converting one address to another is a NOP.  */
+
+static bool
+spu_addr_space_nop_convert_p (addr_space_t from,
+			      addr_space_t to)
+{
+  gcc_assert (from == ADDR_SPACE_GENERIC || from == ADDR_SPACE_EA);
+  gcc_assert (to == ADDR_SPACE_GENERIC || to == ADDR_SPACE_EA);
+  return (to == from);
+}
+
 /* Convert from one address space to another.  */
 static rtx
 spu_addr_space_convert (rtx op,
@@ -6627,6 +6657,9 @@ spu_addr_space_convert (rtx op,
 {
   rtx reg;
 
+  gcc_assert (from == ADDR_SPACE_GENERIC || from == ADDR_SPACE_EA);
+  gcc_assert (to == ADDR_SPACE_GENERIC || to == ADDR_SPACE_EA);
+
   if (to == from)
     return op;
 
Index: gcc/convert.c
===================================================================
--- gcc/convert.c	(revision 142168)
+++ gcc/convert.c	(working copy)
@@ -43,6 +43,11 @@ along with GCC; see the file COPYING3.  
 tree
 convert_to_pointer (tree type, tree expr)
 {
+  addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (type));
+  addr_space_t from_as;
+  enum tree_code tcode;
+  int pointer_size;
+
   if (TREE_TYPE (expr) == type)
     return expr;
 
@@ -54,21 +59,39 @@ convert_to_pointer (tree type, tree expr
     {
     case POINTER_TYPE:
     case REFERENCE_TYPE:
-      return fold_build1 (NOP_EXPR, type, expr);
+      /* If the pointers point to different address spaces, see if we can do the
+	 convert, and if we can do the convert, whether the conversion is a NOP
+	 or not.  */
+      tcode = NOP_EXPR;
+      from_as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
+      if (to_as != from_as)
+	{
+	  if (! targetm.addr_space.can_convert_p (from_as, to_as))
+	    {
+	      error ("cannot convert %s address space pointers to "
+		     "%s address space pointers",
+		     targetm.addr_space.name (from_as),
+		     targetm.addr_space.name (to_as));
+	      return convert_to_pointer (type, integer_zero_node);
+	    }
+
+	  if (! targetm.addr_space.nop_convert_p (from_as, to_as))
+	    tcode = CONVERT_EXPR;
+	}
+      return fold_build1 (tcode, type, expr);
 
     case INTEGER_TYPE:
     case ENUMERAL_TYPE:
     case BOOLEAN_TYPE:
-    {
-      int pointer_size =
-	TYPE_ADDR_SPACE (TREE_TYPE (type))
-	? GET_MODE_BITSIZE (targetm.addr_space.pointer_mode (TYPE_ADDR_SPACE (TREE_TYPE (type))))
-	: POINTER_SIZE;
+      /* Figure out the native pointer size, depending on the address space.  */
+      pointer_size = (!to_as
+		      ? POINTER_SIZE
+		      : GET_MODE_BITSIZE (targetm.addr_space.pointer_mode (to_as))); 
 
       if (TYPE_PRECISION (TREE_TYPE (expr)) != pointer_size)
 	expr = fold_build1 (NOP_EXPR, lang_hooks.types.type_for_size (pointer_size, 0), expr);
-    }
-    return fold_build1 (CONVERT_EXPR, type, expr);
+
+      return fold_build1 (CONVERT_EXPR, type, expr);
 
 
     default:
@@ -488,16 +511,22 @@ convert_to_integer (tree type, tree expr
     case REFERENCE_TYPE:
       {
  	int pointer_size;
+	addr_space_t as;
 
  	if (integer_zerop (expr))
  	  return build_int_cst (type, 0);
 
  	/* Convert to an unsigned integer of the correct width first,
  	   and from there widen/truncate to the required type.  */
- 	pointer_size =
- 	  TYPE_ADDR_SPACE (strip_array_types (TREE_TYPE (intype)))
-	  ? GET_MODE_BITSIZE (targetm.addr_space.pointer_mode (TYPE_ADDR_SPACE (TREE_TYPE (intype))))
- 	  : POINTER_SIZE;
+	as = TYPE_ADDR_SPACE (intype);
+	if (!as)
+	  pointer_size = POINTER_SIZE;
+
+	else
+	  {
+	    enum machine_mode mode = targetm.addr_space.pointer_mode (as);
+	    pointer_size = GET_MODE_BITSIZE (mode);
+	  }
 
  	expr = fold_build1 (CONVERT_EXPR,
  			    lang_hooks.types.type_for_size (pointer_size, 0),

-- 
Michael Meissner, IBM
4 Technology Place Drive, MS 2203A, Westford, MA, 01886, USA
meissner@linux.vnet.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]