This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Don't allocate call-clobbered hard regs over abnormal edges
- From: kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner)
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 14 Apr 03 17:58:00 EDT
- Subject: 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);