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]

Don't allocate call-clobbered hard regs over abnormal edges


We get an ICE in insert_insns_on_edge on Alpha/VMS for the following Ada
testcase.  A discussion a while ago on the GCC list suggested this as the
best fix.

Tested on i686-pc-linux-gnu.

with Ada.Finalization;

package body Bug is

    type Request_Class_Type is (Connect);

    type Cont_1 is new Ada.Finalization.Controlled with null record;

    type Msg_4 is new Ada.Finalization.Controlled with null record;

    type Msg_1 (Request_Class : Request_Class_Type := Connect) is
    record
        X1 : Integer := 0;
        X2 : Integer := 0;
        X3 : Integer := 0;
        XX : Msg_4;
    end record;

    procedure Get_4 (Flow, Format, Stream : in Cont_1; Data : out Integer) is
    begin
        Data := 0;
    end Get_4;

    procedure Get_3 (Data : out Request_Class_Type) is
    begin
        Data := Connect;
    end Get_3;

    function Get_2 (Flow, Format, Stream : access Cont_1) return Msg_4 is
        Tmp : Msg_4;
    begin
        return Tmp;
    end Get_2;

    function Get_1 (Flow, Format, Stream : access Cont_1) return Msg_1 is
        X1 : Integer;
        X2 : Integer;
        X3 : Integer;
        X4 : Integer;
        X5 : Integer;
        Request_Class : Request_Class_Type;
    begin

        begin
            Get_4 (Flow.all, Format.all, Stream.all, X1);
        exception
            when Constraint_Error => null;
        end;

        begin
            Get_4 (Flow.all, Format.all, Stream.all, X2);
        exception
            when Constraint_Error => null;
        end;

        begin
            Get_4 (Flow.all, Format.all, Stream.all, X3);
        exception
            when Constraint_Error => null;
        end;

        begin
            Get_4 (Flow.all, Format.all, Stream.all, X4);
        exception
            when Constraint_Error => null;
        end;

        begin
            Get_4 (Flow.all, Format.all, Stream.all, X5);
        exception
            when Constraint_Error => null;
        end;

        begin
            Get_3 (Request_Class);
        exception
            when Constraint_Error => null;
        end;

        declare
            Tmp : Msg_1 (Connect);
        begin
            Tmp.X1 := X1;
            Tmp.X2 := X2;
            Tmp.X3 := X3;
            Tmp.XX := Get_2 (Flow, Format, Stream);
            return Tmp;
        end;

    exception
        when others =>
            declare
                Tmp : Msg_1 (Connect);
            begin
                return Tmp;
            end;
    end Get_1;

end Bug;
package Bug is
    pragma Elaborate_Body;
end Bug;

2003-04-14  Olivier Hainque <hainque at act-europe dot fr>

	* global.c (global_conflicts): Prevent allocation of call clobbered
	hard regs to pseudos live across abnormal edges, as later passes are
	not ready to handle them.

*** gcc/global.c.ori	25 Jan 2003 14:42:49 -0000	1.77.8.1
--- gcc/global.c	27 Jan 2003 14:01:44 -0000
*************** global_conflicts ()
*** 712,737 ****
  	    scan the instruction that makes either X or Y become live.  */
  	record_conflicts (block_start_allocnos, ax);
  
! #ifdef STACK_REGS
! 	{
! 	  /* Pseudos can't go in stack regs at the start of a basic block
! 	     that is reached by an abnormal edge.  */
  
  	  edge e;
  	  for (e = BASIC_BLOCK (b)->pred; e ; e = e->pred_next)
  	    if (e->flags & EDGE_ABNORMAL)
  	      break;
  	  if (e != NULL)
              {
                EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, ax,
                  {
                    allocno[ax].no_stack_reg = 1;
                  });
                for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++)
                  record_one_conflict (ax);
              }
  	}
- #endif
        }
  
        insn = BLOCK_HEAD (b);
--- 712,749 ----
  	    scan the instruction that makes either X or Y become live.  */
  	record_conflicts (block_start_allocnos, ax);
  
!  	/* Pseudos can't go in stack regs at the start of a basic block that
!  	   is reached by an abnormal edge. Ditto for call clobbered regs,
!  	   because because caller-save, fixup_abnormal_edges, and possibly the
!  	   table driven EH machinery are not quite ready to handle such regs
!  	   live across such edges.  */
  
+ 	{
  	  edge e;
  	  for (e = BASIC_BLOCK (b)->pred; e ; e = e->pred_next)
  	    if (e->flags & EDGE_ABNORMAL)
  	      break;
+ 
  	  if (e != NULL)
              {
+ #ifdef STACK_REGS
                EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, ax,
                  {
                    allocno[ax].no_stack_reg = 1;
                  });
                for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++)
                  record_one_conflict (ax);
+ #endif
+ 
+ 	      /* No need to record conflicts for call clobbered regs if we have
+ 		 nonlocal labels around, as we don't ever try to allocate such
+ 		 regs in this case.  */
+ 	      if (! current_function_has_nonlocal_label)
+ 		for (ax = 0; ax < FIRST_PSEUDO_REGISTER; ax ++)
+ 		  if (call_used_regs [ax])
+ 		    record_one_conflict (ax);
              }
  	}
        }
  
        insn = BLOCK_HEAD (b);


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