Fix liveness analysis in lra for spilled-into hard regs
authorTom de Vries <tom@codesourcery.com>
Thu, 1 Mar 2018 05:51:08 +0000 (05:51 +0000)
committerTom de Vries <vries@gcc.gnu.org>
Thu, 1 Mar 2018 05:51:08 +0000 (05:51 +0000)
2018-03-01  Tom de Vries  <tom@codesourcery.com>

PR rtl-optimization/83327
* lra-int.h (hard_regs_spilled_into): Declare.
* lra.c (hard_regs_spilled_into): Define.
(init_reg_info): Init hard_regs_spilled_into.
* lra-spills.c (assign_spill_hard_regs): Update hard_regs_spilled_into.
* lra-lives.c (make_hard_regno_born, make_hard_regno_dead)
(process_bb_lives): Handle hard_regs_spilled_into.
(lra_create_live_ranges_1): Before doing liveness propagation, clear
regs in all_hard_regs_bitmap if set in hard_regs_spilled_into.

From-SVN: r258093

gcc/ChangeLog
gcc/lra-int.h
gcc/lra-lives.c
gcc/lra-spills.c
gcc/lra.c

index 7d9b0e14005b6a7622bb30506aa8fea9c20f21c2..0a07f4b0a92151d9136fae096dee59451951a94e 100644 (file)
@@ -1,3 +1,15 @@
+2018-03-01  Tom de Vries  <tom@codesourcery.com>
+
+       PR rtl-optimization/83327
+       * lra-int.h (hard_regs_spilled_into): Declare.
+       * lra.c (hard_regs_spilled_into): Define.
+       (init_reg_info): Init hard_regs_spilled_into.
+       * lra-spills.c (assign_spill_hard_regs): Update hard_regs_spilled_into.
+       * lra-lives.c (make_hard_regno_born, make_hard_regno_dead)
+       (process_bb_lives): Handle hard_regs_spilled_into.
+       (lra_create_live_ranges_1): Before doing liveness propagation, clear
+       regs in all_hard_regs_bitmap if set in hard_regs_spilled_into.
+
 2018-02-28  David Edelsohn  <dje.gcc@gmail.com>
 
        * config.gcc (powerpc-ibm-aix7.1.*): New stanza.
index 03839187cf6109f0c84e98e5be1158302264037e..509e29ec4b864f20ff9c114d5cadc17d3cf5997c 100644 (file)
@@ -122,6 +122,8 @@ struct lra_reg
 /* References to the common info about each register.  */
 extern struct lra_reg *lra_reg_info;
 
+extern HARD_REG_SET hard_regs_spilled_into;
+
 /* Static info about each insn operand (common for all insns with the
    same ICODE).         Warning: if the structure definition is changed, the
    initializer for debug_operand_data in lra.c should be changed
index ddc0a9bbcc5176b1fa3d09b6e8df9b9be2e34f1d..588bc09cb8e61b2d33320990c7efa3d8ae8672a0 100644 (file)
@@ -246,7 +246,7 @@ make_hard_regno_born (int regno, bool check_pic_pseudo_p ATTRIBUTE_UNUSED)
        || i != REGNO (pic_offset_table_rtx))
 #endif
       SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno);
-  if (fixed_regs[regno])
+  if (fixed_regs[regno] || TEST_HARD_REG_BIT (hard_regs_spilled_into, regno))
     bitmap_set_bit (bb_gen_pseudos, regno);
 }
 
@@ -260,7 +260,7 @@ make_hard_regno_dead (int regno)
     return;
   sparseset_set_bit (start_dying, regno);
   CLEAR_HARD_REG_BIT (hard_regs_live, regno);
-  if (fixed_regs[regno])
+  if (fixed_regs[regno] || TEST_HARD_REG_BIT (hard_regs_spilled_into, regno))
     {
       bitmap_clear_bit (bb_gen_pseudos, regno);
       bitmap_set_bit (bb_killed_pseudos, regno);
@@ -1062,6 +1062,25 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
        check_pseudos_live_through_calls (j, last_call_used_reg_set);
     }
 
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
+    {
+      if (!TEST_HARD_REG_BIT (hard_regs_live, i))
+       continue;
+
+      if (!TEST_HARD_REG_BIT (hard_regs_spilled_into, i))
+       continue;
+
+      if (bitmap_bit_p (df_get_live_in (bb), i))
+       continue;
+
+      live_change_p = true;
+      if (lra_dump_file)
+       fprintf (lra_dump_file,
+                "  hard reg r%d is added to live at bb%d start\n", i,
+                bb->index);
+      bitmap_set_bit (df_get_live_in (bb), i);
+    }
+
   if (need_curr_point_incr)
     next_program_point (curr_point, freq);
 
@@ -1331,6 +1350,11 @@ lra_create_live_ranges_1 (bool all_p, bool dead_insn_p)
        }
       /* As we did not change CFG since LRA start we can use
         DF-infrastructure solver to solve live data flow problem.  */
+      for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
+       {
+         if (TEST_HARD_REG_BIT (hard_regs_spilled_into, i))
+           bitmap_clear_bit (&all_hard_regs_bitmap, i);
+       }
       df_simple_dataflow
        (DF_BACKWARD, NULL, live_con_fun_0, live_con_fun_n,
         live_trans_fun, &all_blocks,
index 8f6278acae42edabd78f5f188ce627d81e1acedc..33caf9f4564953c9e0bdc78ee00fcfbfa7aa2ed1 100644 (file)
@@ -294,6 +294,8 @@ assign_spill_hard_regs (int *pseudo_regnos, int n)
        }
       if (lra_dump_file != NULL)
        fprintf (lra_dump_file, "  Spill r%d into hr%d\n", regno, hard_regno);
+      add_to_hard_reg_set (&hard_regs_spilled_into,
+                          lra_reg_info[regno].biggest_mode, hard_regno);
       /* Update reserved_hard_regs.  */
       for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
        for (p = r->start; p <= r->finish; p++)
index 08de09d14dd17c4a159cfe23b5f132333aa9391a..a64d8f1a3011eca2686fb210bcde77e658f3daee 100644 (file)
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -1289,6 +1289,8 @@ static int reg_info_size;
 /* Common info about each register.  */
 struct lra_reg *lra_reg_info;
 
+HARD_REG_SET hard_regs_spilled_into;
+
 /* Last register value.         */
 static int last_reg_value;
 
@@ -1338,6 +1340,7 @@ init_reg_info (void)
   for (i = 0; i < reg_info_size; i++)
     initialize_lra_reg_info_element (i);
   copy_vec.truncate (0);
+  CLEAR_HARD_REG_SET (hard_regs_spilled_into);
 }