This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Move ehcleanup pass to before early SRA


Hi,

we have run into optimization regressions in Ada caused by the interaction 
between the GIMPLE clobbers and SRA: on the one hand GIMPLE clobbers create 
artificial EH handlers for aggregate variables, on the other hand SRA refuses 
to scalarize objects that appear in a statement that can throw internally.  
The result is that GIMPLE clobbers block the scalarization of variables that 
used to be possible up to the 4.6 series.  Testcase attached, compile p.adb on 
x86-64 with -O2 -fdump-tree-ealias -fdump-tree-esra.

This can be solved by moving the ehcleanup pass to before early SRA in 
the pipeline.  It has a small but measurable positive effect on some of our 
benchmarks (with a 4.7-based compiler).  Tested on x86-64/Linux.

Thoughts?


2014-01-15  Eric Botcazou  <ebotcazou@adacore.com>

	* passes.def (pass_early_local_passes): Run first EH cleanup pass early.


-- 
Eric Botcazou
Index: passes.def
===================================================================
--- passes.def	(revision 206563)
+++ passes.def	(working copy)
@@ -71,6 +71,10 @@ along with GCC; see the file COPYING3.
 	  /* pass_build_ealias is a dummy pass that ensures that we
 	     execute TODO_rebuild_alias at this point.  */
 	  NEXT_PASS (pass_build_ealias);
+	  /* SRA refuses to scalarize objects that appear in a statement
+	     that can throw internally so we need to cleanup the EH tree
+	     early to remove handlers that contain only clobbers.  */
+	  NEXT_PASS (pass_cleanup_eh);
 	  NEXT_PASS (pass_sra_early);
 	  NEXT_PASS (pass_fre);
 	  NEXT_PASS (pass_copy_prop);
@@ -79,7 +83,6 @@ along with GCC; see the file COPYING3.
 	  NEXT_PASS (pass_early_ipa_sra);
 	  NEXT_PASS (pass_tail_recursion);
 	  NEXT_PASS (pass_convert_switch);
-          NEXT_PASS (pass_cleanup_eh);
           NEXT_PASS (pass_profile);
           NEXT_PASS (pass_local_pure_const);
 	  /* Split functions creates parts that are not run through
with Decls_Pack_2;  use Decls_Pack_2;
with Decls_Support; use Decls_Support;
with Support;       use Support;

procedure P is
   package Decls_Pack_Private is new Decls_Pack_Private_G;
   use Decls_Pack_Private;
begin
   Assert (Get_Integer (Decls_Pack_Private.Local_Fun (Get_Private (1))) = 100);
end;
package body Decls_Pack_2 is

   procedure Local_Swap (V1, V2 : in out Access_Integer) is
      Tmp : Access_Integer := V1;
   begin
      V1  := V2;
      V2  := Tmp;
   end Local_Swap;

   function Local_Fun (I : Integer) return Access_Const_Integer is
      Result : Access_Const_Integer := new Integer'(I);
   begin

      if I < 0 then
        Result := null;
      end if;

      return Result;
   end Local_Fun;


   package body Decls_Pack_Derived_Records_G is

      procedure Local_Swap (V1, V2 : in out Derived_Coordinate) is
         Tmp : Derived_Coordinate;
      begin
         if V1 /= V2 then
            Tmp := V1;
            V1  := V2;
            V2  := Tmp;
         end if;
      end Local_Swap;

      function Local_Fun (C1, C2 : Float) return Derived_Coordinate is
         Result : Derived_Coordinate;
      begin

         if C1 > 0.0 and then C2 > 0.0 then
           Result.X := C1;
           Result.Y := C2;
         end if;

         return Result;
      end Local_Fun;

   end Decls_Pack_Derived_Records_G;

   package body Decls_Pack_Private_G is

      procedure Local_Swap (V1, V2 : in out T_Private) is
         Tmp : T_Private := V1;
      begin
         V1 := V2;
         V2 := Tmp;
      end Local_Swap;

      function Local_Fun (Arg : T_Private) return T_Private is
         Result : T_Private;
      begin

         case Get_Integer (Arg) is
            when 1 =>
               Result := Get_Private (100);
            when 2 =>
               Result := T_Private_Zero;
            when others =>
               null;
         end case;

         return Result;
      end Local_Fun;

   end Decls_Pack_Private_G;

end Decls_Pack_2;
with Decls_Support; use Decls_Support;
with Support;       use Support;
package Decls_Pack_2 is

   Access_All_Integer_Var : Access_All_Integer := Integer_Var'Access;

   I : Integer := Identity (1);

   procedure Local_Swap (V1, V2 : in out Access_Integer);

   function Local_Fun (I : Integer) return Access_Const_Integer;

   generic
   package Decls_Pack_Derived_Records_G is

      Derived_Discrete_Coordinate_V : Derived_Discrete_Coordinate;

      procedure Local_Swap (V1, V2 : in out Derived_Coordinate);

      function Local_Fun (C1, C2 : Float) return Derived_Coordinate;
   end Decls_Pack_Derived_Records_G;

   generic
   package Decls_Pack_Private_G is

      T_Private_C : constant T_Private := T_Private_Zero;

      procedure Local_Swap (V1, V2 : in out T_Private);

      function Local_Fun (Arg : T_Private) return T_Private;
   end Decls_Pack_Private_G;

end Decls_Pack_2;
with Support; use Support;
package Decls_Support is

   type Week_Day is (Mon, Tue, Wen, Thu, Fri, Sat, Sun);

   subtype Index is Natural range 0 .. 100;

   type Var_String (Len : Index := 0) is record
      Data : String (1 .. Len);
   end record;

   type Coordinate is record
      X, Y : Float := 0.0;
   end record;

   Coordinate_Zero : constant Coordinate := (X => 0.0, Y => 0.0);

   type Discrete_Coordinate is record
      X : Integer := Identity (0);
      Y : Integer := Identity (0);
   end record;

   type Vector is array (Integer range <>) of Integer;

   type Matrix is array (Integer range <>, Integer range <>) of Integer;
   subtype Small_Matrix is Matrix (1 .. 2, 1 .. 2);

   type T_Private is private;
   T_Private_Zero : constant T_Private;

   function Get_Private (I : Integer) return T_Private;
   function Get_Integer (X : T_Private) return Integer;
   type Access_Integer is access Integer;
   type Access_All_Integer is access all Integer;
   type Access_Const_Integer is access constant Integer;
   type Access_Coordinate is access Coordinate;

   type Derived_Discrete_Coordinate is new Discrete_Coordinate;
   type Derived_Coordinate is new Coordinate;

   Integer_Var : aliased Integer := 1;

private
   type T_Private is record
      I : Integer := 0;
   end record;

   T_Private_Zero : constant T_Private := (I => 0);

end Decls_Support;
package Support is
   procedure Assert (Cond : Boolean);
   function Identity (X : Integer) return Integer;
   function Identity (B : Boolean) return Boolean;

   function Value (X : Integer) return Integer renames Identity;
   function Value (B : Boolean) return Boolean renames Identity;
end;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]