]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/ira-costs.c
c++: Handle multiple aggregate overloads [PR95319].
[thirdparty/gcc.git] / gcc / ira-costs.c
index c3451f03992922adc79bfc663f814c76fdc14b21..6891156b5aaa6cdc7d43e536a74e077e216eef0c 100644 (file)
@@ -1,5 +1,5 @@
 /* IRA hard register and memory cost calculation for allocnos or pseudos.
-   Copyright (C) 2006-2018 Free Software Foundation, Inc.
+   Copyright (C) 2006-2020 Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
 This file is part of GCC.
@@ -237,7 +237,7 @@ setup_cost_classes (cost_classes_t from)
    allocated.  */
 static cost_classes_t
 restrict_cost_classes (cost_classes_t full, machine_mode mode,
-                      const HARD_REG_SET &regs)
+                      const_hard_reg_set regs)
 {
   static struct cost_classes narrow;
   int map[N_REG_CLASSES];
@@ -254,12 +254,9 @@ restrict_cost_classes (cost_classes_t full, machine_mode mode,
 
       /* Calculate the set of registers in CL that belong to REGS and
         are valid for MODE.  */
-      HARD_REG_SET valid_for_cl;
-      COPY_HARD_REG_SET (valid_for_cl, reg_class_contents[cl]);
-      AND_HARD_REG_SET (valid_for_cl, regs);
-      AND_COMPL_HARD_REG_SET (valid_for_cl,
-                             ira_prohibited_class_mode_regs[cl][mode]);
-      AND_COMPL_HARD_REG_SET (valid_for_cl, ira_no_alloc_regs);
+      HARD_REG_SET valid_for_cl = reg_class_contents[cl] & regs;
+      valid_for_cl &= ~(ira_prohibited_class_mode_regs[cl][mode]
+                       | ira_no_alloc_regs);
       if (hard_reg_set_empty_p (valid_for_cl))
        continue;
 
@@ -343,8 +340,7 @@ setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass)
 
   if ((classes_ptr = cost_classes_aclass_cache[aclass]) == NULL)
     {
-      COPY_HARD_REG_SET (temp, reg_class_contents[aclass]);
-      AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
+      temp = reg_class_contents[aclass] & ~ira_no_alloc_regs;
       /* We exclude classes from consideration which are subsets of
         ACLASS only if ACLASS is an uniform class.  */
       exclude_p = ira_uniform_class_p[aclass];
@@ -356,8 +352,7 @@ setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass)
            {
              /* Exclude non-uniform classes which are subsets of
                 ACLASS.  */
-             COPY_HARD_REG_SET (temp2, reg_class_contents[cl]);
-             AND_COMPL_HARD_REG_SET (temp2, ira_no_alloc_regs);
+             temp2 = reg_class_contents[cl] & ~ira_no_alloc_regs;
              if (hard_reg_set_subset_p (temp2, temp) && cl != aclass)
                continue;
            }
@@ -389,8 +384,8 @@ setup_regno_cost_classes_by_aclass (int regno, enum reg_class aclass)
 
 /* Setup cost classes for pseudo REGNO with MODE.  Usage of MODE can
    decrease number of cost classes for the pseudo, if hard registers
-   of some important classes can not hold a value of MODE.  So the
-   pseudo can not get hard register of some important classes and cost
+   of some important classes cannot hold a value of MODE.  So the
+   pseudo cannot get hard register of some important classes and cost
    calculation for such important classes is only wasting CPU
    time.  */
 static void
@@ -1323,20 +1318,13 @@ record_operand_costs (rtx_insn *insn, enum reg_class *pref)
          move_costs = ira_register_move_cost[mode];
          hard_reg_class = REGNO_REG_CLASS (other_regno);
          bigger_hard_reg_class = ira_pressure_class_translate[hard_reg_class];
-         if (bigger_hard_reg_class == NO_REGS
-             && (other_regno == STACK_POINTER_REGNUM
-#ifdef STATIC_CHAIN_REGNUM
-                 || other_regno == STATIC_CHAIN_REGNUM
-#endif
-                 || other_regno == FRAME_POINTER_REGNUM
-                 || other_regno == HARD_FRAME_POINTER_REGNUM))
-           bigger_hard_reg_class = GENERAL_REGS;
          /* Target code may return any cost for mode which does not
-            fit the the hard reg class (e.g. DImode for AREG on
+            fit the hard reg class (e.g. DImode for AREG on
             i386).  Check this and use a bigger class to get the
             right cost.  */
-         if (! ira_hard_reg_in_set_p (other_regno, mode,
-                                      reg_class_contents[hard_reg_class]))
+         if (bigger_hard_reg_class != NO_REGS
+             && ! ira_hard_reg_in_set_p (other_regno, mode,
+                                         reg_class_contents[hard_reg_class]))
            hard_reg_class = bigger_hard_reg_class;
          i = regno == (int) REGNO (src) ? 1 : 0;
          for (k = cost_classes_ptr->num - 1; k >= 0; k--)
@@ -1345,17 +1333,6 @@ record_operand_costs (rtx_insn *insn, enum reg_class *pref)
              cost = (i == 0
                      ? move_costs[hard_reg_class][rclass]
                      : move_costs[rclass][hard_reg_class]);
-             /* Target code might define wrong big costs for smaller
-                reg classes or reg classes containing only fixed hard
-                regs.  Try a bigger class.  */
-             if (bigger_hard_reg_class != hard_reg_class)
-               {
-                 int cost2 = (i == 0
-                              ? move_costs[bigger_hard_reg_class][rclass]
-                              : move_costs[rclass][bigger_hard_reg_class]);
-                 if (cost2 < cost)
-                   cost = cost2;
-               }
              
              op_costs[i]->cost[k] = cost * frequency;
              /* If we have assigned a class to this allocno in our
@@ -1500,13 +1477,6 @@ scan_one_insn (rtx_insn *insn)
       return insn;
     }
 
-  if (pat_code == CLOBBER_HIGH)
-    {
-      gcc_assert (REG_P (XEXP (PATTERN (insn), 0))
-                 && HARD_REGISTER_P (XEXP (PATTERN (insn), 0)));
-      return insn;
-    }
-
   counted_mem = false;
   set = single_set (insn);
   extract_insn (insn);
@@ -2125,6 +2095,13 @@ process_bb_node_for_hard_reg_moves (ira_loop_tree_node_t loop_tree_node)
        }
       else
        continue;
+      if (reg_class_size[(int) REGNO_REG_CLASS (hard_regno)]
+         == (ira_reg_class_max_nregs
+             [REGNO_REG_CLASS (hard_regno)][(int) ALLOCNO_MODE(a)]))
+       /* If the class can provide only one hard reg to the allocno,
+          we processed the insn record_operand_costs already and we
+          actually updated the hard reg cost there.  */
+       continue;
       rclass = ALLOCNO_CLASS (a);
       if (! TEST_HARD_REG_BIT (reg_class_contents[rclass], hard_regno))
        continue;
@@ -2356,7 +2333,6 @@ ira_tune_allocno_costs (void)
   ira_allocno_object_iterator oi;
   ira_object_t obj;
   bool skip_p;
-  HARD_REG_SET *crossed_calls_clobber_regs;
 
   FOR_EACH_ALLOCNO (a, ai)
     {
@@ -2391,14 +2367,7 @@ ira_tune_allocno_costs (void)
                continue;
              rclass = REGNO_REG_CLASS (regno);
              cost = 0;
-             crossed_calls_clobber_regs
-               = &(ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a));
-             if (ira_hard_reg_set_intersection_p (regno, mode,
-                                                  *crossed_calls_clobber_regs)
-                 && (ira_hard_reg_set_intersection_p (regno, mode,
-                                                      call_used_reg_set)
-                     || targetm.hard_regno_call_part_clobbered (regno,
-                                                                mode)))
+             if (ira_need_caller_save_p (a, regno))
                cost += (ALLOCNO_CALL_FREQ (a)
                         * (ira_memory_move_cost[mode][rclass][0]
                            + ira_memory_move_cost[mode][rclass][1]));