This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RFA: Patch fixing PR/15262
- From: Vladimir Makarov <vmakarov at redhat dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 02 Sep 2004 15:52:05 -0400
- Subject: RFA: Patch fixing PR/15262
The following patch solves PR15262.
The problem is in allocation the same hard register to an
uninitialized pseudo (d) and another pseudo in the following function:
double foo(double *p)
{
double d;
if (d)
bar();
else
d = *p * 2;
return d;
}
Reg-stack is confused because when the uninitialized pseudo dies, it
looks to reg-stack like the other pseudo dies. It results in compiler
crash because reg-stack can not adjust x87 reg stack on an edge.
To solve the problem, the patch prevents modification of live
information based on partial availability for pseudos who can get a
stack register.
The patch was tested by bootstrap on mainline for x86 and itanium.
It looks ok.
Is it ok to commit it into gcc mainline?
Vlad
2004-09-02 Vladimir Makarov <vmakarov@redhat.com>
PR target/15262
* global.c (modify_reg_pav): New function.
(make_accurate_live_analysis): Call the new function. Move pavin
modification by earlyclobber set into the new function.
Index: global.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/global.c,v
retrieving revision 1.105
diff -c -p -r1.105 global.c
*** global.c 12 Jul 2004 18:01:43 -0000 1.105
--- global.c 2 Sep 2004 18:00:23 -0000
*************** static void set_up_bb_rts_numbers (void)
*** 319,324 ****
--- 319,325 ----
static int rpost_cmp (const void *, const void *);
static bool modify_bb_reg_pav (basic_block, basic_block, bool);
static void calculate_reg_pav (void);
+ static void modify_reg_pav (void);
static void make_accurate_live_analysis (void);
*************** calculate_reg_pav (void)
*** 2360,2365 ****
--- 2361,2421 ----
sbitmap_free (wset);
}
+ /* The function modifies partial availability information for two
+ special cases to prevent incorrect work of the subsequent passes
+ with the accurate live information based on the partial
+ availability. */
+
+ static void
+ modify_reg_pav (void)
+ {
+ basic_block bb;
+ struct bb_info *bb_info;
+ #ifdef STACK_REGS
+ int i;
+ HARD_REG_SET zero, stack_hard_regs, used;
+ bitmap stack_regs;
+
+ CLEAR_HARD_REG_SET (zero);
+ CLEAR_HARD_REG_SET (stack_hard_regs);
+ for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
+ SET_HARD_REG_BIT(stack_hard_regs, i);
+ stack_regs = BITMAP_XMALLOC ();
+ for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+ {
+ COPY_HARD_REG_SET (used, reg_class_contents[reg_preferred_class (i)]);
+ IOR_HARD_REG_SET (used, reg_class_contents[reg_alternate_class (i)]);
+ AND_HARD_REG_SET (used, stack_hard_regs);
+ GO_IF_HARD_REG_EQUAL(used, zero, skip);
+ bitmap_set_bit (stack_regs, i);
+ skip:
+ ;
+ }
+ #endif
+ FOR_EACH_BB (bb)
+ {
+ bb_info = BB_INFO (bb);
+
+ /* Reload can assign the same hard register to uninitialized
+ pseudo-register and early clobbered pseudo-register in an
+ insn if the pseudo-register is used first time in given BB
+ and not lived at the BB start. To prevent this we don't
+ change life information for such pseudo-registers. */
+ bitmap_a_or_b (bb_info->pavin, bb_info->pavin, bb_info->earlyclobber);
+ #ifdef STACK_REGS
+ /* We can not use the same stack register for uninitialized
+ pseudo-register and another living pseudo-register because if the
+ uninitialized pseudo-register dies, subsequent pass reg-stack
+ will be confused (it will believe that the other register
+ dies). */
+ bitmap_a_or_b (bb_info->pavin, bb_info->pavin, stack_regs);
+ #endif
+ }
+ #ifdef STACK_REGS
+ BITMAP_XFREE (stack_regs);
+ #endif
+ }
+
/* The following function makes live information more accurate by
modifying global_live_at_start and global_live_at_end of basic
blocks. After the function call a register lives at a program
*************** make_accurate_live_analysis (void)
*** 2379,2394 ****
calculate_local_reg_bb_info ();
set_up_bb_rts_numbers ();
calculate_reg_pav ();
FOR_EACH_BB (bb)
{
bb_info = BB_INFO (bb);
- /* Reload can assign the same hard register to uninitialized
- pseudo-register and early clobbered pseudo-register in an
- insn if the pseudo-register is used first time in given BB
- and not lived at the BB start. To prevent this we don't
- change life information for such pseudo-registers. */
- bitmap_a_or_b (bb_info->pavin, bb_info->pavin, bb_info->earlyclobber);
bitmap_a_and_b (bb->global_live_at_start, bb->global_live_at_start,
bb_info->pavin);
bitmap_a_and_b (bb->global_live_at_end, bb->global_live_at_end,
--- 2435,2445 ----
calculate_local_reg_bb_info ();
set_up_bb_rts_numbers ();
calculate_reg_pav ();
+ modify_reg_pav ();
FOR_EACH_BB (bb)
{
bb_info = BB_INFO (bb);
bitmap_a_and_b (bb->global_live_at_start, bb->global_live_at_start,
bb_info->pavin);
bitmap_a_and_b (bb->global_live_at_end, bb->global_live_at_end,