aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/ada/ChangeLog18
-rw-r--r--gcc/ada/fe.h2
-rw-r--r--gcc/ada/gcc-interface/decl.c47
-rw-r--r--gcc/ada/gcc-interface/gigi.h6
-rw-r--r--gcc/ada/gcc-interface/trans.c38
-rw-r--r--gcc/ada/gcc-interface/utils.c19
6 files changed, 95 insertions, 35 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index b48c757..b2e6e14 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,21 @@
+2018-12-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * 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.
+
2018-12-03 Gary Dismukes <dismukes@adacore.com>
* sem_aux.adb (Object_Type_Has_Constrained_Partial_View): Return
diff --git a/gcc/ada/fe.h b/gcc/ada/fe.h
index d4c4265..c85d69c 100644
--- a/gcc/ada/fe.h
+++ b/gcc/ada/fe.h
@@ -185,6 +185,7 @@ extern Boolean In_Same_Source_Unit (Node_Id, Node_Id);
/* opt: */
#define Back_End_Inlining opt__back_end_inlining
+#define Debug_Generated_Code opt__debug_generated_code
#define Exception_Extra_Info opt__exception_extra_info
#define Exception_Locations_Suppressed opt__exception_locations_suppressed
#define Exception_Mechanism opt__exception_mechanism
@@ -200,6 +201,7 @@ typedef enum {
} Exception_Mechanism_Type;
extern Boolean Back_End_Inlining;
+extern Boolean Debug_Generated_Code;
extern Boolean Exception_Extra_Info;
extern Boolean Exception_Locations_Suppressed;
extern Exception_Mechanism_Type Exception_Mechanism;
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
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index 3029732..f25c328 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -439,9 +439,11 @@ enum inline_status_t
/* Inlining is suppressed for the subprogram. */
is_suppressed,
/* No inlining is requested for the subprogram. */
- is_disabled,
+ is_default,
/* Inlining is requested for the subprogram. */
- is_enabled,
+ is_requested,
+ /* Inlining is strongly requested for the subprogram. */
+ is_prescribed,
/* Inlining is required for the subprogram. */
is_required
};
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 4c066c0..db9223e 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -412,7 +412,7 @@ gigi (Node_Id gnat_root,
= create_subprog_decl (get_identifier ("__gnat_malloc"), NULL_TREE,
build_function_type_list (ptr_type_node, sizetype,
NULL_TREE),
- NULL_TREE, is_disabled, true, true, true, false,
+ NULL_TREE, is_default, true, true, true, false,
false, NULL, Empty);
DECL_IS_MALLOC (malloc_decl) = 1;
@@ -420,7 +420,7 @@ gigi (Node_Id gnat_root,
= create_subprog_decl (get_identifier ("__gnat_free"), NULL_TREE,
build_function_type_list (void_type_node,
ptr_type_node, NULL_TREE),
- NULL_TREE, is_disabled, true, true, true, false,
+ NULL_TREE, is_default, true, true, true, false,
false, NULL, Empty);
realloc_decl
@@ -428,7 +428,7 @@ gigi (Node_Id gnat_root,
build_function_type_list (ptr_type_node,
ptr_type_node, sizetype,
NULL_TREE),
- NULL_TREE, is_disabled, true, true, true, false,
+ NULL_TREE, is_default, true, true, true, false,
false, NULL, Empty);
/* This is used for 64-bit multiplication with overflow checking. */
@@ -437,7 +437,7 @@ gigi (Node_Id gnat_root,
= create_subprog_decl (get_identifier ("__gnat_mulv64"), NULL_TREE,
build_function_type_list (int64_type, int64_type,
int64_type, NULL_TREE),
- NULL_TREE, is_disabled, true, true, true, false,
+ NULL_TREE, is_default, true, true, true, false,
false, NULL, Empty);
/* Name of the _Parent field in tagged record types. */
@@ -461,21 +461,21 @@ gigi (Node_Id gnat_root,
= create_subprog_decl
(get_identifier ("system__soft_links__get_jmpbuf_address_soft"),
NULL_TREE, build_function_type_list (jmpbuf_ptr_type, NULL_TREE),
- NULL_TREE, is_disabled, true, true, true, false, false, NULL, Empty);
+ NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
set_jmpbuf_decl
= create_subprog_decl
(get_identifier ("system__soft_links__set_jmpbuf_address_soft"),
NULL_TREE, build_function_type_list (void_type_node, jmpbuf_ptr_type,
NULL_TREE),
- NULL_TREE, is_disabled, true, true, true, false, false, NULL, Empty);
+ NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
get_excptr_decl
= create_subprog_decl
(get_identifier ("system__soft_links__get_gnat_exception"), NULL_TREE,
build_function_type_list (build_pointer_type (except_type_node),
NULL_TREE),
- NULL_TREE, is_disabled, true, true, true, false, false, NULL, Empty);
+ NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
not_handled_by_others_decl = get_identifier ("not_handled_by_others");
for (t = TYPE_FIELDS (except_type_node); t; t = DECL_CHAIN (t))
@@ -493,7 +493,7 @@ gigi (Node_Id gnat_root,
(get_identifier ("__builtin_setjmp"), NULL_TREE,
build_function_type_list (integer_type_node, jmpbuf_ptr_type,
NULL_TREE),
- NULL_TREE, is_disabled, true, true, true, false, false, NULL, Empty);
+ NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
DECL_BUILT_IN_CLASS (setjmp_decl) = BUILT_IN_NORMAL;
DECL_FUNCTION_CODE (setjmp_decl) = BUILT_IN_SETJMP;
@@ -503,7 +503,7 @@ gigi (Node_Id gnat_root,
= create_subprog_decl
(get_identifier ("__builtin_update_setjmp_buf"), NULL_TREE,
build_function_type_list (void_type_node, jmpbuf_ptr_type, NULL_TREE),
- NULL_TREE, is_disabled, true, true, true, false, false, NULL, Empty);
+ NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
DECL_BUILT_IN_CLASS (update_setjmp_buf_decl) = BUILT_IN_NORMAL;
DECL_FUNCTION_CODE (update_setjmp_buf_decl) = BUILT_IN_UPDATE_SETJMP_BUF;
@@ -515,14 +515,14 @@ gigi (Node_Id gnat_root,
raise_nodefer_decl
= create_subprog_decl
(get_identifier ("__gnat_raise_nodefer_with_msg"), NULL_TREE, ftype,
- NULL_TREE, is_disabled, true, true, true, false, false, NULL, Empty);
+ NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
set_exception_parameter_decl
= create_subprog_decl
(get_identifier ("__gnat_set_exception_parameter"), NULL_TREE,
build_function_type_list (void_type_node, ptr_type_node, ptr_type_node,
NULL_TREE),
- NULL_TREE, is_disabled, true, true, true, false, false, NULL, Empty);
+ NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
/* Hooks to call when entering/leaving an exception handler. */
ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
@@ -530,7 +530,7 @@ gigi (Node_Id gnat_root,
begin_handler_decl
= create_subprog_decl (get_identifier ("__gnat_begin_handler"), NULL_TREE,
ftype, NULL_TREE,
- is_disabled, true, true, true, false, false, NULL,
+ is_default, true, true, true, false, false, NULL,
Empty);
/* __gnat_begin_handler is a dummy procedure. */
TREE_NOTHROW (begin_handler_decl) = 1;
@@ -538,13 +538,13 @@ gigi (Node_Id gnat_root,
end_handler_decl
= create_subprog_decl (get_identifier ("__gnat_end_handler"), NULL_TREE,
ftype, NULL_TREE,
- is_disabled, true, true, true, false, false, NULL,
+ is_default, true, true, true, false, false, NULL,
Empty);
unhandled_except_decl
= create_subprog_decl (get_identifier ("__gnat_unhandled_except_handler"),
NULL_TREE, ftype, NULL_TREE,
- is_disabled, true, true, true, false, false, NULL,
+ is_default, true, true, true, false, false, NULL,
Empty);
/* Indicate that it never returns. */
@@ -552,7 +552,7 @@ gigi (Node_Id gnat_root,
reraise_zcx_decl
= create_subprog_decl (get_identifier ("__gnat_reraise_zcx"), NULL_TREE,
ftype, NULL_TREE,
- is_disabled, true, true, true, false, false, NULL,
+ is_default, true, true, true, false, false, NULL,
Empty);
/* Dummy objects to materialize "others" and "all others" in the exception
@@ -592,7 +592,7 @@ gigi (Node_Id gnat_root,
tree decl
= create_subprog_decl
(get_identifier ("__gnat_last_chance_handler"), NULL_TREE, ftype,
- NULL_TREE, is_disabled, true, true, true, false, false, NULL,
+ NULL_TREE, is_default, true, true, true, false, false, NULL,
Empty);
for (i = 0; i < (int) ARRAY_SIZE (gnat_raise_decls); i++)
gnat_raise_decls[i] = decl;
@@ -756,7 +756,7 @@ build_raise_check (int check, enum exception_info_kind kind)
ftype = build_qualified_type (ftype, TYPE_QUAL_VOLATILE);
result
= create_subprog_decl (get_identifier (Name_Buffer), NULL_TREE, ftype,
- NULL_TREE, is_disabled, true, true, true, false,
+ NULL_TREE, is_default, true, true, true, false,
false, NULL, Empty);
return result;
@@ -6134,7 +6134,7 @@ Compilation_Unit_to_gnu (Node_Id gnat_node)
= create_subprog_decl
(create_concat_name (gnat_unit_entity, body_p ? "elabb" : "elabs"),
NULL_TREE, void_ftype, NULL_TREE,
- is_disabled, true, false, true, true, false, NULL, gnat_unit);
+ is_default, true, false, true, true, false, NULL, gnat_unit);
struct elab_info *info;
vec_safe_push (gnu_elab_proc_stack, gnu_elab_proc_decl);
@@ -7144,7 +7144,7 @@ gnat_to_gnu (Node_Id gnat_node)
create_subprog_decl (create_concat_name
(Entity (Prefix (gnat_node)),
attr == Attr_Elab_Body ? "elabb" : "elabs"),
- NULL_TREE, void_ftype, NULL_TREE, is_disabled,
+ NULL_TREE, void_ftype, NULL_TREE, is_default,
true, true, true, true, false, NULL,
gnat_node);
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 05959d6..5646051 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -3235,20 +3235,17 @@ create_subprog_decl (tree name, tree asm_name, tree type, tree param_decl_list,
DECL_ARTIFICIAL (subprog_decl) = artificial_p;
DECL_EXTERNAL (subprog_decl) = extern_flag;
+ DECL_FUNCTION_IS_DEF (subprog_decl) = definition;
+ DECL_IGNORED_P (subprog_decl) = !debug_info_p;
TREE_PUBLIC (subprog_decl) = public_flag;
- if (!debug_info_p)
- DECL_IGNORED_P (subprog_decl) = 1;
- if (definition)
- DECL_FUNCTION_IS_DEF (subprog_decl) = 1;
-
switch (inline_status)
{
case is_suppressed:
DECL_UNINLINABLE (subprog_decl) = 1;
break;
- case is_disabled:
+ case is_default:
break;
case is_required:
@@ -3269,9 +3266,15 @@ create_subprog_decl (tree name, tree asm_name, tree type, tree param_decl_list,
/* ... fall through ... */
- case is_enabled:
+ case is_prescribed:
+ DECL_DISREGARD_INLINE_LIMITS (subprog_decl) = 1;
+
+ /* ... fall through ... */
+
+ case is_requested:
DECL_DECLARED_INLINE_P (subprog_decl) = 1;
- DECL_NO_INLINE_WARNING_P (subprog_decl) = artificial_p;
+ if (!Debug_Generated_Code)
+ DECL_NO_INLINE_WARNING_P (subprog_decl) = artificial_p;
break;
default: