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]

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,

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