In the Ada compiler, the layout of types is done by gigi and the middle-end, 
but the front-end needs the information for various purposes.  That's why gigi 
back-annotates the nodes generated by the front-end with that information.

It turns out that this can be quite costly in terms of memory consumption for 
big discriminated types, especially for the symbolic back-annotation, so this 
patch disables the latter sort of annotation by default.

Tested on x86_64-suse-linux, applied on the mainline.


2014-04-14  Eric Botcazou  <ebotca...@adacore.com>
            Robert Dewar  <de...@adacore.com>

        * opt.ads (Suppress_Back_Annotation): Remove as unused.
        * fe.h (Back_Annotate_Rep_Info): Likewise.
        (Global_Discard_Names): Likewise.
        (List_Representation_Info): Declare.
        * types.h (Uint_Minus_1): Likewise.
        * repinfo.ads: Document back-annotation change.
        * gcc-interface/gigi.h (init_gnat_decl): Declare.
        (destroy_gnat_decl): Likewise.
        * gcc-interface/decl.c (annotate_value): Do not create the cache of
        annotated values here but...
        <CALL_EXPR>: Only inline the call if -gnatR3 is specified or we are
        in ASIS mode.
        (init_gnat_decl): ...here instead.  New function.
        (destroy_gnat_decl): Likewise.
        * gcc-interface/trans.c (gigi): Call {init|destroy}_gnat_decl.
        * gcc-interface/utils.c (init_gnat_utils): Minor reformatting.


-- 
Eric Botcazou
Index: fe.h
===================================================================
--- fe.h	(revision 209334)
+++ fe.h	(working copy)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                              C Header File                               *
  *                                                                          *
- *          Copyright (C) 1992-2013, Free Software Foundation, Inc.         *
+ *          Copyright (C) 1992-2014, Free Software Foundation, Inc.         *
  *                                                                          *
  * GNAT is free software;  you can  redistribute it  and/or modify it under *
  * terms of the  GNU General Public License as published  by the Free Soft- *
@@ -178,23 +178,21 @@ extern Boolean In_Same_Source_Unit
 
 /* opt: */
 
-#define Back_Annotate_Rep_Info         opt__back_annotate_rep_info
 #define Exception_Extra_Info           opt__exception_extra_info
 #define Exception_Locations_Suppressed opt__exception_locations_suppressed
 #define Exception_Mechanism            opt__exception_mechanism
 #define Generate_SCO_Instance_Table    opt__generate_sco_instance_table
-#define Global_Discard_Names           opt__global_discard_names
 #define Float_Format                   opt__float_format
+#define List_Representation_Info       opt__list_representation_info
 
 typedef enum {Setjmp_Longjmp, Back_End_Exceptions} Exception_Mechanism_Type;
 
-extern Boolean Back_Annotate_Rep_Info;
 extern Boolean Exception_Extra_Info;
 extern Boolean Exception_Locations_Suppressed;
 extern Exception_Mechanism_Type Exception_Mechanism;
 extern Boolean Generate_SCO_Instance_Table;
-extern Boolean Global_Discard_Names;
 extern Char Float_Format;
+extern Int List_Representation_Info;
 
 /* restrict: */
 
Index: types.h
===================================================================
--- types.h	(revision 209334)
+++ types.h	(working copy)
@@ -272,6 +272,8 @@ SUBTYPE (Uint_Direct, Uint, Uint_Direct_
 #define Uint_10 (Uint_Direct_Bias + 10)
 #define Uint_16 (Uint_Direct_Bias + 16)
 
+#define Uint_Minus_1 (Uint_Direct_Bias - 1)
+
 /* Types for Ureal_Support Package:  */
 
 /* Type used for representation of universal reals.  */
Index: repinfo.ads
===================================================================
--- repinfo.ads	(revision 209334)
+++ repinfo.ads	(working copy)
@@ -108,6 +108,14 @@ package Repinfo is
    --       represent the value of such an expression, as explained in
    --       the following section.
 
+   --  Note: the extended back-annotation for the dynamic case is needed only
+   --  for -gnatR3 output, and for proper operation of the ASIS DDA. Since it
+   --  can be expensive to do this back annotation (for discriminated records
+   --  with many variable length arrays), we only do the full back annotation
+   --  in -gnatR3 mode, or ASIS mode. In any other mode, the back-end just sets
+   --  the value to Uint_Minus_1, indicating that the value of the attribute
+   --  depends on discriminant information, but not giving further details.
+
    --  GCC expressions are represented with a Uint value that is negative.
    --  See the body of this package for details on the representation used.
 
@@ -117,7 +125,9 @@ package Repinfo is
    --  as a negative Uint value, provides an expression which, when evaluated
    --  with a given set of discriminant values, indicates whether the variant
    --  is present for that set of values (result is True, i.e. non-zero) or
-   --  not present (result is False, i.e. zero).
+   --  not present (result is False, i.e. zero). Again, the full annotation of
+   --  this field is done only in -gnatR3 mode or in ASIS mode, and in other
+   --  modes, the value is set to Uint_Minus_1.
 
    subtype Node_Ref is Uint;
    --  Subtype used for negative Uint values used to represent nodes
Index: opt.ads
===================================================================
--- opt.ads	(revision 209334)
+++ opt.ads	(working copy)
@@ -1371,12 +1371,6 @@ package Opt is
    --  initialized by Osint.Initialize, and further initialized by the
    --  Adjust_Global_Switches flag in Gnat1drv.
 
-   Suppress_Back_Annotation : Boolean := False;
-   --  GNAT
-   --  This flag is set True if back annotation of representation information
-   --  is to be suppressed. This is set if neither -gnatt or -gnatR0-3 is set.
-   --  This avoids unnecessary time being spent on back annotation.
-
    Table_Factor : Int := 1;
    --  GNAT
    --  Factor by which all initial table sizes set in Alloc are multiplied.
Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c	(revision 209334)
+++ gcc-interface/utils.c	(working copy)
@@ -251,8 +251,8 @@ init_gnat_utils (void)
   dummy_node_table = ggc_alloc_cleared_vec_tree (max_gnat_nodes);
 
   /* Initialize the hash table of padded types.  */
-  pad_type_hash_table = htab_create_ggc (512, pad_type_hash_hash,
-					 pad_type_hash_eq, 0);
+  pad_type_hash_table
+    = htab_create_ggc (512, pad_type_hash_hash, pad_type_hash_eq, 0);
 }
 
 /* Destroy data structures of the utils.c module.  */
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c	(revision 209369)
+++ gcc-interface/decl.c	(working copy)
@@ -7467,12 +7467,8 @@ annotate_value (tree gnu_size)
     {
       struct tree_int_map *e;
 
-      if (!annotate_value_cache)
-        annotate_value_cache = htab_create_ggc (512, tree_int_map_hash,
-					        tree_int_map_eq, 0);
       in.base.from = gnu_size;
-      e = (struct tree_int_map *)
-	    htab_find (annotate_value_cache, &in);
+      e = (struct tree_int_map *) htab_find (annotate_value_cache, &in);
 
       if (e)
 	return (Node_Ref_Or_Val) e->to;
@@ -7559,11 +7555,17 @@ annotate_value (tree gnu_size)
       break;
 
     case CALL_EXPR:
-      {
-	tree t = maybe_inline_call_in_expr (gnu_size);
-	if (t)
-	  return annotate_value (t);
-      }
+      /* In regular mode, inline back only if symbolic annotation is requested
+	 in order to avoid memory explosion on big discriminated record types.
+	 But not in ASIS mode, as symbolic annotation is required for DDA.  */
+      if (List_Representation_Info == 3 || type_annotate_only)
+	{
+	  tree t = maybe_inline_call_in_expr (gnu_size);
+	  if (t)
+	    return annotate_value (t);
+	}
+      else
+	return Uint_Minus_1;
 
       /* Fall through... */
 
@@ -7592,11 +7594,10 @@ annotate_value (tree gnu_size)
   if (in.base.from)
     {
       struct tree_int_map **h;
-      /* We can't assume the hash table data hasn't moved since the
-	 initial look up, so we have to search again.  Allocating and
-	 inserting an entry at that point would be an alternative, but
-	 then we'd better discard the entry if we decided not to cache
-	 it.  */
+      /* We can't assume the hash table data hasn't moved since the initial
+	 look up, so we have to search again.  Allocating and inserting an
+	 entry at that point would be an alternative, but then we'd better
+	 discard the entry if we decided not to cache it.  */
       h = (struct tree_int_map **)
 	    htab_find_slot (annotate_value_cache, &in, INSERT);
       gcc_assert (!*h);
@@ -8922,4 +8923,24 @@ concat_name (tree gnu_name, const char *
   return get_identifier_with_length (new_name, len);
 }
 
+/* Initialize data structures of the decl.c module.  */
+
+void
+init_gnat_decl (void)
+{
+  /* Initialize the cache of annotated values.  */
+  annotate_value_cache
+    = htab_create_ggc (512, tree_int_map_hash, tree_int_map_eq, 0);
+}
+
+/* Destroy data structures of the decl.c module.  */
+
+void
+destroy_gnat_decl (void)
+{
+  /* Destroy the cache of annotated values.  */
+  htab_delete (annotate_value_cache);
+  annotate_value_cache = NULL;
+}
+
 #include "gt-ada-decl.h"
Index: gcc-interface/gigi.h
===================================================================
--- gcc-interface/gigi.h	(revision 209334)
+++ gcc-interface/gigi.h	(working copy)
@@ -210,6 +210,12 @@ extern tree create_concat_name (Entity_I
    the name followed by "___" and the specified suffix.  */
 extern tree concat_name (tree gnu_name, const char *suffix);
 
+/* Initialize data structures of the decl.c module.  */
+extern void init_gnat_decl (void);
+
+/* Destroy data structures of the decl.c module.  */
+extern void destroy_gnat_decl (void);
+
 /* Highest number in the front-end node table.  */
 extern int max_gnat_nodes;
 
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 209334)
+++ gcc-interface/trans.c	(working copy)
@@ -353,6 +353,7 @@ gigi (Node_Id gnat_root,
 
   /* Initialize ourselves.  */
   init_code_table ();
+  init_gnat_decl ();
   init_gnat_utils ();
 
   /* If we are just annotating types, give VOID_TYPE zero sizes to avoid
@@ -727,6 +728,7 @@ gigi (Node_Id gnat_root,
     }
 
   /* Destroy ourselves.  */
+  destroy_gnat_decl ();
   destroy_gnat_utils ();
 
   /* We cannot track the location of errors past this point.  */

Reply via email to