diff mbox

[Ada] Remove recent trick used for fat pointer types

Message ID 1624993.ElyiglcHhq@polaris
State New
Headers show

Commit Message

Eric Botcazou June 13, 2013, 7:45 a.m. UTC
Fat pointer types are pointer types to (slices of) arrays and they are said 
"fat" because they contain a pointer to the array and a pointer to the bounds.
We were using a trick on platforms which pass them by reference to improve the 
debug info at -O0, but this pessimizes when optimization is enabled.

Tested on x86_64-suse-linux, applied on the mainline and 4.8 branch.


2013-06-13  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/ada-tree.h (DECL_BY_DOUBLE_REF_P): Delete.
	* gcc-interface/gigi.h (annotate_object): Adjust prototype.
	(convert_vms_descriptor): Likewise.
	* gcc-interface/decl.c (gnat_to_gnu_param): Do not pass fat pointer
	types by double dereference.
	(annotate_object): Remove BY_DOUBLE_REF parameter and adjust.
	(gnat_to_gnu_entity): Adjust calls to annotate_object.
	* gcc-interface/trans.c (Identifier_to_gnu): Do not deal with double
	dereference.
	(Call_to_gnu): Likewise.
	(build_function_stub): Adjust call to convert_vms_descriptor.
	(Subprogram_Body_to_gnu): Adjust call to annotate_object.
	* gcc-interface/utils.c (convert_vms_descriptor): Remove BY_REF
	parameter and adjust.
diff mbox

Patch

Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c	(revision 200056)
+++ gcc-interface/utils.c	(working copy)
@@ -4096,33 +4096,25 @@  convert_vms_descriptor32 (tree gnu_type,
 
 /* Convert GNU_EXPR, a pointer to a VMS descriptor, to GNU_TYPE, a regular
    pointer or fat pointer type.  GNU_EXPR_ALT_TYPE is the alternate (32-bit)
-   pointer type of GNU_EXPR.  BY_REF is true if the result is to be used by
-   reference.  GNAT_SUBPROG is the subprogram to which the VMS descriptor is
-   passed.  */
+   pointer type of GNU_EXPR.  GNAT_SUBPROG is the subprogram to which the
+   descriptor is passed.  */
 
 tree
 convert_vms_descriptor (tree gnu_type, tree gnu_expr, tree gnu_expr_alt_type,
-			bool by_ref, Entity_Id gnat_subprog)
+			Entity_Id gnat_subprog)
 {
   tree desc_type = TREE_TYPE (TREE_TYPE (gnu_expr));
   tree desc = build1 (INDIRECT_REF, desc_type, gnu_expr);
   tree mbo = TYPE_FIELDS (desc_type);
   const char *mbostr = IDENTIFIER_POINTER (DECL_NAME (mbo));
   tree mbmo = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (mbo)));
-  tree real_type, is64bit, gnu_expr32, gnu_expr64;
-
-  if (by_ref)
-    real_type = TREE_TYPE (gnu_type);
-  else
-    real_type = gnu_type;
+  tree is64bit, gnu_expr32, gnu_expr64;
 
   /* If the field name is not MBO, it must be 32-bit and no alternate.
      Otherwise primary must be 64-bit and alternate 32-bit.  */
   if (strcmp (mbostr, "MBO") != 0)
     {
-      tree ret = convert_vms_descriptor32 (real_type, gnu_expr, gnat_subprog);
-      if (by_ref)
-	ret = build_unary_op (ADDR_EXPR, gnu_type, ret);
+      tree ret = convert_vms_descriptor32 (gnu_type, gnu_expr, gnat_subprog);
       return ret;
     }
 
@@ -4139,14 +4131,9 @@  convert_vms_descriptor (tree gnu_type, t
 					integer_minus_one_node));
 
   /* Build the 2 possible end results.  */
-  gnu_expr64 = convert_vms_descriptor64 (real_type, gnu_expr, gnat_subprog);
-  if (by_ref)
-    gnu_expr64 =  build_unary_op (ADDR_EXPR, gnu_type, gnu_expr64);
+  gnu_expr64 = convert_vms_descriptor64 (gnu_type, gnu_expr, gnat_subprog);
   gnu_expr = fold_convert (gnu_expr_alt_type, gnu_expr);
-  gnu_expr32 = convert_vms_descriptor32 (real_type, gnu_expr, gnat_subprog);
-  if (by_ref)
-    gnu_expr32 =  build_unary_op (ADDR_EXPR, gnu_type, gnu_expr32);
-
+  gnu_expr32 = convert_vms_descriptor32 (gnu_type, gnu_expr, gnat_subprog);
   return build3 (COND_EXPR, gnu_type, is64bit, gnu_expr64, gnu_expr32);
 }
 
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c	(revision 200056)
+++ gcc-interface/decl.c	(working copy)
@@ -1025,7 +1025,7 @@  gnat_to_gnu_entity (Entity_Id gnat_entit
 			save_gnu_tree (gnat_entity, gnu_decl, true);
 			saved = true;
 			annotate_object (gnat_entity, gnu_type, NULL_TREE,
-					 false, false);
+					 false);
 			/* This assertion will fail if the renamed object
 			   isn't aligned enough as to make it possible to
 			   honor the alignment set on the renaming.  */
@@ -1604,7 +1604,7 @@  gnat_to_gnu_entity (Entity_Id gnat_entit
 	   type of the object and not on the object directly, and makes it
 	   possible to support all confirming representation clauses.  */
 	annotate_object (gnat_entity, TREE_TYPE (gnu_decl), gnu_object_size,
-			 used_by_ref, false);
+			 used_by_ref);
       }
       break;
 
@@ -5650,7 +5650,7 @@  gnat_to_gnu_param (Entity_Id gnat_param,
   /* The parameter can be indirectly modified if its address is taken.  */
   bool ro_param = in_param && !Address_Taken (gnat_param);
   bool by_return = false, by_component_ptr = false;
-  bool by_ref = false, by_double_ref = false;
+  bool by_ref = false;
   tree gnu_param;
 
   /* Copy-return is used only for the first parameter of a valued procedure.
@@ -5775,19 +5775,6 @@  gnat_to_gnu_param (Entity_Id gnat_param,
 	gnu_param_type
 	  = build_qualified_type (gnu_param_type, TYPE_QUAL_RESTRICT);
       by_ref = true;
-
-      /* In some ABIs, e.g. SPARC 32-bit, fat pointer types are themselves
-	 passed by reference.  Pass them by explicit reference, this will
-	 generate more debuggable code at -O0.  */
-      if (TYPE_IS_FAT_POINTER_P (gnu_param_type)
-	  && targetm.calls.pass_by_reference (pack_cumulative_args (NULL),
-					      TYPE_MODE (gnu_param_type),
-					      gnu_param_type,
-					      true))
-	{
-	   gnu_param_type = build_reference_type (gnu_param_type);
-	   by_double_ref = true;
-	}
     }
 
   /* Pass In Out or Out parameters using copy-in copy-out mechanism.  */
@@ -5830,7 +5817,6 @@  gnat_to_gnu_param (Entity_Id gnat_param,
   gnu_param = create_param_decl (gnu_param_name, gnu_param_type,
 				 ro_param || by_ref || by_component_ptr);
   DECL_BY_REF_P (gnu_param) = by_ref;
-  DECL_BY_DOUBLE_REF_P (gnu_param) = by_double_ref;
   DECL_BY_COMPONENT_PTR_P (gnu_param) = by_component_ptr;
   DECL_BY_DESCRIPTOR_P (gnu_param) = (mech == By_Descriptor ||
                                       mech == By_Short_Descriptor);
@@ -7554,18 +7540,13 @@  annotate_value (tree gnu_size)
 /* Given GNAT_ENTITY, an object (constant, variable, parameter, exception)
    and GNU_TYPE, its corresponding GCC type, set Esize and Alignment to the
    size and alignment used by Gigi.  Prefer SIZE over TYPE_SIZE if non-null.
-   BY_REF is true if the object is used by reference and BY_DOUBLE_REF is
-   true if the object is used by double reference.  */
+   BY_REF is true if the object is used by reference.  */
 
 void
-annotate_object (Entity_Id gnat_entity, tree gnu_type, tree size, bool by_ref,
-		 bool by_double_ref)
+annotate_object (Entity_Id gnat_entity, tree gnu_type, tree size, bool by_ref)
 {
   if (by_ref)
     {
-      if (by_double_ref)
-	gnu_type = TREE_TYPE (gnu_type);
-
       if (TYPE_IS_FAT_POINTER_P (gnu_type))
 	gnu_type = TYPE_UNCONSTRAINED_ARRAY (gnu_type);
       else
Index: gcc-interface/gigi.h
===================================================================
--- gcc-interface/gigi.h	(revision 200056)
+++ gcc-interface/gigi.h	(working copy)
@@ -178,10 +178,9 @@  extern tree choices_to_gnu (tree operand
 /* Given GNAT_ENTITY, an object (constant, variable, parameter, exception)
    and GNU_TYPE, its corresponding GCC type, set Esize and Alignment to the
    size and alignment used by Gigi.  Prefer SIZE over TYPE_SIZE if non-null.
-   BY_REF is true if the object is used by reference and BY_DOUBLE_REF is
-   true if the object is used by double reference.  */
+   BY_REF is true if the object is used by reference.  */
 extern void annotate_object (Entity_Id gnat_entity, tree gnu_type, tree size,
-			     bool by_ref, bool by_double_ref);
+			     bool by_ref);
 
 /* Return the variant part of RECORD_TYPE, if any.  Otherwise return NULL.  */
 extern tree get_variant_part (tree record_type);
@@ -953,11 +952,10 @@  extern tree fill_vms_descriptor (tree gn
 
 /* Convert GNU_EXPR, a pointer to a VMS descriptor, to GNU_TYPE, a regular
    pointer or fat pointer type.  GNU_EXPR_ALT_TYPE is the alternate (32-bit)
-   pointer type of GNU_EXPR.  BY_REF is true if the result is to be used by
-   reference.  GNAT_SUBPROG is the subprogram to which the VMS descriptor is
-   passed.  */
+   pointer type of GNU_EXPR.  GNAT_SUBPROG is the subprogram to which the
+   descriptor is passed.  */
 extern tree convert_vms_descriptor (tree gnu_type, tree gnu_expr,
-				    tree gnu_expr_alt_type, bool by_ref,
+				    tree gnu_expr_alt_type,
 				    Entity_Id gnat_subprog);
 
 /* Indicate that we need to take the address of T and that it therefore
Index: gcc-interface/ada-tree.h
===================================================================
--- gcc-interface/ada-tree.h	(revision 200056)
+++ gcc-interface/ada-tree.h	(working copy)
@@ -360,10 +360,6 @@  do {						   \
    constant CONSTRUCTOR.  */
 #define DECL_CONST_ADDRESS_P(NODE) DECL_LANG_FLAG_0 (CONST_DECL_CHECK (NODE))
 
-/* Nonzero in a PARM_DECL if it is always used by double reference, i.e. a
-   pair of INDIRECT_REFs is needed to access the object.  */
-#define DECL_BY_DOUBLE_REF_P(NODE) DECL_LANG_FLAG_0 (PARM_DECL_CHECK (NODE))
-
 /* Nonzero in a FIELD_DECL if it is declared as aliased.  */
 #define DECL_ALIASED_P(NODE) DECL_LANG_FLAG_0 (FIELD_DECL_CHECK (NODE))
 
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 200056)
+++ gcc-interface/trans.c	(working copy)
@@ -1082,19 +1082,6 @@  Identifier_to_gnu (Node_Id gnat_node, tr
     {
       const bool read_only = DECL_POINTS_TO_READONLY_P (gnu_result);
 
-      /* First do the first dereference if needed.  */
-      if (TREE_CODE (gnu_result) == PARM_DECL
-	  && DECL_BY_DOUBLE_REF_P (gnu_result))
-	{
-	  gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result);
-	  if (TREE_CODE (gnu_result) == INDIRECT_REF)
-	    TREE_THIS_NOTRAP (gnu_result) = 1;
-
-	  /* The first reference, in case of a double reference, always points
-	     to read-only, see gnat_to_gnu_param for the rationale.  */
-	  TREE_READONLY (gnu_result) = 1;
-	}
-
       /* If it's a PARM_DECL to foreign convention subprogram, convert it.  */
       if (TREE_CODE (gnu_result) == PARM_DECL
 	  && DECL_BY_COMPONENT_PTR_P (gnu_result))
@@ -3375,7 +3362,6 @@  build_function_stub (tree gnu_subprog, E
 	    = convert_vms_descriptor (TREE_TYPE (gnu_subprog_param),
 				      gnu_stub_param,
 				      DECL_PARM_ALT_TYPE (gnu_stub_param),
-				      DECL_BY_DOUBLE_REF_P (gnu_subprog_param),
 				      gnat_subprog);
 	}
       else
@@ -3670,8 +3656,7 @@  Subprogram_Body_to_gnu (Node_Id gnat_nod
       bool is_var_decl = (TREE_CODE (gnu_param) == VAR_DECL);
 
       annotate_object (gnat_param, TREE_TYPE (gnu_param), NULL_TREE,
-		       DECL_BY_REF_P (gnu_param),
-		       !is_var_decl && DECL_BY_DOUBLE_REF_P (gnu_param));
+		       DECL_BY_REF_P (gnu_param));
 
       if (is_var_decl)
 	save_gnu_tree (gnat_param, NULL_TREE, false);
@@ -4133,12 +4118,6 @@  Call_to_gnu (Node_Id gnat_node, tree *gn
 	  /* The symmetry of the paths to the type of an entity is broken here
 	     since arguments don't know that they will be passed by ref.  */
 	  gnu_formal_type = TREE_TYPE (gnu_formal);
-
-	  if (DECL_BY_DOUBLE_REF_P (gnu_formal))
-	    gnu_actual
-	      = build_unary_op (ADDR_EXPR, TREE_TYPE (gnu_formal_type),
-				gnu_actual);
-
 	  gnu_actual = build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual);
 	}
       else if (is_true_formal_parm && DECL_BY_COMPONENT_PTR_P (gnu_formal))