From f087ea4445c639926873179da29955c3a968ddc7 Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Thu, 31 Jul 2014 14:51:34 +0200 Subject: [PATCH] [multiple changes] 2014-07-31 Hristian Kirtchev * sem_util.adb (Is_Effectively_Volatile): New routine. 2014-07-31 Fedor Rybin * gnat_ugn.texi: Document --test-duration option for gnattest. 2014-07-31 Javier Miranda * opt.ads (Back_End_Inlining): New variable which controls activation of inlining by back-end expansion. * gnat1drv.adb (Adjust_Global_Switches): Initialize Back_End_Inlining * sem_ch6.adb (Analyze_Subprogram_Body_Helper): Do not build the body to be inlined by the frontend if Back_End_Inlining is enabled. * exp_ch6.adb (Register_Backend_Call): Moved to inline.adb. (Expand_Call): If backend inlining is enabled let the backend to handle inlined subprograms. * inline.ads (Register_Backend_Call): Moved here from exp_ch6 * inline.adb (Register_Backend_Call): Moved here from exp_ch6. (Add_Inlined_Subprogram): Add subprograms when Back_End_Inlining is set. (Must_Inline): Do not return Inline_Call if Back_End_Inlining is enabled. * debug.adb Document -gnatd.z * fe.h Import Back_End_Inlining variable. * gcc-interface/utils.c (create_subprog_decl): If Back_End_Inlining is enabled then declare attribute "always inline" 2014-07-31 Robert Dewar * a-ngelfu.ads: Minor comment fix. From-SVN: r213353 --- gcc/ada/ChangeLog | 33 ++++++++++++++++++++++++++++++++ gcc/ada/a-ngelfu.ads | 2 +- gcc/ada/debug.adb | 4 +++- gcc/ada/exp_ch6.adb | 26 +++++++++---------------- gcc/ada/fe.h | 2 ++ gcc/ada/gcc-interface/gigi.h | 4 +++- gcc/ada/gcc-interface/utils.c | 36 +++++++++++++++++++++++++++++++++-- gcc/ada/gnat1drv.adb | 11 +++++++++++ gcc/ada/gnat_ugn.texi | 4 ++++ gcc/ada/inline.adb | 29 +++++++++++++++++++++++++++- gcc/ada/inline.ads | 3 +++ gcc/ada/opt.ads | 4 ++++ gcc/ada/sem_ch6.adb | 12 ++++++++++++ gcc/ada/sem_util.adb | 5 ++++- 14 files changed, 151 insertions(+), 24 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index d8fdf6120954..75940fe0e48c 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,36 @@ +2014-07-31 Hristian Kirtchev + + * sem_util.adb (Is_Effectively_Volatile): New routine. + +2014-07-31 Fedor Rybin + + * gnat_ugn.texi: Document --test-duration option for gnattest. + +2014-07-31 Javier Miranda + + * opt.ads (Back_End_Inlining): New variable which controls + activation of inlining by back-end expansion. + * gnat1drv.adb (Adjust_Global_Switches): Initialize Back_End_Inlining + * sem_ch6.adb (Analyze_Subprogram_Body_Helper): Do not build + the body to be inlined by the frontend if Back_End_Inlining + is enabled. + * exp_ch6.adb (Register_Backend_Call): Moved to inline.adb. + (Expand_Call): If backend inlining is enabled let the backend to + handle inlined subprograms. + * inline.ads (Register_Backend_Call): Moved here from exp_ch6 + * inline.adb (Register_Backend_Call): Moved here from exp_ch6. + (Add_Inlined_Subprogram): Add subprograms when Back_End_Inlining is set. + (Must_Inline): Do not return Inline_Call if Back_End_Inlining is + enabled. + * debug.adb Document -gnatd.z + * fe.h Import Back_End_Inlining variable. + * gcc-interface/utils.c (create_subprog_decl): If Back_End_Inlining is + enabled then declare attribute "always inline" + +2014-07-31 Robert Dewar + + * a-ngelfu.ads: Minor comment fix. + 2014-07-31 Hristian Kirtchev * freeze.adb (Freeze_Record_Type): Replace all calls to diff --git a/gcc/ada/a-ngelfu.ads b/gcc/ada/a-ngelfu.ads index fba557f5f612..8afb7332204c 100644 --- a/gcc/ada/a-ngelfu.ads +++ b/gcc/ada/a-ngelfu.ads @@ -49,7 +49,7 @@ package Ada.Numerics.Generic_Elementary_Functions is -- and the sqrt of numbers less than 1 is greater than the argument). -- This property is useful in particular for static analysis. The - -- property that X is positive is not expressed as (X > 0), as + -- property that X is positive is not expressed as (X > 0.0), as -- the value X may be held in registers that have larger range and -- precision on some architecture (for example, on x86 using x387 -- FPU, as opposed to SSE2). So, it might be possible for X to be diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb index a1a1d8c1a136..be1eff3e1357 100644 --- a/gcc/ada/debug.adb +++ b/gcc/ada/debug.adb @@ -116,7 +116,7 @@ package body Debug is -- d.w Do not check for infinite loops -- d.x No exception handlers -- d.y - -- d.z + -- d.z Enable new support for backend inlining -- d.A Read/write Aspect_Specifications hash table to tree -- d.B @@ -594,6 +594,8 @@ package body Debug is -- fully compiled and analyzed, they just get eliminated from the -- code generation step. + -- d.z Need documentation of this flag ??? + -- d.A There seems to be a problem with ASIS if we activate the circuit -- for reading and writing the aspect specification hash table, so -- for now, this is controlled by the debug flag d.A. The hash table diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb index 45327b96a72f..87a4ccbfa03b 100644 --- a/gcc/ada/exp_ch6.adb +++ b/gcc/ada/exp_ch6.adb @@ -2113,9 +2113,6 @@ package body Exp_Ch6 is -- then register the enclosing unit of Subp to Inlined_Bodies so that -- the body of Subp can be retrieved and analyzed by the backend. - procedure Register_Backend_Call (N : Node_Id); - -- Append N to the list Backend_Calls - ----------------------- -- Do_Backend_Inline -- ----------------------- @@ -2174,19 +2171,6 @@ package body Exp_Ch6 is end if; end Do_Backend_Inline; - --------------------------- - -- Register_Backend_Call -- - --------------------------- - - procedure Register_Backend_Call (N : Node_Id) is - begin - if Backend_Calls = No_Elist then - Backend_Calls := New_Elmt_List; - end if; - - Append_Elmt (N, To => Backend_Calls); - end Register_Backend_Call; - -- Start of processing for Do_Inline begin @@ -3846,9 +3830,17 @@ package body Exp_Ch6 is return; end if; + -- Back end inlining: let the back end handle it + + if Back_End_Inlining + and then Is_Inlined (Subp) + then + Add_Inlined_Body (Subp); + Register_Backend_Call (Call_Node); + -- Handle inlining (old semantics) - if Is_Inlined (Subp) and then not Debug_Flag_Dot_K then + elsif Is_Inlined (Subp) and then not Debug_Flag_Dot_K then Inlined_Subprogram : declare Bod : Node_Id; Must_Inline : Boolean := False; diff --git a/gcc/ada/fe.h b/gcc/ada/fe.h index 9b889ff8da1a..905283fb958b 100644 --- a/gcc/ada/fe.h +++ b/gcc/ada/fe.h @@ -173,6 +173,7 @@ extern Boolean In_Same_Source_Unit (Node_Id, Node_Id); /* opt: */ +#define Back_End_Inlining opt__back_end_inlining #define Exception_Extra_Info opt__exception_extra_info #define Exception_Locations_Suppressed opt__exception_locations_suppressed #define Exception_Mechanism opt__exception_mechanism @@ -182,6 +183,7 @@ extern Boolean In_Same_Source_Unit (Node_Id, Node_Id); typedef enum {Setjmp_Longjmp, Back_End_Exceptions} Exception_Mechanism_Type; +extern Boolean Back_End_Inlining; extern Boolean Exception_Extra_Info; extern Boolean Exception_Locations_Suppressed; extern Exception_Mechanism_Type Exception_Mechanism; diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index 6d83203981d0..e9e634e52286 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -449,7 +449,9 @@ enum inline_status_t /* No inlining is requested for the subprogram. */ is_disabled, /* Inlining is requested for the subprogram. */ - is_enabled + is_enabled, + /* Inlining is required for the subprogram. */ + is_required }; extern GTY(()) tree gnat_std_decls[(int) ADT_LAST]; diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index a9afc53f41f5..fa6f791c452c 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -94,6 +94,7 @@ static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *); static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *); static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *); static tree handle_leaf_attribute (tree *, tree, tree, int, bool *); +static tree handle_always_inline_attribute (tree *, tree, tree, int, bool *); static tree handle_malloc_attribute (tree *, tree, tree, int, bool *); static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *); static tree handle_vector_size_attribute (tree *, tree, tree, int, bool *); @@ -125,6 +126,8 @@ const struct attribute_spec gnat_internal_attribute_table[] = false }, { "leaf", 0, 0, true, false, false, handle_leaf_attribute, false }, + { "always_inline",0, 0, true, false, false, handle_always_inline_attribute, + false }, { "malloc", 0, 0, true, false, false, handle_malloc_attribute, false }, { "type generic", 0, 0, false, true, true, handle_type_generic_attribute, @@ -2715,6 +2718,14 @@ create_subprog_decl (tree subprog_name, tree asm_name, tree subprog_type, case is_disabled: break; + case is_required: + if (Back_End_Inlining) + decl_attributes (&subprog_decl, + tree_cons (get_identifier ("always_inline"), + NULL_TREE, NULL_TREE), + ATTR_FLAG_TYPE_IN_PLACE); + /* ... fall through ... */ + case is_enabled: DECL_DECLARED_INLINE_P (subprog_decl) = 1; DECL_NO_INLINE_WARNING_P (subprog_decl) = artificial_flag; @@ -5790,6 +5801,7 @@ gnat_write_global_declarations (void) TREE_STATIC (dummy_global) = 1; node = varpool_node::get_create (dummy_global); node->definition = 1; + node->definition = 1; node->force_output = 1; while (!types_used_by_cur_var_decl->is_empty ()) @@ -6382,8 +6394,7 @@ handle_noreturn_attribute (tree *node, tree name, tree ARG_UNUSED (args), struct attribute_spec.handler. */ static tree -handle_leaf_attribute (tree *node, tree name, - tree ARG_UNUSED (args), +handle_leaf_attribute (tree *node, tree name, tree ARG_UNUSED (args), int ARG_UNUSED (flags), bool *no_add_attrs) { if (TREE_CODE (*node) != FUNCTION_DECL) @@ -6400,6 +6411,27 @@ handle_leaf_attribute (tree *node, tree name, return NULL_TREE; } +/* Handle a "always_inline" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_always_inline_attribute (tree *node, tree name, tree ARG_UNUSED (args), + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + if (TREE_CODE (*node) == FUNCTION_DECL) + { + /* Set the attribute and mark it for disregarding inline limits. */ + DECL_DISREGARD_INLINE_LIMITS (*node) = 1; + } + else + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + /* Handle a "malloc" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb index 353f6d07d1c7..0f6cc4451e9d 100644 --- a/gcc/ada/gnat1drv.adb +++ b/gcc/ada/gnat1drv.adb @@ -594,6 +594,17 @@ procedure Gnat1drv is end if; end if; + -- No backend inlining for AAMP, VM. Turn off inlining under GNATprove + -- mode which would confuse formal verification output. Turn off backend + -- inlining if the frontend inlining is enabled. + + Back_End_Inlining := + VM_Target = No_VM + and then not AAMP_On_Target + and then not GNATprove_Mode + and then not Front_End_Inlining + and then Debug_Flag_Dot_Z; + -- Output warning if -gnateE specified and cannot be supported if Exception_Extra_Info diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi index 19b4ecc03c73..bbbe553c1bf5 100644 --- a/gcc/ada/gnat_ugn.texi +++ b/gcc/ada/gnat_ugn.texi @@ -19987,6 +19987,10 @@ by hand. Suppresses comment line containing file name and line number of corresponding subprograms in test skeletons. +@item --test-duration +@cindex @option{--test-duration} (@command{gnattest}) +Adds time measurements for each test in generated test driver. + @end table @option{--tests_root}, @option{--subdir} and @option{--tests-dir} switches are diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb index e0357027af5e..b7775b4855f8 100644 --- a/gcc/ada/inline.adb +++ b/gcc/ada/inline.adb @@ -376,6 +376,15 @@ package body Inline is Set_Is_Inlined (Pack); Inlined_Bodies.Increment_Last; Inlined_Bodies.Table (Inlined_Bodies.Last) := Pack; + + -- If the backend takes care of inlining the call then we must + -- ensure that it has available the body of the subprogram. + + elsif Level = Inline_Call + and then Back_End_Inlining + then + Inlined_Bodies.Increment_Last; + Inlined_Bodies.Table (Inlined_Bodies.Last) := Pack; end if; end if; end; @@ -458,11 +467,16 @@ package body Inline is -- subprogram has been generated by the compiler, and if it is declared -- at the library level not in the main unit, and if it can be inlined -- by the back-end, then insert it in the list of inlined subprograms. + -- We also add it when its unit is not inlined but we are compiling with + -- Back_End_Inlining since at this stage we know that Add_Inlined_Body + -- forced loading its unit to allow the backend to inline single calls + -- at -gnatn1 if Is_Inlined (E) and then (Is_Inlined (Pack) or else Is_Generic_Instance (Pack) - or else Is_Internal (E)) + or else Is_Internal (E) + or else Back_End_Inlining) and then not In_Main_Unit_Or_Subunit (E) and then not Is_Nested (E) and then not Has_Initialized_Type (E) @@ -4602,6 +4616,19 @@ package body Inline is Inlined.Release; end Lock; + --------------------------- + -- Register_Backend_Call -- + --------------------------- + + procedure Register_Backend_Call (N : Node_Id) is + begin + if Backend_Calls = No_Elist then + Backend_Calls := New_Elmt_List; + end if; + + Append_Elmt (N, To => Backend_Calls); + end Register_Backend_Call; + -------------------------- -- Remove_Dead_Instance -- -------------------------- diff --git a/gcc/ada/inline.ads b/gcc/ada/inline.ads index 24ffd6ff58f0..34720b432389 100644 --- a/gcc/ada/inline.ads +++ b/gcc/ada/inline.ads @@ -231,6 +231,9 @@ package Inline is -- expressions in the body must be converted to the desired type (which -- is simply not noted in the tree without inline expansion). + procedure Register_Backend_Call (N : Node_Id); + -- Append N to the list Backend_Calls + procedure Remove_Dead_Instance (N : Node_Id); -- If an instantiation appears in unreachable code, delete the pending -- body instance. diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads index dfb2aac86c45..6f79fc12fb9c 100644 --- a/gcc/ada/opt.ads +++ b/gcc/ada/opt.ads @@ -246,6 +246,10 @@ package Opt is -- default can be modified using -gnatd.L (sets the flag True). This is -- used to test the possibility of having the backend handle this. + Back_End_Inlining : Boolean := False; + -- GNAT + -- Set True to activate inlining by back-end expansion + Bind_Alternate_Main_Name : Boolean := False; -- GNATBIND -- True if main should be called Alternate_Main_Name.all. diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb index 6bae214ca3ec..3143a93c82fa 100644 --- a/gcc/ada/sem_ch6.adb +++ b/gcc/ada/sem_ch6.adb @@ -3553,7 +3553,19 @@ package body Sem_Ch6 is -- Old semantics if not Debug_Flag_Dot_K then + + -- If the backend inlining is available then at this stage we only + -- have to mark the subprogram as inlined. The expander will take + -- care of registering it in the table of subprograms inlined by + -- the backend a part of processing calls to it (cf. Expand_Call) + if Present (Spec_Id) + and then Expander_Active + and then Back_End_Inlining + then + Set_Is_Inlined (Spec_Id); + + elsif Present (Spec_Id) and then Expander_Active and then (Has_Pragma_Inline_Always (Spec_Id) diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index abe834c874d4..e0f979bd209c 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -10150,7 +10150,10 @@ package body Sem_Util is -- Otherwise Id denotes an object else - return Is_Volatile (Id) or else Is_Effectively_Volatile (Etype (Id)); + return + Is_Volatile (Id) + or else Has_Volatile_Components (Id) + or else Is_Effectively_Volatile (Etype (Id)); end if; end Is_Effectively_Volatile;