diff gcc/regrename.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
line wrap: on
line diff
--- a/gcc/regrename.c	Fri Oct 27 22:46:09 2017 +0900
+++ b/gcc/regrename.c	Thu Oct 25 07:37:49 2018 +0900
@@ -1,5 +1,5 @@
 /* Register renaming for the GNU compiler.
-   Copyright (C) 2000-2017 Free Software Foundation, Inc.
+   Copyright (C) 2000-2018 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
@@ -963,6 +963,7 @@
   struct du_chain *chain;
   unsigned int base_regno = head->regno;
   machine_mode mode;
+  rtx last_reg = NULL_RTX, last_repl = NULL_RTX;
 
   for (chain = head->first; chain; chain = chain->next_use)
     {
@@ -975,12 +976,16 @@
 			 gen_rtx_UNKNOWN_VAR_LOC (), true);
       else
 	{
-	  validate_change (chain->insn, chain->loc, 
-			   gen_raw_REG (GET_MODE (*chain->loc), reg), true);
-	  if (regno >= FIRST_PSEUDO_REGISTER)
-	    ORIGINAL_REGNO (*chain->loc) = regno;
-	  REG_ATTRS (*chain->loc) = attr;
-	  REG_POINTER (*chain->loc) = reg_ptr;
+	  if (*chain->loc != last_reg)
+	    {
+	      last_repl = gen_raw_REG (GET_MODE (*chain->loc), reg);
+	      if (regno >= FIRST_PSEUDO_REGISTER)
+		ORIGINAL_REGNO (last_repl) = regno;
+	      REG_ATTRS (last_repl) = attr;
+	      REG_POINTER (last_repl) = reg_ptr;
+	      last_reg = *chain->loc;
+	    }
+	  validate_change (chain->insn, chain->loc, last_repl, true);
 	}
     }
 
@@ -1656,7 +1661,8 @@
 	     (6) For any non-earlyclobber write we find in an operand, make
 	         a new chain or mark the hard register as live.
 	     (7) For any REG_UNUSED, close any chains we just opened.
-	     (8) For any REG_CFA_RESTORE, kill any chain containing it.
+	     (8) For any REG_CFA_RESTORE or REG_CFA_REGISTER, kill any chain
+	         containing its dest.
 
 	     We cannot deal with situations where we track a reg in one mode
 	     and see a reference in another mode; these will cause the chain
@@ -1697,13 +1703,19 @@
 		     not already tracking such a reg, we won't start here,
 		     and we must instead make sure to make the operand visible
 		     to the machinery that tracks hard registers.  */
-		  if (matches >= 0
-		      && (GET_MODE_SIZE (recog_data.operand_mode[i])
-			  != GET_MODE_SIZE (recog_data.operand_mode[matches]))
-		      && !verify_reg_in_set (op, &live_in_chains))
+		  machine_mode i_mode = recog_data.operand_mode[i];
+		  if (matches >= 0)
 		    {
-		      untracked_operands |= 1 << i;
-		      untracked_operands |= 1 << matches;
+		      machine_mode matches_mode
+			= recog_data.operand_mode[matches];
+
+		      if (maybe_ne (GET_MODE_SIZE (i_mode),
+				    GET_MODE_SIZE (matches_mode))
+			  && !verify_reg_in_set (op, &live_in_chains))
+			{
+			  untracked_operands |= 1 << i;
+			  untracked_operands |= 1 << matches;
+			}
 		    }
 		}
 #ifdef STACK_REGS
@@ -1871,12 +1883,22 @@
 	      }
 
 	  /* Step 8: Kill the chains involving register restores.  Those
-	     should restore _that_ register.  */
+	     should restore _that_ register.  Similar for REG_CFA_REGISTER.  */
 	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
-	    if (REG_NOTE_KIND (note) == REG_CFA_RESTORE)
-	      scan_rtx (insn, &XEXP (note, 0), NO_REGS, mark_all_read, OP_IN);
+	    if (REG_NOTE_KIND (note) == REG_CFA_RESTORE
+		|| REG_NOTE_KIND (note) == REG_CFA_REGISTER)
+	      {
+		rtx *x = &XEXP (note, 0);
+		if (!*x)
+		  x = &PATTERN (insn);
+		if (GET_CODE (*x) == PARALLEL)
+		  x = &XVECEXP (*x, 0, 0);
+		if (GET_CODE (*x) == SET)
+		  x = &SET_DEST (*x);
+		scan_rtx (insn, x, NO_REGS, mark_all_read, OP_IN);
+	      }
 	}
-      else if (DEBUG_INSN_P (insn)
+      else if (DEBUG_BIND_INSN_P (insn)
 	       && !VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)))
 	{
 	  scan_rtx (insn, &INSN_VAR_LOCATION_LOC (insn),