]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/ira-emit.c
[C++] Protect call to copy_attributes_to_builtin (PR91505)
[thirdparty/gcc.git] / gcc / ira-emit.c
index 445b386b67fc6d2c729379895b40761a3b45d0f6..255af307b3c83ba3d7173598928ccb836e65643c 100644 (file)
@@ -1,5 +1,5 @@
 /* Integrated Register Allocator.  Changing code and generating moves.
-   Copyright (C) 2006-2014 Free Software Foundation, Inc.
+   Copyright (C) 2006-2019 Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
 This file is part of GCC.
@@ -68,22 +68,21 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "regs.h"
+#include "backend.h"
 #include "rtl.h"
-#include "tm_p.h"
-#include "target.h"
-#include "flags.h"
-#include "obstack.h"
-#include "bitmap.h"
-#include "hard-reg-set.h"
-#include "basic-block.h"
-#include "expr.h"
-#include "recog.h"
-#include "params.h"
-#include "reload.h"
+#include "tree.h"
+#include "predict.h"
 #include "df.h"
+#include "insn-config.h"
+#include "regs.h"
+#include "memmodel.h"
+#include "ira.h"
 #include "ira-int.h"
+#include "cfgrtl.h"
+#include "cfgbuild.h"
+#include "expr.h"
+#include "reload.h"
+#include "cfgloop.h"
 
 
 /* Data used to emit live range split insns and to flattening IR.  */
@@ -301,6 +300,15 @@ change_regs (rtx *loc)
   return result;
 }
 
+static bool
+change_regs_in_insn (rtx_insn **insn_ptr)
+{
+  rtx rtx = *insn_ptr;
+  bool result = change_regs (&rtx);
+  *insn_ptr = as_a <rtx_insn *> (rtx);
+  return result;
+}
+
 /* Attach MOVE to the edge E.  The move is attached to the head of the
    list if HEAD_P is TRUE.  */
 static void
@@ -557,7 +565,8 @@ change_loop (ira_loop_tree_node_t node)
   int regno;
   bool used_p;
   ira_allocno_t allocno, parent_allocno, *map;
-  rtx insn, original_reg;
+  rtx_insn *insn;
+  rtx original_reg;
   enum reg_class aclass, pclass;
   ira_loop_tree_node_t parent;
 
@@ -568,7 +577,7 @@ change_loop (ira_loop_tree_node_t node)
       if (node->bb != NULL)
        {
          FOR_BB_INSNS (node->bb, insn)
-           if (INSN_P (insn) && change_regs (&insn))
+           if (INSN_P (insn) && change_regs_in_insn (&insn))
              {
                df_insn_rescan (insn);
                df_notes_rescan (insn);
@@ -610,7 +619,10 @@ change_loop (ira_loop_tree_node_t node)
                  /* don't create copies because reload can spill an
                     allocno set by copy although the allocno will not
                     get memory slot.  */
-                 || ira_equiv_no_lvalue_p (regno)))
+                 || ira_equiv_no_lvalue_p (regno)
+                 || (pic_offset_table_rtx != NULL
+                     && (ALLOCNO_REGNO (allocno)
+                         == (int) REGNO (pic_offset_table_rtx)))))
            continue;
          original_reg = allocno_emit_reg (allocno);
          if (parent_allocno == NULL
@@ -764,14 +776,14 @@ modify_move_list (move_t list)
 
   if (list == NULL)
     return NULL;
-  /* Creat move deps.  */
+  /* Create move deps.  */
   curr_tick++;
   for (move = list; move != NULL; move = move->next)
     {
       to = move->to;
       if ((hard_regno = ALLOCNO_HARD_REGNO (to)) < 0)
        continue;
-      nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (to)];
+      nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (to));
       for (i = 0; i < nregs; i++)
        {
          hard_regno_last_set[hard_regno + i] = move;
@@ -784,7 +796,7 @@ modify_move_list (move_t list)
       to = move->to;
       if ((hard_regno = ALLOCNO_HARD_REGNO (from)) >= 0)
        {
-         nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (from)];
+         nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (from));
          for (n = i = 0; i < nregs; i++)
            if (hard_regno_last_set_check[hard_regno + i] == curr_tick
                && (ALLOCNO_REGNO (hard_regno_last_set[hard_regno + i]->to)
@@ -799,7 +811,7 @@ modify_move_list (move_t list)
          move->deps_num = n;
        }
     }
-  /* Toplogical sorting:  */
+  /* Topological sorting:  */
   move_vec.truncate (0);
   for (move = list; move != NULL; move = move->next)
     traverse_moves (move);
@@ -822,7 +834,7 @@ modify_move_list (move_t list)
       to = move->to;
       if ((hard_regno = ALLOCNO_HARD_REGNO (from)) >= 0)
        {
-         nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (from)];
+         nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (from));
          for (i = 0; i < nregs; i++)
            if (hard_regno_last_set_check[hard_regno + i] == curr_tick
                && ALLOCNO_HARD_REGNO
@@ -874,7 +886,7 @@ modify_move_list (move_t list)
        }
       if ((hard_regno = ALLOCNO_HARD_REGNO (to)) < 0)
        continue;
-      nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (to)];
+      nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (to));
       for (i = 0; i < nregs; i++)
        {
          hard_regno_last_set[hard_regno + i] = move;
@@ -900,7 +912,7 @@ emit_move_list (move_t list, int freq)
   int to_regno, from_regno, cost, regno;
   rtx_insn *result, *insn;
   rtx set;
-  enum machine_mode mode;
+  machine_mode mode;
   enum reg_class aclass;
 
   grow_reg_equivs ();
@@ -985,23 +997,30 @@ emit_moves (void)
   basic_block bb;
   edge_iterator ei;
   edge e;
-  rtx_insn *insns, *tmp;
+  rtx_insn *insns, *tmp, *next;
 
   FOR_EACH_BB_FN (bb, cfun)
     {
       if (at_bb_start[bb->index] != NULL)
        {
          at_bb_start[bb->index] = modify_move_list (at_bb_start[bb->index]);
-         insns = emit_move_list (at_bb_start[bb->index],
-                                 REG_FREQ_FROM_BB (bb));
+         insns
+           = emit_move_list (at_bb_start[bb->index], REG_FREQ_FROM_BB (bb));
          tmp = BB_HEAD (bb);
          if (LABEL_P (tmp))
            tmp = NEXT_INSN (tmp);
          if (NOTE_INSN_BASIC_BLOCK_P (tmp))
            tmp = NEXT_INSN (tmp);
+         /* Make sure to put the location of TMP or a subsequent instruction
+            to avoid inheriting the location of the previous instruction.  */
+         next = tmp;
+         while (next && !NONDEBUG_INSN_P (next))
+           next = NEXT_INSN (next);
+         if (next)
+           set_insn_locations (insns, INSN_LOCATION (next));
          if (tmp == BB_HEAD (bb))
            emit_insn_before (insns, tmp);
-         else if (tmp != NULL_RTX)
+         else if (tmp)
            emit_insn_after (insns, PREV_INSN (tmp));
          else
            emit_insn_after (insns, get_last_insn ());