aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/decl.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2018-12-11 11:08:45 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2018-12-11 11:08:45 +0000
commit13a6dfe3a1268265006628e58ec94d7d4222328d (patch)
treee7a7cc44e293595fed209fd469dc146c46db4b6b /gcc/ada/gcc-interface/decl.c
parentd6a73cc353b90dbb253985aa6aba95c0d98680e6 (diff)
downloadgcc-13a6dfe3a1268265006628e58ec94d7d4222328d.zip
gcc-13a6dfe3a1268265006628e58ec94d7d4222328d.tar.gz
gcc-13a6dfe3a1268265006628e58ec94d7d4222328d.tar.bz2
[Ada] Almost always inline init. procedure of small and simple records
2018-12-11 Eric Botcazou <ebotcazou@adacore.com> gcc/ada/ * fe.h (Debug_Generated_Code): Declare. * gcc-interface/gigi.h (enum inline_status_t): Rename is_disabled to is_default, is_enabled to is_requested and add is_prescribed. * gcc-interface/decl.c (inline_status_for_subprog): New function. (gnat_to_gnu_entity) <E_Subprogram_Type>: Use it to get the inlining status of the subprogram. * gcc-interface/trans.c (gigi): Adjust to above renaming. (build_raise_check): Likewise. (Compilation_Unit_to_gnu): Likewise. (gnat_to_gnu): Likewise. * gcc-interface/utils.c (create_subprog_decl): Likewise. Deal with is_prescribed status by setting DECL_DISREGARD_INLINE_LIMITS. Do not set the DECL_NO_INLINE_WARNING_P flag if Debug_Generated_Code is true. From-SVN: r266976
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r--gcc/ada/gcc-interface/decl.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index d8fb8ee..758f2c3 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -205,6 +205,7 @@ static tree gnat_to_gnu_component_type (Entity_Id, bool, bool);
static tree gnat_to_gnu_subprog_type (Entity_Id, bool, bool, tree *);
static int adjust_packed (tree, tree, int);
static tree gnat_to_gnu_field (Entity_Id, tree, int, bool, bool);
+static enum inline_status_t inline_status_for_subprog (Entity_Id);
static tree gnu_ext_name_for_subprog (Entity_Id, tree);
static void set_nonaliased_component_on_array_type (tree);
static void set_reverse_storage_order_on_array_type (tree);
@@ -3883,12 +3884,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
{
tree gnu_ext_name
= gnu_ext_name_for_subprog (gnat_entity, gnu_entity_name);
- enum inline_status_t inline_status
- = Has_Pragma_No_Inline (gnat_entity)
- ? is_suppressed
- : Has_Pragma_Inline_Always (gnat_entity)
- ? is_required
- : (Is_Inlined (gnat_entity) ? is_enabled : is_disabled);
+ const enum inline_status_t inline_status
+ = inline_status_for_subprog (gnat_entity);
bool public_flag = Is_Public (gnat_entity) || imported_p;
/* Subprograms marked both Intrinsic and Always_Inline need not
have a body of their own. */
@@ -4934,6 +4931,44 @@ is_cplusplus_method (Entity_Id gnat_entity)
return false;
}
+/* Return the inlining status of the GNAT subprogram SUBPROG. */
+
+static enum inline_status_t
+inline_status_for_subprog (Entity_Id subprog)
+{
+ if (Has_Pragma_No_Inline (subprog))
+ return is_suppressed;
+
+ if (Has_Pragma_Inline_Always (subprog))
+ return is_required;
+
+ if (Is_Inlined (subprog))
+ {
+ tree gnu_type;
+
+ /* This is a kludge to work around a pass ordering issue: for small
+ record types with many components, i.e. typically bit-fields, the
+ initialization routine can contain many assignments that will be
+ merged by the GIMPLE store merging pass. But this pass runs very
+ late in the pipeline, in particular after the inlining decisions
+ are made, so the inlining heuristics cannot take its outcome into
+ account. Therefore, we optimistically override the heuristics for
+ the initialization routine in this case. */
+ if (Is_Init_Proc (subprog)
+ && flag_store_merging
+ && Is_Record_Type (Etype (First_Formal (subprog)))
+ && (gnu_type = gnat_to_gnu_type (Etype (First_Formal (subprog))))
+ && !TYPE_IS_BY_REFERENCE_P (gnu_type)
+ && tree_fits_uhwi_p (TYPE_SIZE (gnu_type))
+ && compare_tree_int (TYPE_SIZE (gnu_type), MAX_FIXED_MODE_SIZE) <= 0)
+ return is_prescribed;
+
+ return is_requested;
+ }
+
+ return is_default;
+}
+
/* Finalize the processing of From_Limited_With incomplete types. */
void