refactor SLP constant insertion and provde entry insert helper
[gcc.git] / gcc / lra-lives.c
index 40e9f66f3b11a4a57a1f270e2f037024b05cb675..917c617903f29d4390e87437ad1dfd2755caeb33 100644 (file)
@@ -1,5 +1,5 @@
 /* Build live ranges for pseudos.
-   Copyright (C) 2010-2019 Free Software Foundation, Inc.
+   Copyright (C) 2010-2020 Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
 This file is part of GCC.
@@ -281,7 +281,8 @@ static void
 make_hard_regno_live (int regno)
 {
   lra_assert (HARD_REGISTER_NUM_P (regno));
-  if (TEST_HARD_REG_BIT (hard_regs_live, regno))
+  if (TEST_HARD_REG_BIT (hard_regs_live, regno)
+      || TEST_HARD_REG_BIT (eliminable_regset, regno))
     return;
   SET_HARD_REG_BIT (hard_regs_live, regno);
   sparseset_set_bit (start_living, regno);
@@ -295,6 +296,9 @@ make_hard_regno_live (int regno)
 static void
 make_hard_regno_dead (int regno)
 {
+  if (TEST_HARD_REG_BIT (eliminable_regset, regno))
+    return;
+
   lra_assert (HARD_REGISTER_NUM_P (regno));
   unsigned int i;
   EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i)
@@ -576,40 +580,21 @@ lra_setup_reload_pseudo_preferenced_hard_reg (int regno,
     }
 }
 
-/* Check that REGNO living through calls and setjumps, set up conflict
-   regs using LAST_CALL_USED_REG_SET, and clear corresponding bits in
-   PSEUDOS_LIVE_THROUGH_CALLS and PSEUDOS_LIVE_THROUGH_SETJUMPS.
-   CALL_INSN is a call that is representative of all calls in the region
-   described by the PSEUDOS_LIVE_THROUGH_* sets, in terms of the registers
-   that it preserves and clobbers.  */
+/* Check whether REGNO lives through calls and setjmps and clear
+   the corresponding bits in PSEUDOS_LIVE_THROUGH_CALLS and
+   PSEUDOS_LIVE_THROUGH_SETJUMPS.  All calls in the region described
+   by PSEUDOS_LIVE_THROUGH_CALLS have the given ABI.  */
 
 static inline void
-check_pseudos_live_through_calls (int regno,
-                                 HARD_REG_SET last_call_used_reg_set,
-                                 rtx_insn *call_insn)
+check_pseudos_live_through_calls (int regno, const function_abi &abi)
 {
-  int hr;
-  rtx_insn *old_call_insn;
-
   if (! sparseset_bit_p (pseudos_live_through_calls, regno))
     return;
 
-  function_abi callee_abi = insn_callee_abi (call_insn);
-  old_call_insn = lra_reg_info[regno].call_insn;
-  if (!old_call_insn
-      || (targetm.return_call_with_max_clobbers
-         && targetm.return_call_with_max_clobbers (old_call_insn, call_insn)
-            == call_insn))
-    lra_reg_info[regno].call_insn = call_insn;
+  machine_mode mode = PSEUDO_REGNO_MODE (regno);
 
   sparseset_clear_bit (pseudos_live_through_calls, regno);
-  lra_reg_info[regno].conflict_hard_regs |= last_call_used_reg_set;
-
-  for (hr = 0; HARD_REGISTER_NUM_P (hr); hr++)
-    if (targetm.hard_regno_call_part_clobbered (callee_abi.id (), hr,
-                                               PSEUDO_REGNO_MODE (regno)))
-      add_to_hard_reg_set (&lra_reg_info[regno].conflict_hard_regs,
-                          PSEUDO_REGNO_MODE (regno), hr);
+  lra_reg_info[regno].conflict_hard_regs |= abi.mode_clobbers (mode);
   if (! sparseset_bit_p (pseudos_live_through_setjumps, regno))
     return;
   sparseset_clear_bit (pseudos_live_through_setjumps, regno);
@@ -630,19 +615,6 @@ reg_early_clobber_p (const struct lra_insn_reg *reg, int n_alt)
             && TEST_BIT (reg->early_clobber_alts, n_alt)));
 }
 
-/* Return true if call instructions CALL1 and CALL2 use ABIs that
-   preserve the same set of registers.  */
-
-static bool
-calls_have_same_clobbers_p (rtx_insn *call1, rtx_insn *call2)
-{
-  if (!targetm.return_call_with_max_clobbers)
-    return false;
-
-  return (targetm.return_call_with_max_clobbers (call1, call2) == call1
-          && targetm.return_call_with_max_clobbers (call2, call1) == call2);
-}
-
 /* Process insns of the basic block BB to update pseudo live ranges,
    pseudo hard register conflicts, and insn notes.  We do it on
    backward scan of BB insns.  CURR_POINT is the program point where
@@ -662,15 +634,13 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
   rtx_insn *next;
   rtx link, *link_loc;
   bool need_curr_point_incr;
-  HARD_REG_SET last_call_used_reg_set;
-  rtx_insn *call_insn = NULL;
-  rtx_insn *last_call_insn = NULL;
+  /* Only has a meaningful value once we've seen a call.  */
+  function_abi last_call_abi = default_function_abi;
 
   reg_live_out = df_get_live_out (bb);
   sparseset_clear (pseudos_live);
   sparseset_clear (pseudos_live_through_calls);
   sparseset_clear (pseudos_live_through_setjumps);
-  CLEAR_HARD_REG_SET (last_call_used_reg_set);
   REG_SET_TO_HARD_REG_SET (hard_regs_live, reg_live_out);
   hard_regs_live &= ~eliminable_regset;
   EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi)
@@ -702,7 +672,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
       bool call_p;
       int n_alt, dst_regno, src_regno;
       rtx set;
-      struct lra_insn_reg *reg, *hr;
+      struct lra_insn_reg *reg;
 
       if (!NONDEBUG_INSN_P (curr_insn))
        continue;
@@ -734,7 +704,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
                break;
              }
          for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
-           if (reg->type != OP_IN && !reg->clobber_high)
+           if (reg->type != OP_IN)
              {
                remove_p = false;
                break;
@@ -871,24 +841,13 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
         unused values because they still conflict with quantities
         that are live at the time of the definition.  */
       for (reg = curr_id->regs; reg != NULL; reg = reg->next)
-       {
-         if (reg->type != OP_IN)
-           {
-             update_pseudo_point (reg->regno, curr_point, USE_POINT);
-             mark_regno_live (reg->regno, reg->biggest_mode);
-             check_pseudos_live_through_calls (reg->regno,
-                                               last_call_used_reg_set,
-                                               call_insn);
-           }
-
-         if (!HARD_REGISTER_NUM_P (reg->regno))
-           for (hr = curr_static_id->hard_regs; hr != NULL; hr = hr->next)
-             if (hr->clobber_high
-                 && maybe_gt (GET_MODE_SIZE (PSEUDO_REGNO_MODE (reg->regno)),
-                              GET_MODE_SIZE (hr->biggest_mode)))
-               SET_HARD_REG_BIT (lra_reg_info[reg->regno].conflict_hard_regs,
-                                 hr->regno);
-       }
+       if (reg->type != OP_IN)
+         {
+           update_pseudo_point (reg->regno, curr_point, USE_POINT);
+           mark_regno_live (reg->regno, reg->biggest_mode);
+           /* ??? Should be a no-op for unused registers.  */
+           check_pseudos_live_through_calls (reg->regno, last_call_abi);
+         }
 
       for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
        if (reg->type != OP_IN)
@@ -927,37 +886,13 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
 
       if (call_p)
        {
-         call_insn = curr_insn;
-         if (! flag_ipa_ra && ! targetm.return_call_with_max_clobbers)
-           last_call_used_reg_set = call_used_or_fixed_regs;
-         else
-           {
-             HARD_REG_SET this_call_used_reg_set
-               = insn_callee_abi (curr_insn).full_reg_clobbers ();
-             /* ??? This preserves traditional behavior; it might not
-                be needed.  */
-             this_call_used_reg_set |= fixed_reg_set;
-
-             bool flush = (! hard_reg_set_empty_p (last_call_used_reg_set)
-                           && (last_call_used_reg_set
-                               != this_call_used_reg_set))
-                          || (last_call_insn && ! calls_have_same_clobbers_p
-                                                    (call_insn,
-                                                     last_call_insn));
-
-             EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, j)
-               {
-                 lra_reg_info[j].actual_call_used_reg_set
-                   |= this_call_used_reg_set;
+         function_abi call_abi = insn_callee_abi (curr_insn);
 
-                 if (flush)
-                   check_pseudos_live_through_calls (j,
-                                                     last_call_used_reg_set,
-                                                     last_call_insn);
-               }
-             last_call_used_reg_set = this_call_used_reg_set;
-             last_call_insn = call_insn;
-           }
+         if (last_call_abi != call_abi)
+           EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, j)
+             check_pseudos_live_through_calls (j, last_call_abi);
+
+         last_call_abi = call_abi;
 
          sparseset_ior (pseudos_live_through_calls,
                         pseudos_live_through_calls, pseudos_live);
@@ -995,9 +930,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
            if (reg->type == OP_IN)
              update_pseudo_point (reg->regno, curr_point, USE_POINT);
            mark_regno_live (reg->regno, reg->biggest_mode);
-           check_pseudos_live_through_calls (reg->regno,
-                                             last_call_used_reg_set,
-                                             call_insn);
+           check_pseudos_live_through_calls (reg->regno, last_call_abi);
          }
 
       for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
@@ -1081,27 +1014,36 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
     }
 
   if (bb_has_eh_pred (bb))
+    /* Any pseudos that are currently live conflict with the eh_return
+       data registers.  For liveness purposes, these registers are set
+       by artificial definitions at the start of the BB, so are not
+       actually live on entry.  */
     for (j = 0; ; ++j)
       {
        unsigned int regno = EH_RETURN_DATA_REGNO (j);
 
        if (regno == INVALID_REGNUM)
          break;
+
        make_hard_regno_live (regno);
+       make_hard_regno_dead (regno);
       }
 
   /* Pseudos can't go in stack regs at the start of a basic block that
-     is reached by an abnormal edge. Likewise for call clobbered regs,
-     because caller-save, fixup_abnormal_edges and possibly the table
-     driven EH machinery are not quite ready to handle such pseudos
-     live across such edges.  */
+     is reached by an abnormal edge.  Likewise for registers that are at
+     least partly call clobbered, because caller-save, fixup_abnormal_edges
+     and possibly the table driven EH machinery are not quite ready to
+     handle such pseudos live across such edges.  */
   if (bb_has_abnormal_pred (bb))
     {
+      HARD_REG_SET clobbers;
+
+      CLEAR_HARD_REG_SET (clobbers);
 #ifdef STACK_REGS
       EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, px)
        lra_reg_info[px].no_stack_p = true;
       for (px = FIRST_STACK_REG; px <= LAST_STACK_REG; px++)
-       make_hard_regno_live (px);
+       SET_HARD_REG_BIT (clobbers, px);
 #endif
       /* No need to record conflicts for call clobbered regs if we
         have nonlocal labels around, as we don't ever try to
@@ -1109,7 +1051,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
       if (!cfun->has_nonlocal_label
          && has_abnormal_call_or_eh_pred_edge_p (bb))
        for (px = 0; HARD_REGISTER_NUM_P (px); px++)
-         if (call_used_or_fixed_reg_p (px)
+         if (eh_edge_abi.clobbers_at_least_part_of_reg_p (px)
 #ifdef REAL_PIC_OFFSET_TABLE_REGNUM
              /* We should create a conflict of PIC pseudo with PIC
                 hard reg as PIC hard reg can have a wrong value after
@@ -1121,7 +1063,15 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
                  && !HARD_REGISTER_P (pic_offset_table_rtx))
 #endif
              )
+           SET_HARD_REG_BIT (clobbers, px);
+
+      clobbers &= ~hard_regs_live;
+      for (px = 0; HARD_REGISTER_NUM_P (px); px++)
+       if (TEST_HARD_REG_BIT (clobbers, px))
+         {
            make_hard_regno_live (px);
+           make_hard_regno_dead (px);
+         }
     }
 
   bool live_change_p = false;
@@ -1166,7 +1116,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
       if (sparseset_cardinality (pseudos_live_through_calls) == 0)
        break;
       if (sparseset_bit_p (pseudos_live_through_calls, j))
-       check_pseudos_live_through_calls (j, last_call_used_reg_set, call_insn);
+       check_pseudos_live_through_calls (j, last_call_abi);
     }
 
   for (i = 0; HARD_REGISTER_NUM_P (i); ++i)
@@ -1400,7 +1350,6 @@ lra_create_live_ranges_1 (bool all_p, bool dead_insn_p)
        lra_reg_info[i].biggest_mode = GET_MODE (regno_reg_rtx[i]);
       else
        lra_reg_info[i].biggest_mode = VOIDmode;
-      lra_reg_info[i].call_insn = NULL;
       if (!HARD_REGISTER_NUM_P (i)
          && lra_reg_info[i].nrefs != 0)
        {