Add -march=interaptiv.
[platform/upstream/gcc.git] / gcc / tree-switch-conversion.c
index 32f0a11..3201912 100644 (file)
@@ -1,6 +1,6 @@
 /* Lower GIMPLE_SWITCH expressions to something more efficient than
    a jump table.
-   Copyright (C) 2006-2014 Free Software Foundation, Inc.
+   Copyright (C) 2006-2015 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -25,42 +25,25 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "line-map.h"
+#include "backend.h"
+#include "cfghooks.h"
+#include "tree.h"
+#include "gimple.h"
+#include "rtl.h"
+#include "ssa.h"
 #include "params.h"
 #include "flags.h"
-#include "tree.h"
+#include "alias.h"
+#include "fold-const.h"
 #include "varasm.h"
 #include "stor-layout.h"
-#include "predict.h"
-#include "vec.h"
-#include "hashtab.h"
-#include "hash-set.h"
-#include "machmode.h"
-#include "hard-reg-set.h"
-#include "input.h"
-#include "function.h"
-#include "dominance.h"
-#include "cfg.h"
 #include "cfganal.h"
-#include "basic-block.h"
-#include "tree-ssa-alias.h"
 #include "internal-fn.h"
-#include "gimple-expr.h"
-#include "is-a.h"
-#include "gimple.h"
 #include "gimplify.h"
 #include "gimple-iterator.h"
 #include "gimplify-me.h"
-#include "gimple-ssa.h"
-#include "hash-map.h"
-#include "plugin-api.h"
-#include "ipa-ref.h"
 #include "cgraph.h"
 #include "tree-cfg.h"
-#include "tree-phinodes.h"
-#include "stringpool.h"
-#include "tree-ssanames.h"
 #include "tree-pass.h"
 #include "gimple-pretty-print.h"
 #include "cfgloop.h"
@@ -70,7 +53,15 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "langhooks.h"
 
 /* Need to include expr.h and optabs.h for lshift_cheap_p.  */
+#include "insn-config.h"
+#include "expmed.h"
+#include "dojump.h"
+#include "explow.h"
+#include "calls.h"
+#include "emit-rtl.h"
+#include "stmt.h"
 #include "expr.h"
+#include "insn-codes.h"
 #include "optabs.h"
 \f
 /* Maximum number of case bit tests.
@@ -99,7 +90,7 @@ hoist_edge_and_branch_if_true (gimple_stmt_iterator *gsip,
                               bool update_dominators)
 {
   tree tmp;
-  gimple cond_stmt;
+  gcond *cond_stmt;
   edge e_false;
   basic_block new_bb, split_bb = gsi_bb (*gsip);
   bool dominated_e_true = false;
@@ -284,7 +275,7 @@ case_bit_test_cmp (const void *p1, const void *p2)
     node targets.  */
 
 static void
-emit_case_bit_tests (gimple swtch, tree index_expr,
+emit_case_bit_tests (gswitch *swtch, tree index_expr,
                     tree minval, tree range, tree maxval)
 {
   struct case_bit_test test[MAX_CASE_BIT_TESTS];
@@ -303,7 +294,7 @@ emit_case_bit_tests (gimple swtch, tree index_expr,
   unsigned int branch_num = gimple_switch_num_labels (swtch);
 
   gimple_stmt_iterator gsi;
-  gimple shift_stmt;
+  gassign *shift_stmt;
 
   tree idx, tmp, csui;
   tree word_type_node = lang_hooks.types.type_for_mode (word_mode, 1);
@@ -373,9 +364,11 @@ emit_case_bit_tests (gimple swtch, tree index_expr,
       for (i = 0; i < count; i++)
        {
          rtx r = immed_wide_int_const (test[i].mask, word_mode);
-         cost_diff += set_src_cost (gen_rtx_AND (word_mode, reg, r), speed_p);
+         cost_diff += set_src_cost (gen_rtx_AND (word_mode, reg, r),
+                                    word_mode, speed_p);
          r = immed_wide_int_const (wi::lshift (test[i].mask, m), word_mode);
-         cost_diff -= set_src_cost (gen_rtx_AND (word_mode, reg, r), speed_p);
+         cost_diff -= set_src_cost (gen_rtx_AND (word_mode, reg, r),
+                                    word_mode, speed_p);
        }
       if (cost_diff > 0)
        {
@@ -443,7 +436,7 @@ emit_case_bit_tests (gimple swtch, tree index_expr,
     }
 
   /* csui = (1 << (word_mode) idx) */
-  csui = make_ssa_name (word_type_node, NULL);
+  csui = make_ssa_name (word_type_node);
   tmp = fold_build2 (LSHIFT_EXPR, word_type_node, word_mode_one,
                     fold_convert (word_type_node, idx));
   tmp = force_gimple_operand_gsi (&gsi, tmp,
@@ -620,7 +613,7 @@ struct switch_conv_info
 /* Collect information about GIMPLE_SWITCH statement SWTCH into INFO.  */
 
 static void
-collect_switch_conv_info (gimple swtch, struct switch_conv_info *info)
+collect_switch_conv_info (gswitch *swtch, struct switch_conv_info *info)
 {
   unsigned int branch_num = gimple_switch_num_labels (swtch);
   tree min_case, max_case;
@@ -758,12 +751,12 @@ check_all_empty_except_final (struct switch_conv_info *info)
 static bool
 check_final_bb (struct switch_conv_info *info)
 {
-  gimple_stmt_iterator gsi;
+  gphi_iterator gsi;
 
   info->phi_count = 0;
   for (gsi = gsi_start_phis (info->final_bb); !gsi_end_p (gsi); gsi_next (&gsi))
     {
-      gimple phi = gsi_stmt (gsi);
+      gphi *phi = gsi.phi ();
       unsigned int i;
 
       info->phi_count++;
@@ -839,7 +832,7 @@ free_temp_arrays (struct switch_conv_info *info)
 static void
 gather_default_values (tree default_case, struct switch_conv_info *info)
 {
-  gimple_stmt_iterator gsi;
+  gphi_iterator gsi;
   basic_block bb = label_to_block (CASE_LABEL (default_case));
   edge e;
   int i = 0;
@@ -853,7 +846,7 @@ gather_default_values (tree default_case, struct switch_conv_info *info)
 
   for (gsi = gsi_start_phis (info->final_bb); !gsi_end_p (gsi); gsi_next (&gsi))
     {
-      gimple phi = gsi_stmt (gsi);
+      gphi *phi = gsi.phi ();
       tree val = PHI_ARG_DEF_FROM_EDGE (phi, e);
       gcc_assert (val);
       info->default_values[i++] = val;
@@ -865,7 +858,7 @@ gather_default_values (tree default_case, struct switch_conv_info *info)
    order of phi nodes.  SWTCH is the switch statement being converted.  */
 
 static void
-build_constructors (gimple swtch, struct switch_conv_info *info)
+build_constructors (gswitch *swtch, struct switch_conv_info *info)
 {
   unsigned i, branch_num = gimple_switch_num_labels (swtch);
   tree pos = info->range_min;
@@ -876,7 +869,7 @@ build_constructors (gimple swtch, struct switch_conv_info *info)
       basic_block bb = label_to_block (CASE_LABEL (cs));
       edge e;
       tree high;
-      gimple_stmt_iterator gsi;
+      gphi_iterator gsi;
       int j;
 
       if (bb == info->final_bb)
@@ -911,7 +904,7 @@ build_constructors (gimple swtch, struct switch_conv_info *info)
       for (gsi = gsi_start_phis (info->final_bb);
           !gsi_end_p (gsi); gsi_next (&gsi))
        {
-         gimple phi = gsi_stmt (gsi);
+         gphi *phi = gsi.phi ();
          tree val = PHI_ARG_DEF_FROM_EDGE (phi, e);
          tree low = CASE_LOW (cs);
          pos = CASE_LOW (cs);
@@ -959,7 +952,7 @@ constructor_contains_same_values_p (vec<constructor_elt, va_gc> *vec)
    all the constants.  */
 
 static tree
-array_value_type (gimple swtch, tree type, int num,
+array_value_type (gswitch *swtch, tree type, int num,
                  struct switch_conv_info *info)
 {
   unsigned int i, len = vec_safe_length (info->constructors[num]);
@@ -1036,8 +1029,8 @@ array_value_type (gimple swtch, tree type, int num,
    new array.  */
 
 static void
-build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi,
-                tree tidx, struct switch_conv_info *info)
+build_one_array (gswitch *swtch, int num, tree arr_index_type,
+                gphi *phi, tree tidx, struct switch_conv_info *info)
 {
   tree name, cst;
   gimple load;
@@ -1046,7 +1039,7 @@ build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi,
 
   gcc_assert (info->default_values[num]);
 
-  name = copy_ssa_name (PHI_RESULT (phi), NULL);
+  name = copy_ssa_name (PHI_RESULT (phi));
   info->target_inbound_names[num] = name;
 
   cst = constructor_contains_same_values_p (info->constructors[num]);
@@ -1077,8 +1070,10 @@ build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi,
 
       DECL_NAME (decl) = create_tmp_var_name ("CSWTCH");
       DECL_ARTIFICIAL (decl) = 1;
+      DECL_IGNORED_P (decl) = 1;
       TREE_CONSTANT (decl) = 1;
       TREE_READONLY (decl) = 1;
+      DECL_IGNORED_P (decl) = 1;
       varpool_node::finalize_decl (decl);
 
       fetch = build4 (ARRAY_REF, value_type, decl, tidx, NULL_TREE,
@@ -1102,12 +1097,13 @@ build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi,
    them.  */
 
 static void
-build_arrays (gimple swtch, struct switch_conv_info *info)
+build_arrays (gswitch *swtch, struct switch_conv_info *info)
 {
   tree arr_index_type;
   tree tidx, sub, utype;
   gimple stmt;
   gimple_stmt_iterator gsi;
+  gphi_iterator gpi;
   int i;
   location_t loc = gimple_location (swtch);
 
@@ -1121,7 +1117,7 @@ build_arrays (gimple swtch, struct switch_conv_info *info)
     utype = lang_hooks.types.type_for_mode (TYPE_MODE (utype), 1);
 
   arr_index_type = build_index_type (info->range_size);
-  tidx = make_ssa_name (utype, NULL);
+  tidx = make_ssa_name (utype);
   sub = fold_build2_loc (loc, MINUS_EXPR, utype,
                         fold_convert_loc (loc, utype, info->index_expr),
                         fold_convert_loc (loc, utype, info->range_min));
@@ -1133,23 +1129,23 @@ build_arrays (gimple swtch, struct switch_conv_info *info)
   update_stmt (stmt);
   info->arr_ref_first = stmt;
 
-  for (gsi = gsi_start_phis (info->final_bb), i = 0;
-       !gsi_end_p (gsi); gsi_next (&gsi), i++)
-    build_one_array (swtch, i, arr_index_type, gsi_stmt (gsi), tidx, info);
+  for (gpi = gsi_start_phis (info->final_bb), i = 0;
+       !gsi_end_p (gpi); gsi_next (&gpi), i++)
+    build_one_array (swtch, i, arr_index_type, gpi.phi (), tidx, info);
 }
 
 /* Generates and appropriately inserts loads of default values at the position
    given by BSI.  Returns the last inserted statement.  */
 
-static gimple
+static gassign *
 gen_def_assigns (gimple_stmt_iterator *gsi, struct switch_conv_info *info)
 {
   int i;
-  gimple assign = NULL;
+  gassign *assign = NULL;
 
   for (i = 0; i < info->phi_count; i++)
     {
-      tree name = copy_ssa_name (info->target_inbound_names[i], NULL);
+      tree name = copy_ssa_name (info->target_inbound_names[i]);
       info->target_outbound_names[i] = name;
       assign = gimple_build_assign (name, info->default_values[i]);
       gsi_insert_before (gsi, assign, GSI_SAME_STMT);
@@ -1189,13 +1185,13 @@ static void
 fix_phi_nodes (edge e1f, edge e2f, basic_block bbf,
               struct switch_conv_info *info)
 {
-  gimple_stmt_iterator gsi;
+  gphi_iterator gsi;
   int i;
 
   for (gsi = gsi_start_phis (bbf), i = 0;
        !gsi_end_p (gsi); gsi_next (&gsi), i++)
     {
-      gimple phi = gsi_stmt (gsi);
+      gphi *phi = gsi.phi ();
       add_phi_arg (phi, info->target_inbound_names[i], e1f, UNKNOWN_LOCATION);
       add_phi_arg (phi, info->target_outbound_names[i], e2f, UNKNOWN_LOCATION);
     }
@@ -1223,18 +1219,18 @@ fix_phi_nodes (edge e1f, edge e2f, basic_block bbf,
 */
 
 static void
-gen_inbound_check (gimple swtch, struct switch_conv_info *info)
+gen_inbound_check (gswitch *swtch, struct switch_conv_info *info)
 {
   tree label_decl1 = create_artificial_label (UNKNOWN_LOCATION);
   tree label_decl2 = create_artificial_label (UNKNOWN_LOCATION);
   tree label_decl3 = create_artificial_label (UNKNOWN_LOCATION);
-  gimple label1, label2, label3;
+  glabel *label1, *label2, *label3;
   tree utype, tidx;
   tree bound;
 
-  gimple cond_stmt;
+  gcond *cond_stmt;
 
-  gimple last_assign;
+  gassign *last_assign;
   gimple_stmt_iterator gsi;
   basic_block bb0, bb1, bb2, bbf, bbd;
   edge e01, e02, e21, e1d, e1f, e2f;
@@ -1343,7 +1339,7 @@ gen_inbound_check (gimple swtch, struct switch_conv_info *info)
    conversion failed.  */
 
 static const char *
-process_switch (gimple swtch)
+process_switch (gswitch *swtch)
 {
   struct switch_conv_info info;
 
@@ -1477,7 +1473,7 @@ pass_convert_switch::execute (function *fun)
            putc ('\n', dump_file);
          }
 
-       failure_reason = process_switch (stmt);
+       failure_reason = process_switch (as_a <gswitch *> (stmt));
        if (! failure_reason)
          {
            if (dump_file)