public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Ada] fix undue pessimization wrt Pure subprograms
@ 2008-11-13 14:57 Olivier Hainque
  0 siblings, 0 replies; only message in thread
From: Olivier Hainque @ 2008-11-13 14:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: hainque

[-- Attachment #1: Type: text/plain, Size: 1346 bytes --]

Hello,

We rediscussed the Ada language reference manual bits about "pragma
Pure" and decided to revisit the orientation taken in

   http://gcc.gnu.org/ml/gcc-patches/2008-08/msg00029.html

In particular, we are now of the opinion that

  << 18/2 If a library unit is declared pure, then the implementation is
          permitted to omit a call on a library-level subprogram of
          the library unit if the results are not needed after the call.
  >>

allows us to omit a call to a Pure subprogram possibly raising an
exception even if there is an exception handler, as in 

    procedure handle_raise_from_pure is
       K : Integer;
    begin
       K := Raise_CE_If_0 (0);
    exception
       when others => Put_Line ("exception caught");
    end;

This patch re-activates and tidies the code controling this, which
cures a regression in optimization opportunities.

Bootstrapped and regtested on x86_64-suse-linux.

Olivier

	2008-11-13  Olivier Hainque  <hainque@adacore.com>

	ada/
	* gcc-interface/decl.c (gnat_to_gnu_entity) <case E_Function>:
	Turn Ada Pure on subprograms back into GCC CONST when eh constructs
	are explicit to the back-end.  Tidy.

	testsuite/
	* gnat.dg/test_raise_from_pure.adb: Adjust to match revised intent.
	* gnat.dg/wrap_raise_from_pure.ad[bs]: Remove.
	* gnat.dg/handle_raise_from_pure.adb: New test.


[-- Attachment #2: pure-const.dif --]
[-- Type: text/plain, Size: 6200 bytes --]

Index: ada/gcc-interface/decl.c
===================================================================
*** ada/gcc-interface/decl.c	(revision 141734)
--- ada/gcc-interface/decl.c	(working copy)
*************** gnat_to_gnu_entity (Entity_Id gnat_entit
*** 3739,3745 ****
  	bool public_flag = Is_Public (gnat_entity) || imported_p;
  	bool extern_flag
  	  = (Is_Public (gnat_entity) && !definition) || imported_p;
! 	bool pure_flag = Is_Pure (gnat_entity);
  	bool volatile_flag = No_Return (gnat_entity);
  	bool returns_by_ref = false;
  	bool returns_unconstrained = false;
--- 3739,3757 ----
  	bool public_flag = Is_Public (gnat_entity) || imported_p;
  	bool extern_flag
  	  = (Is_Public (gnat_entity) && !definition) || imported_p;
! 
!        /* The semantics of "pure" in Ada essentially matches that of "const"
!           in the back-end.  In particular, both properties are orthogonal to
!           the "nothrow" property if the EH circuitry is explicit in the
!           internal representation of the back-end.  If we are to completely
!           hide the EH circuitry from it, we need to declare that calls to pure
!           Ada subprograms that can throw have side effects since they can
!           trigger an "abnormal" transfer of control flow; thus they can be
!           neither "const" nor "pure" in the back-end sense.  */
! 	bool const_flag
! 	  = (Exception_Mechanism == Back_End_Exceptions
! 	     && Is_Pure (gnat_entity));
! 
  	bool volatile_flag = No_Return (gnat_entity);
  	bool returns_by_ref = false;
  	bool returns_unconstrained = false;
*************** gnat_to_gnu_entity (Entity_Id gnat_entit
*** 3972,3983 ****
  
  		/* If a parameter is a pointer, this function may modify
  		   memory through it and thus shouldn't be considered
! 		   a pure function.  Also, the memory may be modified
  		   between two calls, so they can't be CSE'ed.  The latter
  		   case also handles by-ref parameters.  */
  		if (POINTER_TYPE_P (gnu_param_type)
  		    || TYPE_FAT_POINTER_P (gnu_param_type))
! 		  pure_flag = false;
  	      }
  
  	    if (copy_in_copy_out)
--- 3984,3995 ----
  
  		/* If a parameter is a pointer, this function may modify
  		   memory through it and thus shouldn't be considered
! 		   a const function.  Also, the memory may be modified
  		   between two calls, so they can't be CSE'ed.  The latter
  		   case also handles by-ref parameters.  */
  		if (POINTER_TYPE_P (gnu_param_type)
  		    || TYPE_FAT_POINTER_P (gnu_param_type))
! 		  const_flag = false;
  	      }
  
  	    if (copy_in_copy_out)
*************** gnat_to_gnu_entity (Entity_Id gnat_entit
*** 4054,4074 ****
  				   returns_by_ref, returns_by_target_ptr);
  
  	/* A subprogram (something that doesn't return anything) shouldn't
! 	   be considered Pure since there would be no reason for such a
  	   subprogram.  Note that procedures with Out (or In Out) parameters
  	   have already been converted into a function with a return type. */
  	if (TREE_CODE (gnu_return_type) == VOID_TYPE)
! 	  pure_flag = false;
! 
! 	/* The semantics of "pure" in Ada used to essentially match that of
! 	   "const" in the middle-end.  In particular, both properties were
! 	   orthogonal to the "nothrow" property.  This is not true in the
! 	   middle-end any more and we have no choice but to ignore the hint
! 	   at this stage.  */
  
  	gnu_type
  	  = build_qualified_type (gnu_type,
  				  TYPE_QUALS (gnu_type)
  				  | (TYPE_QUAL_VOLATILE * volatile_flag));
  
  	Sloc_to_locus (Sloc (gnat_entity), &input_location);
--- 4066,4081 ----
  				   returns_by_ref, returns_by_target_ptr);
  
  	/* A subprogram (something that doesn't return anything) shouldn't
! 	   be considered const since there would be no reason for such a
  	   subprogram.  Note that procedures with Out (or In Out) parameters
  	   have already been converted into a function with a return type. */
  	if (TREE_CODE (gnu_return_type) == VOID_TYPE)
! 	  const_flag = false;
  
  	gnu_type
  	  = build_qualified_type (gnu_type,
  				  TYPE_QUALS (gnu_type)
+ 				  | (TYPE_QUAL_CONST * const_flag)
  				  | (TYPE_QUAL_VOLATILE * volatile_flag));
  
  	Sloc_to_locus (Sloc (gnat_entity), &input_location);
*************** gnat_to_gnu_entity (Entity_Id gnat_entit
*** 4077,4084 ****
  	  gnu_stub_type
  	    = build_qualified_type (gnu_stub_type,
  				    TYPE_QUALS (gnu_stub_type)
! 				    | (Exception_Mechanism == Back_End_Exceptions
! 				       ? TYPE_QUAL_CONST * pure_flag : 0)
  				    | (TYPE_QUAL_VOLATILE * volatile_flag));
  
  	/* If we have a builtin decl for that function, check the signatures
--- 4084,4090 ----
  	  gnu_stub_type
  	    = build_qualified_type (gnu_stub_type,
  				    TYPE_QUALS (gnu_stub_type)
! 				    | (TYPE_QUAL_CONST * const_flag)
  				    | (TYPE_QUAL_VOLATILE * volatile_flag));
  
  	/* If we have a builtin decl for that function, check the signatures
Index: testsuite/gnat.dg/handle_raise_from_pure.adb
===================================================================
*** testsuite/gnat.dg/handle_raise_from_pure.adb	(revision 0)
--- testsuite/gnat.dg/handle_raise_from_pure.adb	(revision 0)
***************
*** 0 ****
--- 1,11 ----
+ --  { dg-do run }
+ --  { dg-options "-O2" }
+ with Ada.Text_Io; use Ada.Text_IO;
+ with Raise_From_Pure; use Raise_From_Pure;
+ procedure handle_raise_from_pure is
+    K : Integer;
+ begin
+    K := Raise_CE_If_0 (0);
+ exception
+    when others => Put_Line ("exception caught");
+ end;
Index: testsuite/gnat.dg/test_raise_from_pure.adb
===================================================================
*** testsuite/gnat.dg/test_raise_from_pure.adb	(revision 141259)
--- testsuite/gnat.dg/test_raise_from_pure.adb	(working copy)
***************
*** 1,9 ****
  --  { dg-do run }
  --  { dg-options "-O2" }
! with Wrap_Raise_From_Pure; use Wrap_Raise_From_Pure;
  procedure test_raise_from_pure is
  begin
!    Wrap_Raise_From_Pure.Check;
! exception
!    when Constraint_Error => null;
  end;
--- 1,8 ----
  --  { dg-do run }
  --  { dg-options "-O2" }
! with Raise_From_Pure; use Raise_From_Pure;
  procedure test_raise_from_pure is
+    K : Integer;
  begin
!    K := Raise_CE_If_0 (0);
  end;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-11-13 14:25 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-11-13 14:57 [Ada] fix undue pessimization wrt Pure subprograms Olivier Hainque

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).