]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/ira-build.c
Correct a function pre/postcondition [PR102403].
[thirdparty/gcc.git] / gcc / ira-build.c
index 1fa7a86831175750e67c043b9a177cbf575e2128..42120656366416d56f81dec01d38e097fefaf16d 100644 (file)
@@ -1,5 +1,5 @@
 /* Building internal representation for IRA.
-   Copyright (C) 2006-2019 Free Software Foundation, Inc.
+   Copyright (C) 2006-2021 Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
 This file is part of GCC.
@@ -31,7 +31,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "memmodel.h"
 #include "ira.h"
 #include "ira-int.h"
-#include "params.h"
 #include "sparseset.h"
 #include "cfgloop.h"
 
@@ -129,7 +128,6 @@ create_loop_tree_nodes (void)
   bool skip_p;
   edge_iterator ei;
   edge e;
-  vec<edge> edges;
   loop_p loop;
 
   ira_bb_nodes
@@ -174,14 +172,13 @@ create_loop_tree_nodes (void)
              }
          if (skip_p)
            continue;
-         edges = get_loop_exit_edges (loop);
+         auto_vec<edge> edges = get_loop_exit_edges (loop);
          FOR_EACH_VEC_ELT (edges, j, e)
            if ((e->flags & EDGE_ABNORMAL) && EDGE_CRITICAL_P (e))
              {
                skip_p = true;
                break;
              }
-         edges.release ();
          if (skip_p)
            continue;
        }
@@ -458,10 +455,8 @@ ira_create_object (ira_allocno_t a, int subword)
   OBJECT_NUM_CONFLICTS (obj) = 0;
   OBJECT_CONFLICT_HARD_REGS (obj) = ira_no_alloc_regs;
   OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) = ira_no_alloc_regs;
-  IOR_COMPL_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
-                         reg_class_contents[aclass]);
-  IOR_COMPL_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
-                         reg_class_contents[aclass]);
+  OBJECT_CONFLICT_HARD_REGS (obj) |= ~reg_class_contents[aclass];
+  OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= ~reg_class_contents[aclass];
   OBJECT_MIN (obj) = INT_MAX;
   OBJECT_MAX (obj) = -1;
   OBJECT_LIVE_RANGES (obj) = NULL;
@@ -506,6 +501,7 @@ ira_create_allocno (int regno, bool cap_p,
   ALLOCNO_CALL_FREQ (a) = 0;
   ALLOCNO_CALLS_CROSSED_NUM (a) = 0;
   ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a) = 0;
+  ALLOCNO_CROSSED_CALLS_ABIS (a) = 0;
   CLEAR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a));
 #ifdef STACK_REGS
   ALLOCNO_NO_STACK_REG_P (a) = false;
@@ -549,10 +545,8 @@ ira_set_allocno_class (ira_allocno_t a, enum reg_class aclass)
   ALLOCNO_CLASS (a) = aclass;
   FOR_EACH_ALLOCNO_OBJECT (a, obj, oi)
     {
-      IOR_COMPL_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj),
-                             reg_class_contents[aclass]);
-      IOR_COMPL_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj),
-                             reg_class_contents[aclass]);
+      OBJECT_CONFLICT_HARD_REGS (obj) |= ~reg_class_contents[aclass];
+      OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= ~reg_class_contents[aclass];
     }
 }
 
@@ -602,10 +596,10 @@ merge_hard_reg_conflicts (ira_allocno_t from, ira_allocno_t to,
       ira_object_t to_obj = ALLOCNO_OBJECT (to, i);
 
       if (!total_only)
-       IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (to_obj),
-                         OBJECT_CONFLICT_HARD_REGS (from_obj));
-      IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (to_obj),
-                       OBJECT_TOTAL_CONFLICT_HARD_REGS (from_obj));
+       OBJECT_CONFLICT_HARD_REGS (to_obj)
+         |= OBJECT_CONFLICT_HARD_REGS (from_obj);
+      OBJECT_TOTAL_CONFLICT_HARD_REGS (to_obj)
+       |= OBJECT_TOTAL_CONFLICT_HARD_REGS (from_obj);
     }
 #ifdef STACK_REGS
   if (!total_only && ALLOCNO_NO_STACK_REG_P (from))
@@ -618,15 +612,15 @@ merge_hard_reg_conflicts (ira_allocno_t from, ira_allocno_t to,
 /* Update hard register conflict information for all objects associated with
    A to include the regs in SET.  */
 void
-ior_hard_reg_conflicts (ira_allocno_t a, HARD_REG_SET *set)
+ior_hard_reg_conflicts (ira_allocno_t a, const_hard_reg_set set)
 {
   ira_allocno_object_iterator i;
   ira_object_t obj;
 
   FOR_EACH_ALLOCNO_OBJECT (a, obj, i)
     {
-      IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), *set);
-      IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), *set);
+      OBJECT_CONFLICT_HARD_REGS (obj) |= set;
+      OBJECT_TOTAL_CONFLICT_HARD_REGS (obj) |= set;
     }
 }
 
@@ -907,8 +901,9 @@ create_cap_allocno (ira_allocno_t a)
 
   ALLOCNO_CALLS_CROSSED_NUM (cap) = ALLOCNO_CALLS_CROSSED_NUM (a);
   ALLOCNO_CHEAP_CALLS_CROSSED_NUM (cap) = ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a);
-  IOR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (cap),
-                   ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a));
+  ALLOCNO_CROSSED_CALLS_ABIS (cap) = ALLOCNO_CROSSED_CALLS_ABIS (a);
+  ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (cap)
+    = ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a);
   if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
     {
       fprintf (ira_dump_file, "    Creating cap ");
@@ -1677,7 +1672,7 @@ finish_cost_vectors (void)
 
 static vec<ira_loop_tree_node_t>
 ira_loop_tree_body_rev_postorder (ira_loop_tree_node_t loop_node ATTRIBUTE_UNUSED,
-                                 vec<ira_loop_tree_node_t> loop_preorder)
+                                 const vec<ira_loop_tree_node_t> &loop_preorder)
 {
   vec<ira_loop_tree_node_t> topsort_nodes = vNULL;
   unsigned int n_loop_preorder;
@@ -1876,11 +1871,6 @@ create_insn_allocnos (rtx x, rtx outer, bool output_p)
       create_insn_allocnos (XEXP (x, 0), NULL, true);
       return;
     }
-  else if (code == CLOBBER_HIGH)
-    {
-      gcc_assert (REG_P (XEXP (x, 0)) && HARD_REGISTER_P (XEXP (x, 0)));
-      return;
-    }
   else if (code == MEM)
     {
       create_insn_allocnos (XEXP (x, 0), NULL, false);
@@ -1972,17 +1962,15 @@ create_loop_tree_node_allocnos (ira_loop_tree_node_t loop_node)
       int i;
       edge_iterator ei;
       edge e;
-      vec<edge> edges;
 
       ira_assert (current_loops != NULL);
       FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
        if (e->src != loop_node->loop->latch)
          create_loop_allocnos (e);
 
-      edges = get_loop_exit_edges (loop_node->loop);
+      auto_vec<edge> edges = get_loop_exit_edges (loop_node->loop);
       FOR_EACH_VEC_ELT (edges, i, e)
        create_loop_allocnos (e);
-      edges.release ();
     }
 }
 
@@ -2036,8 +2024,10 @@ propagate_allocno_info (void)
            += ALLOCNO_CALLS_CROSSED_NUM (a);
          ALLOCNO_CHEAP_CALLS_CROSSED_NUM (parent_a)
            += ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a);
-         IOR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (parent_a),
-                           ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a));
+         ALLOCNO_CROSSED_CALLS_ABIS (parent_a)
+           |= ALLOCNO_CROSSED_CALLS_ABIS (a);
+         ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (parent_a)
+           |= ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a);
          ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a)
            += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
          aclass = ALLOCNO_CLASS (a);
@@ -2173,13 +2163,12 @@ loop_with_complex_edge_p (class loop *loop)
   int i;
   edge_iterator ei;
   edge e;
-  vec<edge> edges;
   bool res;
 
   FOR_EACH_EDGE (e, ei, loop->header->preds)
     if (e->flags & EDGE_EH)
       return true;
-  edges = get_loop_exit_edges (loop);
+  auto_vec<edge> edges = get_loop_exit_edges (loop);
   res = false;
   FOR_EACH_VEC_ELT (edges, i, e)
     if (e->flags & EDGE_COMPLEX)
@@ -2187,7 +2176,6 @@ loop_with_complex_edge_p (class loop *loop)
        res = true;
        break;
       }
-  edges.release ();
   return res;
 }
 #endif
@@ -2222,7 +2210,7 @@ loop_compare_func (const void *v1p, const void *v2p)
    hardly helps (for irregular register file architecture it could
    help by choosing a better hard register in the loop but we prefer
    faster allocation even in this case).  We also remove cheap loops
-   if there are more than IRA_MAX_LOOPS_NUM of them.  Loop with EH
+   if there are more than param_ira_max_loops_num of them.  Loop with EH
    exit or enter edges are removed too because the allocation might
    require put pseudo moves on the EH edges (we could still do this
    for pseudos with caller saved hard registers in some cases but it
@@ -2258,7 +2246,7 @@ mark_loops_for_removal (void)
             );
       }
   qsort (sorted_loops, n, sizeof (ira_loop_tree_node_t), loop_compare_func);
-  for (i = 0; i < n - IRA_MAX_LOOPS_NUM; i++)
+  for (i = 0; i < n - param_ira_max_loops_num; i++)
     {
       sorted_loops[i]->to_remove_p = true;
       if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
@@ -2419,8 +2407,9 @@ propagate_some_info_from_allocno (ira_allocno_t a, ira_allocno_t from_a)
   ALLOCNO_CALLS_CROSSED_NUM (a) += ALLOCNO_CALLS_CROSSED_NUM (from_a);
   ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a)
     += ALLOCNO_CHEAP_CALLS_CROSSED_NUM (from_a);
-  IOR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a),
-                   ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (from_a));
+  ALLOCNO_CROSSED_CALLS_ABIS (a) |= ALLOCNO_CROSSED_CALLS_ABIS (from_a);
+  ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a)
+    |= ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (from_a);
 
   ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
     += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (from_a);
@@ -3060,8 +3049,10 @@ copy_info_to_removed_store_destinations (int regno)
        += ALLOCNO_CALLS_CROSSED_NUM (a);
       ALLOCNO_CHEAP_CALLS_CROSSED_NUM (parent_a)
        += ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a);
-      IOR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (parent_a),
-                       ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a));
+      ALLOCNO_CROSSED_CALLS_ABIS (parent_a)
+       |= ALLOCNO_CROSSED_CALLS_ABIS (a);
+      ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (parent_a)
+       |= ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a);
       ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a)
        += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
       merged_p = true;
@@ -3159,6 +3150,9 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
                -= ALLOCNO_CALLS_CROSSED_NUM (a);
              ALLOCNO_CHEAP_CALLS_CROSSED_NUM (parent_a)
                -= ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a);
+             /* Assume that ALLOCNO_CROSSED_CALLS_ABIS and
+                ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS stay the same.
+                We'd need to rebuild the IR to do better.  */
              ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a)
                -= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
              ira_assert (ALLOCNO_CALLS_CROSSED_NUM (parent_a) >= 0
@@ -3466,7 +3460,7 @@ ira_build (void)
         allocno crossing calls.  */
       FOR_EACH_ALLOCNO (a, ai)
        if (ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
-         ior_hard_reg_conflicts (a, &call_used_reg_set);
+         ior_hard_reg_conflicts (a, ira_need_caller_save_regs (a));
     }
   if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
     print_copies (ira_dump_file);