diff gcc/lra-eliminations.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
line wrap: on
line diff
--- a/gcc/lra-eliminations.c	Thu Oct 25 07:37:49 2018 +0900
+++ b/gcc/lra-eliminations.c	Thu Feb 13 11:34:05 2020 +0900
@@ -1,5 +1,5 @@
 /* Code for RTL register eliminations.
-   Copyright (C) 2010-2018 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.
@@ -71,8 +71,9 @@
 
 /* This structure is used to record information about hard register
    eliminations.  */
-struct lra_elim_table
+class lra_elim_table
 {
+public:
   /* Hard register number to be eliminated.  */
   int from;
   /* Hard register number used as replacement.	*/
@@ -99,7 +100,7 @@
    of eliminating a register in favor of another.  If there is more
    than one way of eliminating a particular register, the most
    preferred should be specified first.	 */
-static struct lra_elim_table *reg_eliminate = 0;
+static class lra_elim_table *reg_eliminate = 0;
 
 /* This is an intermediate structure to initialize the table.  It has
    exactly the members provided by ELIMINABLE_REGS.  */
@@ -117,7 +118,7 @@
 static void
 print_elim_table (FILE *f)
 {
-  struct lra_elim_table *ep;
+  class lra_elim_table *ep;
 
   for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
     {
@@ -141,7 +142,7 @@
    VALUE.  Setup FRAME_POINTER_NEEDED if elimination from frame
    pointer to stack pointer is not possible anymore.  */
 static void
-setup_can_eliminate (struct lra_elim_table *ep, bool value)
+setup_can_eliminate (class lra_elim_table *ep, bool value)
 {
   ep->can_eliminate = ep->prev_can_eliminate = value;
   if (! value
@@ -155,12 +156,12 @@
    or NULL if none.  The elimination table may contain more than
    one elimination for the same hard register, but this map specifies
    the one that we are currently using.  */
-static struct lra_elim_table *elimination_map[FIRST_PSEUDO_REGISTER];
+static class lra_elim_table *elimination_map[FIRST_PSEUDO_REGISTER];
 
 /* When an eliminable hard register becomes not eliminable, we use the
    following special structure to restore original offsets for the
    register.  */
-static struct lra_elim_table self_elim_table;
+static class lra_elim_table self_elim_table;
 
 /* Offsets should be used to restore original offsets for eliminable
    hard register which just became not eliminable.  Zero,
@@ -176,7 +177,7 @@
 setup_elimination_map (void)
 {
   int i;
-  struct lra_elim_table *ep;
+  class lra_elim_table *ep;
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     elimination_map[i] = NULL;
@@ -241,7 +242,7 @@
 int
 lra_get_elimination_hard_regno (int hard_regno)
 {
-  struct lra_elim_table *ep;
+  class lra_elim_table *ep;
 
   if (hard_regno < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
     return hard_regno;
@@ -252,11 +253,11 @@
 
 /* Return elimination which will be used for hard reg REG, NULL
    otherwise.  */
-static struct lra_elim_table *
+static class lra_elim_table *
 get_elimination (rtx reg)
 {
   int hard_regno;
-  struct lra_elim_table *ep;
+  class lra_elim_table *ep;
 
   lra_assert (REG_P (reg));
   if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
@@ -333,7 +334,7 @@
 		      poly_int64 update_sp_offset, bool full_p)
 {
   enum rtx_code code = GET_CODE (x);
-  struct lra_elim_table *ep;
+  class lra_elim_table *ep;
   rtx new_rtx;
   int i, j;
   const char *fmt;
@@ -654,7 +655,6 @@
       return x;
 
     case CLOBBER:
-    case CLOBBER_HIGH:
     case SET:
       gcc_unreachable ();
 
@@ -730,7 +730,7 @@
 mark_not_eliminable (rtx x, machine_mode mem_mode)
 {
   enum rtx_code code = GET_CODE (x);
-  struct lra_elim_table *ep;
+  class lra_elim_table *ep;
   int i, j;
   const char *fmt;
   poly_int64 offset = 0;
@@ -807,16 +807,6 @@
 	    setup_can_eliminate (ep, false);
       return;
 
-    case CLOBBER_HIGH:
-      gcc_assert (REG_P (XEXP (x, 0)));
-      gcc_assert (REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER);
-      for (ep = reg_eliminate;
-	   ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
-	   ep++)
-	if (reg_is_clobbered_by_clobber_high (ep->to_rtx, XEXP (x, 0)))
-	  setup_can_eliminate (ep, false);
-      return;
-
     case SET:
       if (SET_DEST (x) == stack_pointer_rtx
 	  && GET_CODE (SET_SRC (x)) == PLUS
@@ -876,32 +866,6 @@
 
 
 
-#ifdef HARD_FRAME_POINTER_REGNUM
-
-/* Search INSN's reg notes to see whether the destination is equal to
-   WHAT + C for some constant C.  Return true if so, storing C in
-   *OFFSET_OUT and removing the reg note.  */
-static bool
-remove_reg_equal_offset_note (rtx_insn *insn, rtx what, poly_int64 *offset_out)
-{
-  rtx link, *link_loc;
-
-  for (link_loc = &REG_NOTES (insn);
-       (link = *link_loc) != NULL_RTX;
-       link_loc = &XEXP (link, 1))
-    if (REG_NOTE_KIND (link) == REG_EQUAL
-	&& GET_CODE (XEXP (link, 0)) == PLUS
-	&& XEXP (XEXP (link, 0), 0) == what
-	&& poly_int_rtx_p (XEXP (XEXP (link, 0), 1), offset_out))
-      {
-	*link_loc = XEXP (link, 1);
-	return true;
-      }
-  return false;
-}
-
-#endif
-
 /* Scan INSN and eliminate all eliminable hard registers in it.
 
    If REPLACE_P is true, do the replacement destructively.  Also
@@ -926,7 +890,7 @@
   int i;
   rtx substed_operand[MAX_RECOG_OPERANDS];
   rtx orig_operand[MAX_RECOG_OPERANDS];
-  struct lra_elim_table *ep;
+  class lra_elim_table *ep;
   rtx plus_src, plus_cst_src;
   lra_insn_recog_data_t id;
   struct lra_static_insn_data *static_id;
@@ -939,72 +903,6 @@
       return;
     }
 
-  /* Check for setting an eliminable register.	*/
-  if (old_set != 0 && REG_P (SET_DEST (old_set))
-      && (ep = get_elimination (SET_DEST (old_set))) != NULL)
-    {
-      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
-	if (ep->from_rtx == SET_DEST (old_set) && ep->can_eliminate)
-	  {
-	    bool delete_p = replace_p;
-	    
-#ifdef HARD_FRAME_POINTER_REGNUM
-	    if (ep->from == FRAME_POINTER_REGNUM
-		&& ep->to == HARD_FRAME_POINTER_REGNUM)
-	      /* If this is setting the frame pointer register to the
-		 hardware frame pointer register and this is an
-		 elimination that will be done (tested above), this
-		 insn is really adjusting the frame pointer downward
-		 to compensate for the adjustment done before a
-		 nonlocal goto.  */
-	      {
-		rtx src = SET_SRC (old_set);
-		poly_int64 offset = 0;
-
-		/* We should never process such insn with non-zero
-		   UPDATE_SP_OFFSET.  */
-		lra_assert (known_eq (update_sp_offset, 0));
-		
-		if (remove_reg_equal_offset_note (insn, ep->to_rtx, &offset)
-		    || strip_offset (src, &offset) == ep->to_rtx)
-		  {
-		    if (replace_p)
-		      {
-			SET_DEST (old_set) = ep->to_rtx;
-			lra_update_insn_recog_data (insn);
-			return;
-		      }
-		    offset -= (ep->offset - ep->previous_offset);
-		    src = plus_constant (Pmode, ep->to_rtx, offset);
-		    
-		    /* First see if this insn remains valid when we
-		       make the change.  If not, keep the INSN_CODE
-		       the same and let the constraint pass fit it
-		       up.  */
-		    validate_change (insn, &SET_SRC (old_set), src, 1);
-		    validate_change (insn, &SET_DEST (old_set),
-				     ep->from_rtx, 1);
-		    if (! apply_change_group ())
-		      {
-			SET_SRC (old_set) = src;
-			SET_DEST (old_set) = ep->from_rtx;
-		      }
-		    lra_update_insn_recog_data (insn);
-		    /* Add offset note for future updates.  */
-		    add_reg_note (insn, REG_EQUAL, copy_rtx (src));
-		    return;
-		  }
-	      }
-#endif
-	    
-	    /* This insn isn't serving a useful purpose.  We delete it
-	       when REPLACE is set.  */
-	    if (delete_p)
-	      lra_delete_dead_insn (insn);
-	    return;
-	  }
-    }
-
   /* We allow one special case which happens to work on all machines we
      currently support: a single set with the source or a REG_EQUAL
      note being a PLUS of an eliminable register and a constant.  */
@@ -1109,7 +1007,7 @@
 	    {
 	      /* If we are assigning to a hard register that can be
 		 eliminated, it must be as part of a PARALLEL, since
-		 the code above handles single SETs.  This reg can not
+		 the code above handles single SETs.  This reg cannot
 		 be longer eliminated -- it is forced by
 		 mark_not_eliminable.  */
 	      for (ep = reg_eliminate;
@@ -1145,8 +1043,7 @@
      PARALLEL since the new one still will, but we can't call
      single_set without having put new body into the insn and the
      re-recognition won't hurt in this rare case.  */
-  id = lra_update_insn_recog_data (insn);
-  static_id = id->insn_static_data;
+  lra_update_insn_recog_data (insn);
 }
 
 /* Spill pseudos which are assigned to hard registers in SET.  Add
@@ -1181,7 +1078,7 @@
 	reg_renumber[i] = -1;
 	bitmap_ior_into (&to_process, &lra_reg_info[i].insn_bitmap);
       }
-  IOR_HARD_REG_SET (lra_no_alloc_regs, set);
+  lra_no_alloc_regs |= set;
   for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn))
     if (bitmap_bit_p (&to_process, INSN_UID (insn)))
       {
@@ -1201,7 +1098,7 @@
 update_reg_eliminate (bitmap insns_with_changed_offsets)
 {
   bool prev, result;
-  struct lra_elim_table *ep, *ep1;
+  class lra_elim_table *ep, *ep1;
   HARD_REG_SET temp_hard_reg_set;
 
   targetm.compute_frame_layout ();
@@ -1236,7 +1133,7 @@
 		     "	Elimination %d to %d is not possible anymore\n",
 		     ep->from, ep->to);
 	  /* If after processing RTL we decides that SP can be used as
-	     a result of elimination, it can not be changed.  */
+	     a result of elimination, it cannot be changed.  */
 	  gcc_assert ((ep->to_rtx != stack_pointer_rtx)
 		      || (ep->from < FIRST_PSEUDO_REGISTER
 			  && fixed_regs [ep->from]));
@@ -1294,8 +1191,8 @@
 	    result = true;
 	  }
       }
-  IOR_HARD_REG_SET (lra_no_alloc_regs, temp_hard_reg_set);
-  AND_COMPL_HARD_REG_SET (eliminable_regset, temp_hard_reg_set);
+  lra_no_alloc_regs |= temp_hard_reg_set;
+  eliminable_regset &= ~temp_hard_reg_set;
   spill_pseudos (temp_hard_reg_set);
   return result;
 }
@@ -1306,12 +1203,12 @@
 static void
 init_elim_table (void)
 {
-  struct lra_elim_table *ep;
+  class lra_elim_table *ep;
   bool value_p;
   const struct elim_table_1 *ep1;
 
   if (!reg_eliminate)
-    reg_eliminate = XCNEWVEC (struct lra_elim_table, NUM_ELIMINABLE_REGS);
+    reg_eliminate = XCNEWVEC (class lra_elim_table, NUM_ELIMINABLE_REGS);
 
   memset (self_elim_offsets, 0, sizeof (self_elim_offsets));
   /* Initiate member values which will be never changed.  */
@@ -1354,7 +1251,7 @@
   bool stop_to_sp_elimination_p;
   basic_block bb;
   rtx_insn *insn;
-  struct lra_elim_table *ep;
+  class lra_elim_table *ep;
 
   init_elim_table ();
   FOR_EACH_BB_FN (bb, cfun)
@@ -1388,7 +1285,7 @@
 lra_eliminate_reg_if_possible (rtx *loc)
 {
   int regno;
-  struct lra_elim_table *ep;
+  class lra_elim_table *ep;
 
   lra_assert (REG_P (*loc));
   if ((regno = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER
@@ -1414,6 +1311,11 @@
 
       if (icode >= 0 && icode != INSN_CODE (insn))
 	{
+	  if (INSN_CODE (insn) >= 0)
+	    /* Insn code is changed.  It may change its operand type
+	       from IN to INOUT.  Inform the subsequent assignment
+	       subpass about this situation.  */
+	    check_and_force_assignment_correctness_p = true;
 	  INSN_CODE (insn) = icode;
 	  lra_update_insn_recog_data (insn);
 	}
@@ -1432,7 +1334,7 @@
   unsigned int uid;
   bitmap_head insns_with_changed_offsets;
   bitmap_iterator bi;
-  struct lra_elim_table *ep;
+  class lra_elim_table *ep;
 
   gcc_assert (! final_p || ! first_p);