diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2016-05-02 12:34:16 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2016-05-02 12:34:16 +0200 |
commit | fc3819c9b4924ae0cc0e19826ba27afd4a46f169 (patch) | |
tree | fd24ec6706d1850fce6ff19dacedc77549e9d96f /gcc/ada | |
parent | 494a7e453377c5a99277c217005685203b07615b (diff) | |
download | gcc-fc3819c9b4924ae0cc0e19826ba27afd4a46f169.zip gcc-fc3819c9b4924ae0cc0e19826ba27afd4a46f169.tar.gz gcc-fc3819c9b4924ae0cc0e19826ba27afd4a46f169.tar.bz2 |
[multiple changes]
2016-05-02 Ed Schonberg <schonberg@adacore.com>
* exp_ch6.adb (Expand_Call): When inlining a call to a function
declared in a package instance, locate the instance node of the
package after the actual package declaration. skipping over
pragmas that may have been introduced when the generic unit
carries aspects that are transformed into pragmas.
2016-05-02 Bob Duff <duff@adacore.com>
* s-memory.adb (Alloc, Realloc): Move checks
for Size = 0 or size_t'Last into the Result = System.Null_Address
path for efficiency. Improve comments (based on actual C language
requirements for malloc).
* exp_util.adb (Build_Allocate_Deallocate_Proc): Optimize the
case where we are using the default Global_Pool_Object, and we
don't need the heavy finalization machinery.
From-SVN: r235745
Diffstat (limited to 'gcc/ada')
-rw-r--r-- | gcc/ada/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/ada/exp_ch6.adb | 19 | ||||
-rw-r--r-- | gcc/ada/exp_util.adb | 8 | ||||
-rw-r--r-- | gcc/ada/s-memory.adb | 70 |
4 files changed, 79 insertions, 36 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 2a0ef8d..8764dbb 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,21 @@ +2016-05-02 Ed Schonberg <schonberg@adacore.com> + + * exp_ch6.adb (Expand_Call): When inlining a call to a function + declared in a package instance, locate the instance node of the + package after the actual package declaration. skipping over + pragmas that may have been introduced when the generic unit + carries aspects that are transformed into pragmas. + +2016-05-02 Bob Duff <duff@adacore.com> + + * s-memory.adb (Alloc, Realloc): Move checks + for Size = 0 or size_t'Last into the Result = System.Null_Address + path for efficiency. Improve comments (based on actual C language + requirements for malloc). + * exp_util.adb (Build_Allocate_Deallocate_Proc): Optimize the + case where we are using the default Global_Pool_Object, and we + don't need the heavy finalization machinery. + 2016-05-02 Gary Dismukes <dismukes@adacore.com> * exp_util.ads, sem_ch12.adb: Minor reformatting. diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb index 4c89374..aff75ac 100644 --- a/gcc/ada/exp_ch6.adb +++ b/gcc/ada/exp_ch6.adb @@ -3970,8 +3970,9 @@ package body Exp_Ch6 is and then Optimization_Level > 0 then declare - Inst : Entity_Id; - Decl : Node_Id; + Decl : Node_Id; + Inst : Entity_Id; + Inst_Node : Node_Id; begin Inst := Scope (Subp); @@ -4001,7 +4002,19 @@ package body Exp_Ch6 is null; else - Add_Pending_Instantiation (Next (Decl), Decl); + -- The instantiation node follows the package + -- declaration for the instance. If the generic + -- unit had aspect specifications, they have + -- been transformed into pragmas in the instance, + -- and the instance node appears after them. + + Inst_Node := Next (Decl); + + while Nkind (Inst_Node) /= N_Package_Instantiation loop + Inst_Node := Next (Inst_Node); + end loop; + + Add_Pending_Instantiation (Inst_Node, Decl); end if; end if; end; diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb index 011ccc4..4ea4cb2 100644 --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -584,6 +584,14 @@ package body Exp_Util is elsif Is_RTE (Pool_Id, RE_SS_Pool) then return; + -- Optimize the case where we are using the default Global_Pool_Object, + -- and we don't need the heavy finalization machinery. + + elsif Pool_Id = RTE (RE_Global_Pool_Object) + and then not Needs_Finalization (Desig_Typ) + then + return; + -- Do not replicate the machinery if the allocator / free has already -- been expanded and has a custom Allocate / Deallocate. diff --git a/gcc/ada/s-memory.adb b/gcc/ada/s-memory.adb index b7d37d2..009efa2 100644 --- a/gcc/ada/s-memory.adb +++ b/gcc/ada/s-memory.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2001-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2001-2016, 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- -- @@ -43,14 +43,12 @@ pragma Compiler_Unit_Warning; -with Ada.Exceptions; -with System.Soft_Links; -with System.Parameters; with System.CRTL; +with System.Parameters; +with System.Soft_Links; package body System.Memory is - use Ada.Exceptions; use System.Soft_Links; function c_malloc (Size : System.CRTL.size_t) return System.Address @@ -68,33 +66,41 @@ package body System.Memory is ----------- function Alloc (Size : size_t) return System.Address is - Result : System.Address; - Actual_Size : size_t := Size; - + Result : System.Address; begin - if Size = size_t'Last then - Raise_Exception (Storage_Error'Identity, "object too large"); - end if; - - -- Change size from zero to non-zero. We still want a proper pointer - -- for the zero case because pointers to zero length objects have to - -- be distinct, but we can't just go ahead and allocate zero bytes, - -- since some malloc's return zero for a zero argument. - - if Size = 0 then - Actual_Size := 1; - end if; - if Parameters.No_Abort then - Result := c_malloc (System.CRTL.size_t (Actual_Size)); + Result := c_malloc (System.CRTL.size_t (Size)); else Abort_Defer.all; - Result := c_malloc (System.CRTL.size_t (Actual_Size)); + Result := c_malloc (System.CRTL.size_t (Size)); Abort_Undefer.all; end if; if Result = System.Null_Address then - Raise_Exception (Storage_Error'Identity, "heap exhausted"); + -- If Size = 0, we can't allocate 0 bytes, because then two different + -- allocators, one of which has Size = 0, could return pointers that + -- compare equal, which is wrong. (Nonnull pointers compare equal if + -- and only if they designate the same object, and two different + -- allocators allocate two different objects). + + -- malloc(0) is defined to allocate a non-zero-sized object (in which + -- case we won't get here, and all is well) or NULL, in which case we + -- get here. We also get here in case of error. So check for the + -- zero-size case, and allocate 1 byte. Otherwise, raise + -- Storage_Error. + + -- We check for zero size here, rather than at the start, for + -- efficiency. + + if Size = 0 then + return Alloc (1); + end if; + + if Size = size_t'Last then + raise Storage_Error with "object too large"; + end if; + + raise Storage_Error with "heap exhausted"; end if; return Result; @@ -125,23 +131,21 @@ package body System.Memory is return System.Address is Result : System.Address; - Actual_Size : constant size_t := Size; - begin - if Size = size_t'Last then - Raise_Exception (Storage_Error'Identity, "object too large"); - end if; - if Parameters.No_Abort then - Result := c_realloc (Ptr, System.CRTL.size_t (Actual_Size)); + Result := c_realloc (Ptr, System.CRTL.size_t (Size)); else Abort_Defer.all; - Result := c_realloc (Ptr, System.CRTL.size_t (Actual_Size)); + Result := c_realloc (Ptr, System.CRTL.size_t (Size)); Abort_Undefer.all; end if; if Result = System.Null_Address then - Raise_Exception (Storage_Error'Identity, "heap exhausted"); + if Size = size_t'Last then + raise Storage_Error with "object too large"; + end if; + + raise Storage_Error with "heap exhausted"; end if; return Result; |