From: Eric Botcazou Date: Tue, 11 Dec 2018 11:08:45 +0000 (+0000) Subject: [Ada] Almost always inline init. procedure of small and simple records X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=13a6dfe3a1268265006628e58ec94d7d4222328d;p=gcc.git [Ada] Almost always inline init. procedure of small and simple records 2018-12-11 Eric Botcazou 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) : 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 --- diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index b48c757b816..b2e6e142ef3 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,21 @@ +2018-12-11 Eric Botcazou + + * 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) : 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 * sem_aux.adb (Object_Type_Has_Constrained_Partial_View): Return diff --git a/gcc/ada/fe.h b/gcc/ada/fe.h index d4c426501b7..c85d69c5825 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 d8fb8ee74b9..758f2c3733d 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 3029732603a..f25c32879a3 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 4c066c02421..db9223ef4a6 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 05959d6427b..5646051b4dc 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: