Remove clobber_high
[platform/upstream/gcc.git] / gcc / ira-costs.c
index cfda432..baf7261 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-2019 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
@@ -1314,27 +1309,32 @@ record_operand_costs (rtx_insn *insn, enum reg_class *pref)
          machine_mode mode = GET_MODE (SET_SRC (set));
          cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
          enum reg_class *cost_classes = cost_classes_ptr->classes;
-         reg_class_t rclass, hard_reg_class, pref_class;
+         reg_class_t rclass, hard_reg_class, pref_class, bigger_hard_reg_class;
          int cost, k;
+         move_table *move_costs;
          bool dead_p = find_regno_note (insn, REG_DEAD, REGNO (src));
 
+         ira_init_register_move_cost_if_necessary (mode);
+         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];
          /* Target code may return any cost for mode which does not
             fit the 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]))
-           hard_reg_class = ira_pressure_class_translate[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--)
            {
              rclass = cost_classes[k];
-             cost = ((i == 0
-                      ? ira_register_move_cost[mode][hard_reg_class][rclass]
-                      : ira_register_move_cost[mode][rclass][hard_reg_class])
-                     * frequency);
-             op_costs[i]->cost[k] = cost;
+             cost = (i == 0
+                     ? move_costs[hard_reg_class][rclass]
+                     : move_costs[rclass][hard_reg_class]);
+             
+             op_costs[i]->cost[k] = cost * frequency;
              /* If we have assigned a class to this allocno in our
                 first pass, add a cost to this alternative
                 corresponding to what we would add if this allocno
@@ -1349,7 +1349,7 @@ record_operand_costs (rtx_insn *insn, enum reg_class *pref)
                  else if (ira_reg_class_intersect[pref_class][rclass]
                           == NO_REGS)
                    op_costs[i]->cost[k]
-                     += (ira_register_move_cost[mode][pref_class][rclass]
+                     += (move_costs[pref_class][rclass]
                          * frequency);
                }
              /* If this insn is a single set copying operand 1 to
@@ -1477,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);
@@ -1534,36 +1527,40 @@ scan_one_insn (rtx_insn *insn)
   /* Now add the cost for each operand to the total costs for its
      allocno.  */
   for (i = 0; i < recog_data.n_operands; i++)
-    if (REG_P (recog_data.operand[i])
-       && REGNO (recog_data.operand[i]) >= FIRST_PSEUDO_REGISTER)
-      {
-       int regno = REGNO (recog_data.operand[i]);
-       struct costs *p = COSTS (costs, COST_INDEX (regno));
-       struct costs *q = op_costs[i];
-       int *p_costs = p->cost, *q_costs = q->cost;
-       cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
-       int add_cost;
-
-       /* If the already accounted for the memory "cost" above, don't
-          do so again.  */
-       if (!counted_mem)
-         {
-           add_cost = q->mem_cost;
-           if (add_cost > 0 && INT_MAX - add_cost < p->mem_cost)
-             p->mem_cost = INT_MAX;
-           else
-             p->mem_cost += add_cost;
-         }
-       for (k = cost_classes_ptr->num - 1; k >= 0; k--)
-         {
-           add_cost = q_costs[k];
-           if (add_cost > 0 && INT_MAX - add_cost < p_costs[k])
-             p_costs[k] = INT_MAX;
-           else
-             p_costs[k] += add_cost;
-         }
-      }
-
+    {
+      rtx op = recog_data.operand[i];
+      
+      if (GET_CODE (op) == SUBREG)
+       op = SUBREG_REG (op);
+      if (REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER)
+       {
+         int regno = REGNO (op);
+         struct costs *p = COSTS (costs, COST_INDEX (regno));
+         struct costs *q = op_costs[i];
+         int *p_costs = p->cost, *q_costs = q->cost;
+         cost_classes_t cost_classes_ptr = regno_cost_classes[regno];
+         int add_cost;
+         
+         /* If the already accounted for the memory "cost" above, don't
+            do so again.  */
+         if (!counted_mem)
+           {
+             add_cost = q->mem_cost;
+             if (add_cost > 0 && INT_MAX - add_cost < p->mem_cost)
+               p->mem_cost = INT_MAX;
+             else
+               p->mem_cost += add_cost;
+           }
+         for (k = cost_classes_ptr->num - 1; k >= 0; k--)
+           {
+             add_cost = q_costs[k];
+             if (add_cost > 0 && INT_MAX - add_cost < p_costs[k])
+               p_costs[k] = INT_MAX;
+             else
+               p_costs[k] += add_cost;
+           }
+       }
+    }
   return insn;
 }
 
@@ -2098,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;
@@ -2329,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)
     {
@@ -2364,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]));