re PR c++/67523 (ICE with invalid combined simd inside of a template)
[gcc.git] / gcc / ira-color.c
index 543440d919bbe62aa41709b1e9e184a6cf0c71b8..74d2c2ed6081c42c6dd8e56bbd121abbf7f26099 100644 (file)
@@ -21,35 +21,16 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
+#include "backend.h"
+#include "predict.h"
+#include "tree.h"
 #include "rtl.h"
+#include "df.h"
 #include "tm_p.h"
 #include "target.h"
 #include "regs.h"
 #include "flags.h"
-#include "sbitmap.h"
-#include "bitmap.h"
-#include "hash-table.h"
-#include "hard-reg-set.h"
-#include "predict.h"
-#include "vec.h"
-#include "hashtab.h"
-#include "hash-set.h"
-#include "machmode.h"
-#include "input.h"
-#include "function.h"
-#include "dominance.h"
-#include "cfg.h"
-#include "basic-block.h"
-#include "symtab.h"
-#include "statistics.h"
-#include "double-int.h"
-#include "real.h"
-#include "fixed-value.h"
 #include "alias.h"
-#include "wide-int.h"
-#include "inchash.h"
-#include "tree.h"
 #include "insn-config.h"
 #include "expmed.h"
 #include "dojump.h"
@@ -62,7 +43,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic-core.h"
 #include "reload.h"
 #include "params.h"
-#include "df.h"
+#include "cfgloop.h"
+#include "ira.h"
+#include "alloc-pool.h"
 #include "ira-int.h"
 
 typedef struct allocno_hard_regs *allocno_hard_regs_t;
@@ -123,21 +106,6 @@ struct update_cost_record
   int divisor;
   /* Next record for given allocno.  */
   struct update_cost_record *next;
-
-  /* Pool allocation new operator.  */
-  inline void *operator new (size_t)
-  {
-    return pool.allocate ();
-  }
-
-  /* Delete operator utilizing pool allocation.  */
-  inline void operator delete (void *ptr)
-  {
-    pool.remove ((update_cost_record *) ptr);
-  }
-
-  /* Memory allocation pool.  */
-  static pool_allocator<update_cost_record> pool;
 };
 
 /* To decrease footprint of ira_allocno structure we store all data
@@ -240,10 +208,8 @@ static vec<ira_allocno_t> allocno_stack_vec;
 /* Vector of unique allocno hard registers.  */
 static vec<allocno_hard_regs_t> allocno_hard_regs_vec;
 
-struct allocno_hard_regs_hasher : typed_noop_remove <allocno_hard_regs>
+struct allocno_hard_regs_hasher : nofree_ptr_hash <allocno_hard_regs>
 {
-  typedef allocno_hard_regs *value_type;
-  typedef allocno_hard_regs *compare_type;
   static inline hashval_t hash (const allocno_hard_regs *);
   static inline bool equal (const allocno_hard_regs *,
                            const allocno_hard_regs *);
@@ -1078,7 +1044,10 @@ setup_profitable_hard_regs (void)
        continue;
       data = ALLOCNO_COLOR_DATA (a);
       if (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL
-         && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a))
+         && ALLOCNO_CLASS_COST (a) > ALLOCNO_MEMORY_COST (a)
+         /* Do not empty profitable regs for static chain pointer
+            pseudo when non-local goto is used.  */
+         && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
        CLEAR_HARD_REG_SET (data->profitable_hard_regs);
       else
        {
@@ -1160,7 +1129,10 @@ setup_profitable_hard_regs (void)
              if (! TEST_HARD_REG_BIT (data->profitable_hard_regs,
                                       hard_regno))
                continue;
-             if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j])
+             if (ALLOCNO_UPDATED_MEMORY_COST (a) < costs[j]
+                 /* Do not remove HARD_REGNO for static chain pointer
+                    pseudo when non-local goto is used.  */
+                 && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
                CLEAR_HARD_REG_BIT (data->profitable_hard_regs,
                                    hard_regno);
              else if (min_cost > costs[j])
@@ -1168,7 +1140,10 @@ setup_profitable_hard_regs (void)
            }
        }
       else if (ALLOCNO_UPDATED_MEMORY_COST (a)
-              < ALLOCNO_UPDATED_CLASS_COST (a))
+              < ALLOCNO_UPDATED_CLASS_COST (a)
+              /* Do not empty profitable regs for static chain
+                 pointer pseudo when non-local goto is used.  */
+              && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
        CLEAR_HARD_REG_SET (data->profitable_hard_regs);
       if (ALLOCNO_UPDATED_CLASS_COST (a) > min_cost)
        ALLOCNO_UPDATED_CLASS_COST (a) = min_cost;
@@ -1181,7 +1156,7 @@ setup_profitable_hard_regs (void)
    allocnos.  */
 
 /* Pool for update cost records.  */
-static pool_allocator<update_cost_record> update_cost_record_pool
+static object_allocator<update_cost_record> update_cost_record_pool
   ("update cost records", 100);
 
 /* Return new update cost record with given params.  */
@@ -1745,15 +1720,22 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
          /* Reload can give another class so we need to check all
             allocnos.  */
          if (!retry_p
-             && (!bitmap_bit_p (consideration_allocno_bitmap,
-                                ALLOCNO_NUM (conflict_a))
-                 || ((!ALLOCNO_ASSIGNED_P (conflict_a)
-                      || ALLOCNO_HARD_REGNO (conflict_a) < 0)
-                     && !(hard_reg_set_intersect_p
-                          (profitable_hard_regs,
-                           ALLOCNO_COLOR_DATA
-                           (conflict_a)->profitable_hard_regs)))))
-           continue;
+             && ((!ALLOCNO_ASSIGNED_P (conflict_a)
+                  || ALLOCNO_HARD_REGNO (conflict_a) < 0)
+                 && !(hard_reg_set_intersect_p
+                      (profitable_hard_regs,
+                       ALLOCNO_COLOR_DATA
+                       (conflict_a)->profitable_hard_regs))))
+           {
+             /* All conflict allocnos are in consideration bitmap
+                when retry_p is false.  It might change in future and
+                if it happens the assert will be broken.  It means
+                the code should be modified for the new
+                assumptions.  */
+             ira_assert (bitmap_bit_p (consideration_allocno_bitmap,
+                                       ALLOCNO_NUM (conflict_a)));
+             continue;
+           }
          conflict_aclass = ALLOCNO_CLASS (conflict_a);
          ira_assert (ira_reg_classes_intersect_p
                      [aclass][conflict_aclass]);
@@ -1881,7 +1863,10 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
          ira_assert (hard_regno >= 0);
        }
     }
-  if (min_full_cost > mem_cost)
+  if (min_full_cost > mem_cost
+      /* Do not spill static chain pointer pseudo when non-local goto
+        is used.  */
+      && ! non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a)))
     {
       if (! retry_p && internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
        fprintf (ira_dump_file, "(memory is more profitable %d vs %d) ",
@@ -2507,6 +2492,12 @@ allocno_spill_priority_compare (ira_allocno_t a1, ira_allocno_t a2)
 {
   int pri1, pri2, diff;
 
+  /* Avoid spilling static chain pointer pseudo when non-local goto is
+     used.  */
+  if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1)))
+    return 1;
+  else if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2)))
+    return -1;
   if (ALLOCNO_BAD_SPILL_P (a1) && ! ALLOCNO_BAD_SPILL_P (a2))
     return 1;
   if (ALLOCNO_BAD_SPILL_P (a2) && ! ALLOCNO_BAD_SPILL_P (a1))
@@ -2759,6 +2750,11 @@ improve_allocation (void)
   ira_allocno_t a;
   bitmap_iterator bi;
 
+  /* Don't bother to optimize the code with static chain pointer and
+     non-local goto in order not to spill the chain pointer
+     pseudo.  */
+  if (cfun->static_chain_decl && crtl->has_nonlocal_goto)
+    return;
   /* Clear counts used to process conflicting allocnos only once for
      each allocno.  */
   EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi)
@@ -2965,6 +2961,12 @@ allocno_priority_compare_func (const void *v1p, const void *v2p)
   ira_allocno_t a2 = *(const ira_allocno_t *) v2p;
   int pri1, pri2;
 
+  /* Assign hard reg to static chain pointer pseudo first when
+     non-local goto is used.  */
+  if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a1)))
+    return 1;
+  else if (non_spilled_static_chain_regno_p (ALLOCNO_REGNO (a2)))
+    return -1;
   pri1 = allocno_priorities[ALLOCNO_NUM (a1)];
   pri2 = allocno_priorities[ALLOCNO_NUM (a2)];
   if (pri2 != pri1)
@@ -3406,7 +3408,10 @@ move_spill_restore (void)
                 by copy although the allocno will not get memory
                 slot.  */
              || ira_equiv_no_lvalue_p (regno)
-             || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a)))
+             || !bitmap_bit_p (loop_node->border_allocnos, ALLOCNO_NUM (a))
+             /* Do not spill static chain pointer pseudo when
+                non-local goto is used.  */
+             || non_spilled_static_chain_regno_p (regno))
            continue;
          mode = ALLOCNO_MODE (a);
          rclass = ALLOCNO_CLASS (a);