patch that caused regression PR f/9258
Jan Hubicka
jh@suse.cz
Tue Jan 14 20:05:00 GMT 2003
> 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
More information about the Gcc-patches
mailing list