pr60092.c: Remove default dg-skip-if arguments.
[gcc.git] / gcc / loop-iv.c
index 5695e29825658504237f01467692efed01c8c37b..9091220642ccda3ac559bec063c2d5028815a26a 100644 (file)
@@ -1,5 +1,5 @@
 /* Rtl-level induction variable analysis.
-   Copyright (C) 2004-2013 Free Software Foundation, Inc.
+   Copyright (C) 2004-2014 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -60,7 +60,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "intl.h"
 #include "diagnostic-core.h"
 #include "df.h"
-#include "hashtab.h"
+#include "hash-table.h"
 #include "dumpfile.h"
 
 /* Possible return values of iv_get_reaching_def.  */
@@ -99,16 +99,42 @@ static unsigned int iv_ref_table_size = 0;
 static struct rtx_iv ** iv_ref_table;
 
 /* Induction variable stored at the reference.  */
-#define DF_REF_IV(REF) iv_ref_table[DF_REF_ID(REF)]
-#define DF_REF_IV_SET(REF, IV) iv_ref_table[DF_REF_ID(REF)] = (IV)
+#define DF_REF_IV(REF) iv_ref_table[DF_REF_ID (REF)]
+#define DF_REF_IV_SET(REF, IV) iv_ref_table[DF_REF_ID (REF)] = (IV)
 
 /* The current loop.  */
 
 static struct loop *current_loop;
 
+/* Hashtable helper.  */
+
+struct biv_entry_hasher : typed_free_remove <biv_entry>
+{
+  typedef biv_entry value_type;
+  typedef rtx_def compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Returns hash value for biv B.  */
+
+inline hashval_t
+biv_entry_hasher::hash (const value_type *b)
+{
+  return b->regno;
+}
+
+/* Compares biv B and register R.  */
+
+inline bool
+biv_entry_hasher::equal (const value_type *b, const compare_type *r)
+{
+  return b->regno == REGNO (r);
+}
+
 /* Bivs of the current loop.  */
 
-static htab_t bivs;
+static hash_table <biv_entry_hasher> bivs;
 
 static bool iv_analyze_op (rtx, rtx, struct rtx_iv *);
 
@@ -186,7 +212,7 @@ lowpart_subreg (enum machine_mode outer_mode, rtx expr,
 static void
 check_iv_ref_table_size (void)
 {
-  if (iv_ref_table_size < DF_DEFS_TABLE_SIZE())
+  if (iv_ref_table_size < DF_DEFS_TABLE_SIZE ())
     {
       unsigned int new_size = DF_DEFS_TABLE_SIZE () + (DF_DEFS_TABLE_SIZE () / 4);
       iv_ref_table = XRESIZEVEC (struct rtx_iv *, iv_ref_table, new_size);
@@ -243,51 +269,27 @@ clear_iv_info (void)
        }
     }
 
-  htab_empty (bivs);
-}
-
-/* Returns hash value for biv B.  */
-
-static hashval_t
-biv_hash (const void *b)
-{
-  return ((const struct biv_entry *) b)->regno;
+  bivs.empty ();
 }
 
-/* Compares biv B and register R.  */
-
-static int
-biv_eq (const void *b, const void *r)
-{
-  return ((const struct biv_entry *) b)->regno == REGNO ((const_rtx) r);
-}
 
 /* Prepare the data for an induction variable analysis of a LOOP.  */
 
 void
 iv_analysis_loop_init (struct loop *loop)
 {
-  basic_block *body = get_loop_body_in_dom_order (loop), bb;
-  bitmap blocks = BITMAP_ALLOC (NULL);
-  unsigned i;
-
   current_loop = loop;
 
   /* Clear the information from the analysis of the previous loop.  */
   if (clean_slate)
     {
       df_set_flags (DF_EQ_NOTES + DF_DEFER_INSN_RESCAN);
-      bivs = htab_create (10, biv_hash, biv_eq, free);
+      bivs.create (10);
       clean_slate = false;
     }
   else
     clear_iv_info ();
 
-  for (i = 0; i < loop->num_nodes; i++)
-    {
-      bb = body[i];
-      bitmap_set_bit (blocks, bb->index);
-    }
   /* Get rid of the ud chains before processing the rescans.  Then add
      the problem back.  */
   df_remove_problem (df_chain);
@@ -295,14 +297,11 @@ iv_analysis_loop_init (struct loop *loop)
   df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
   df_chain_add_problem (DF_UD_CHAIN);
   df_note_add_problem ();
-  df_set_blocks (blocks);
-  df_analyze ();
+  df_analyze_loop (loop);
   if (dump_file)
     df_dump_region (dump_file);
 
   check_iv_ref_table_size ();
-  BITMAP_FREE (blocks);
-  free (body);
 }
 
 /* Finds the definition of REG that dominates loop latch and stores
@@ -425,7 +424,9 @@ iv_subreg (struct rtx_iv *iv, enum machine_mode mode)
       && !iv->first_special)
     {
       rtx val = get_iv_value (iv, const0_rtx);
-      val = lowpart_subreg (mode, val, iv->extend_mode);
+      val = lowpart_subreg (mode, val,
+                           iv->extend == IV_UNKNOWN_EXTEND
+                           ? iv->mode : iv->extend_mode);
 
       iv->base = val;
       iv->extend = IV_UNKNOWN_EXTEND;
@@ -465,8 +466,14 @@ iv_extend (struct rtx_iv *iv, enum iv_extend_code extend, enum machine_mode mode
       && !iv->first_special)
     {
       rtx val = get_iv_value (iv, const0_rtx);
+      if (iv->extend_mode != iv->mode
+         && iv->extend != IV_UNKNOWN_EXTEND
+         && iv->extend != extend)
+       val = lowpart_subreg (iv->mode, val, iv->extend_mode);
       val = simplify_gen_unary (iv_extend_to_rtx_code (extend), mode,
-                               val, iv->extend_mode);
+                               val,
+                               iv->extend == extend
+                               ? iv->extend_mode : iv->mode);
       iv->base = val;
       iv->extend = IV_UNKNOWN_EXTEND;
       iv->mode = iv->extend_mode = mode;
@@ -837,8 +844,7 @@ record_iv (df_ref def, struct rtx_iv *iv)
 static bool
 analyzed_for_bivness_p (rtx def, struct rtx_iv *iv)
 {
-  struct biv_entry *biv =
-    (struct biv_entry *) htab_find_with_hash (bivs, def, REGNO (def));
+  struct biv_entry *biv = bivs.find_with_hash (def, REGNO (def));
 
   if (!biv)
     return false;
@@ -851,7 +857,7 @@ static void
 record_biv (rtx def, struct rtx_iv *iv)
 {
   struct biv_entry *biv = XNEW (struct biv_entry);
-  void **slot = htab_find_slot_with_hash (bivs, def, REGNO (def), INSERT);
+  biv_entry **slot = bivs.find_slot_with_hash (def, REGNO (def), INSERT);
 
   biv->regno = REGNO (def);
   biv->iv = *iv;
@@ -1293,11 +1299,10 @@ iv_analysis_done (void)
       clear_iv_info ();
       clean_slate = true;
       df_finish_pass (true);
-      htab_delete (bivs);
+      bivs.dispose ();
       free (iv_ref_table);
       iv_ref_table = NULL;
       iv_ref_table_size = 0;
-      bivs = NULL;
     }
 }
 
@@ -1920,7 +1925,7 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
     return;
 
   e = loop_preheader_edge (loop);
-  if (e->src == ENTRY_BLOCK_PTR)
+  if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
     return;
 
   altered = ALLOC_REG_SET (&reg_obstack);
@@ -2051,7 +2056,7 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
        }
 
       if (!single_pred_p (e->src)
-         || single_pred (e->src) == ENTRY_BLOCK_PTR)
+         || single_pred (e->src) == ENTRY_BLOCK_PTR_FOR_FN (cfun))
        break;
       e = single_pred_edge (e->src);
     }
@@ -2663,11 +2668,11 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition,
       bound = GEN_INT (((unsigned HOST_WIDEST_INT) 1 << (size - 1 ) << 1) - 1);
 
       tmp1 = lowpart_subreg (mode, iv1.base, comp_mode);
-      tmp = simplify_gen_binary (UMOD, mode, tmp1, GEN_INT (d));
+      tmp = simplify_gen_binary (UMOD, mode, tmp1, gen_int_mode (d, mode));
       assumption = simplify_gen_relational (NE, SImode, mode, tmp, const0_rtx);
       desc->infinite = alloc_EXPR_LIST (0, assumption, desc->infinite);
 
-      tmp = simplify_gen_binary (UDIV, mode, tmp1, GEN_INT (d));
+      tmp = simplify_gen_binary (UDIV, mode, tmp1, gen_int_mode (d, mode));
       inv = inverse (s, size);
       tmp = simplify_gen_binary (MULT, mode, tmp, gen_int_mode (inv, mode));
       desc->niter_expr = simplify_gen_binary (AND, mode, tmp, bound);
@@ -2992,9 +2997,9 @@ find_simple_exit (struct loop *loop, struct niter_desc *desc)
          fprintf (dump_file, "\n");
 
          fprintf (dump_file, "  upper bound: %li\n",
-                  (long)max_loop_iterations_int (loop));
+                  (long)get_max_loop_iterations_int (loop));
          fprintf (dump_file, "  realistic bound: %li\n",
-                  (long)estimated_loop_iterations_int (loop));
+                  (long)get_estimated_loop_iterations_int (loop));
        }
       else
        fprintf (dump_file, "Loop %d is not simple.\n", loop->num);