This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: patch that caused regression PR f/9258
- From: Jan Hubicka <jh at suse dot cz>
- To: Janis Johnson <janis187 at us dot ibm dot com>, gcc-patches at gcc dot gnu dot org,rth at cygnus dot com
- Cc: gcc at gcc dot gnu dot org, jh at suse dot cz
- Date: Tue, 14 Jan 2003 21:05:15 +0100
- Subject: Re: patch that caused regression PR f/9258
- References: <20030114095503.A23671@us.ibm.com>
> The regression reported in PR f/9258 ([3.2/3.3/3.4 regression] ICE in
> compensate_edge, at reg-stack.c:2589) showed up with this patch:
>
> Sat Jun 23 01:23:59 CEST 2001 Jan Hubicka <jh@suse.cz>
>
> * flow.c (mark_set_1, attempt_auto_inc, mark_used_reg,
> try_pre_increment_1): compute REG_FREQ using bb->frequency.
>
> * regclass.c (loop_cost): Kill.
> (frequency): New global variable.
> (record_operand_costs): Replace loop_cost by frequency.
> (scan_one_insn): Likewise.
> (regclass): Likewise; set frequency according to bb->frequency.
>
> * flow.c (split_edge): Set frequency.
>
> I used the minimized test case from the PR and got the same ICE message.
> This information has been added to the PR.
>
> Janis
Hi,
the problem is that register allocator produces stack register live across
abnormal edge. This is because it decides to ignore the conflict with stack
register added for this reason believing that it is just local alloc stupidity
- funny feature.
Only way around this I found is the attached patch.
SUBROUTINE FOO (B)
10 CALL BAR(A)
ASSIGN 20 TO M
IF(100.LT.A) GOTO 10
GOTO 40
C
20 IF(B.LT.ABS(A)) GOTO 10
ASSIGN 30 TO M
GOTO 40
C
30 ASSIGN 10 TO M
40 GOTO M,(10,20,30)
END
Tue Jan 14 23:04:44 CET 2003 Jan Hubicka <jh@suse.cz>
* global.c (struct allocno): Add no_stack_reg.
(global_conflicts): Set no_stack_reg.
(find_reg): Use it.
*** global.c.old Tue Jan 14 23:04:16 2003
--- global.c Tue Jan 14 23:04:20 2003
*************** struct allocno
*** 130,135 ****
--- 130,140 ----
/* Set of hard registers that some later allocno has a preference for. */
HARD_REG_SET regs_someone_prefers;
+
+ #ifdef STACK_REGS
+ /* Set to true if allocno can't be allocated in the stack register. */
+ bool no_stack_reg;
+ #endif
};
static struct allocno *allocno;
*************** global_conflicts ()
*** 706,713 ****
if (e->flags & EDGE_ABNORMAL)
break;
if (e != NULL)
! for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++)
! record_one_conflict (ax);
}
#endif
}
--- 711,724 ----
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
}
*************** find_reg (num, losers, alt_regs_p, accep
*** 1206,1211 ****
--- 1217,1226 ----
(reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
regno)))
#endif
+ #ifdef STACK_REGS
+ && (!allocno[num].no_stack_reg
+ || regno < FIRST_STACK_REG || regno > LAST_STACK_REG)
+ #endif
)
{
/* We explicitly evaluate the divide results into temporary