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. */