]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/postreload.c
c++: Handle multiple aggregate overloads [PR95319].
[thirdparty/gcc.git] / gcc / postreload.c
index 12d74fcc0504fd657bdba28671e67572314bb65f..f625828502248f74f9fd88f6383e6e04b02a0cb8 100644 (file)
@@ -1,5 +1,5 @@
 /* Perform simple optimizations to clean up the result of reload.
-   Copyright (C) 1987-2019 Free Software Foundation, Inc.
+   Copyright (C) 1987-2020 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "dbgcnt.h"
 #include "function-abi.h"
+#include "rtl-iter.h"
 
 static int reload_cse_noop_set_p (rtx);
 static bool reload_cse_simplify (rtx_insn *, rtx);
@@ -96,6 +97,16 @@ reload_cse_simplify (rtx_insn *insn, rtx testreg)
   if (NO_FUNCTION_CSE && CALL_P (insn))
     return false;
 
+  /* Remember if this insn has been sp += const_int.  */
+  rtx sp_set = set_for_reg_notes (insn);
+  rtx sp_addend = NULL_RTX;
+  if (sp_set
+      && SET_DEST (sp_set) == stack_pointer_rtx
+      && GET_CODE (SET_SRC (sp_set)) == PLUS
+      && XEXP (SET_SRC (sp_set), 0) == stack_pointer_rtx
+      && CONST_INT_P (XEXP (SET_SRC (sp_set), 1)))
+    sp_addend = XEXP (SET_SRC (sp_set), 1);
+
   if (GET_CODE (body) == SET)
     {
       int count = 0;
@@ -179,6 +190,15 @@ reload_cse_simplify (rtx_insn *insn, rtx testreg)
        reload_cse_simplify_operands (insn, testreg);
     }
 
+  /* If sp += const_int insn is changed into sp = reg;, add REG_EQUAL
+     note so that the stack_adjustments pass can undo it if beneficial.  */
+  if (sp_addend
+      && SET_DEST (sp_set) == stack_pointer_rtx
+      && REG_P (SET_SRC (sp_set)))
+    set_dst_reg_note (insn, REG_EQUAL,
+                     gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+                                   sp_addend), stack_pointer_rtx);
+
 done:
   return (EDGE_COUNT (insn_bb->succs) != insn_bb_succs);
 }
@@ -1078,6 +1098,10 @@ reload_combine_recognize_pattern (rtx_insn *insn)
       struct reg_use *use = reg_state[regno].reg_use + i;
       if (GET_MODE (*use->usep) != mode)
        return false;
+      /* Don't try to adjust (use (REGX)).  */
+      if (GET_CODE (PATTERN (use->insn)) == USE
+         && &XEXP (PATTERN (use->insn), 0) == use->usep)
+       return false;
     }
 
   /* Look for (set (REGX) (CONST_INT))
@@ -1199,11 +1223,10 @@ reload_combine_recognize_pattern (rtx_insn *insn)
              /* Delete the reg-reg addition.  */
              delete_insn (insn);
 
-             if (reg_state[regno].offset != const0_rtx
-                 /* Previous REG_EQUIV / REG_EQUAL notes for PREV
-                    are now invalid.  */
-                 && remove_reg_equal_equiv_notes (prev))
-               df_notes_rescan (prev);
+             if (reg_state[regno].offset != const0_rtx)
+               /* Previous REG_EQUIV / REG_EQUAL notes for PREV
+                  are now invalid.  */
+               remove_reg_equal_equiv_notes (prev);
 
              reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES;
              return true;
@@ -2086,6 +2109,21 @@ reload_cse_move2add (rtx_insn *first)
                }
            }
        }
+
+      /* There are no REG_INC notes for SP autoinc.  */
+      subrtx_var_iterator::array_type array;
+      FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), NONCONST)
+       {
+         rtx mem = *iter;
+         if (mem
+             && MEM_P (mem)
+             && GET_RTX_CLASS (GET_CODE (XEXP (mem, 0))) == RTX_AUTOINC)
+           {
+             if (XEXP (XEXP (mem, 0), 0) == stack_pointer_rtx)
+               reg_mode[STACK_POINTER_REGNUM] = VOIDmode;
+           }
+       }
+
       note_stores (insn, move2add_note_store, insn);
 
       /* If INSN is a conditional branch, we try to extract an
@@ -2140,17 +2178,6 @@ move2add_note_store (rtx dst, const_rtx set, void *data)
   unsigned int regno = 0;
   scalar_int_mode mode;
 
-  /* Some targets do argument pushes without adding REG_INC notes.  */
-
-  if (MEM_P (dst))
-    {
-      dst = XEXP (dst, 0);
-      if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC
-         || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC)
-       reg_mode[REGNO (XEXP (dst, 0))] = VOIDmode;
-      return;
-    }
-
   if (GET_CODE (dst) == SUBREG)
     regno = subreg_regno (dst);
   else if (REG_P (dst))