]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
targhooks.c (default_case_values_threshold): Fix code style nit.
authorSteven Bosscher <steven@gcc.gnu.org>
Wed, 18 Apr 2012 18:27:51 +0000 (18:27 +0000)
committerSteven Bosscher <steven@gcc.gnu.org>
Wed, 18 Apr 2012 18:27:51 +0000 (18:27 +0000)
gcc/
* targhooks.c (default_case_values_threshold): Fix code style nit.

* stmt.c (add_case_node, expand_case): Move logic to remove/reduce
case range and type folding from here...
* gimplify.c (gimplify_switch_expr): ... to here.  Expect NULL_TREE
type, as documented in tree.def

fortran/
* trans-decl.c (gfc_trans_entry_master_switch): Build SWITCH_EXPR
with NULL_TREE type instead of void_type_node.
* trans-io.c (io_result): Likewise.
* trans-stmt.c (gfc_trans_integer_select,
gfc_trans_character_select): Likewise.

go/
* go-gcc.cc (Gcc_backend::switch_statement): Build SWITCH_EXPR
with NULL_TREE type instead of void_type_node.

From-SVN: r186579

gcc/ChangeLog
gcc/fortran/ChangeLog
gcc/fortran/trans-decl.c
gcc/fortran/trans-io.c
gcc/fortran/trans-stmt.c
gcc/gimplify.c
gcc/go/ChangeLog
gcc/go/go-gcc.cc
gcc/stmt.c
gcc/targhooks.c

index ebee8ab22cef406abfcc4546eb48c8e7e1fd0232..f2d9dc0cf3cf721bb404fde7591f83b3e70ceb54 100644 (file)
@@ -1,3 +1,12 @@
+2012-04-18  Steven Bosscher  <steven@gcc.gnu.org>
+
+       * targhooks.c (default_case_values_threshold): Fix code style nit.
+
+       * stmt.c (add_case_node, expand_case): Move logic to remove/reduce
+       case range and type folding from here...
+       * gimplify.c (gimplify_switch_expr): ... to here.  Expect NULL_TREE
+       type, as documented in tree.def
+
 2012-04-18  Jan Hubicka  <jh@suse.cz>
 
        * cgraph.h (verify_symtab, verify_symtab_node, verify_symtab_base):
index 9793c8b57b0b356fbcff13797316f68a69d17da4..cfe1192b6ef198926007745f7aafe11f50467647 100644 (file)
@@ -1,3 +1,11 @@
+2012-04-18  Steven Bosscher  <steven@gcc.gnu.org>
+
+       * trans-decl.c (gfc_trans_entry_master_switch): Build SWITCH_EXPR
+       with NULL_TREE type instead of void_type_node.
+       * trans-io.c (io_result): Likewise.
+       * trans-stmt.c (gfc_trans_integer_select,
+       gfc_trans_character_select): Likewise.
+
 2012-04-16  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/52864
index 129010e4cf857afde26cd95c794f138262f4f62b..d6c090e86062cad913d640f0ae123e0ca9eba1ae 100644 (file)
@@ -4749,7 +4749,8 @@ gfc_trans_entry_master_switch (gfc_entry_list * el)
   tmp = gfc_finish_block (&block);
   /* The first argument selects the entry point.  */
   val = DECL_ARGUMENTS (current_function_decl);
-  tmp = build3_v (SWITCH_EXPR, val, tmp, NULL_TREE);
+  tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
+                        val, tmp, NULL_TREE);
   return tmp;
 }
 
index 12dfcf82333ab69ab3b6ae3cf861aeb8b5bc8b17..8218f85a98daeb242face9c16affe9b3066094ae 100644 (file)
@@ -882,7 +882,8 @@ io_result (stmtblock_t * block, tree var, gfc_st_label * err_label,
                        rc, build_int_cst (TREE_TYPE (rc),
                                           IOPARM_common_libreturn_mask));
 
-  tmp = build3_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
+  tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
+                        rc, tmp, NULL_TREE);
 
   gfc_add_expr_to_block (block, tmp);
 }
index bb3a89084e03ae6f6ae045540d4fad50326b2946..12a1390e2aaa18318e5205eab3a59f763919db93 100644 (file)
@@ -1918,7 +1918,8 @@ gfc_trans_integer_select (gfc_code * code)
     }
 
   tmp = gfc_finish_block (&body);
-  tmp = build3_v (SWITCH_EXPR, se.expr, tmp, NULL_TREE);
+  tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
+                        se.expr, tmp, NULL_TREE);
   gfc_add_expr_to_block (&block, tmp);
 
   tmp = build1_v (LABEL_EXPR, end_label);
@@ -2203,7 +2204,8 @@ gfc_trans_character_select (gfc_code *code)
          gfc_add_block_to_block (&block, &expr1se.post);
 
          tmp = gfc_finish_block (&body);
-         tmp = build3_v (SWITCH_EXPR, case_num, tmp, NULL_TREE);
+         tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
+                                case_num, tmp, NULL_TREE);
          gfc_add_expr_to_block (&block, tmp);
 
          tmp = build1_v (LABEL_EXPR, end_label);
@@ -2349,7 +2351,8 @@ gfc_trans_character_select (gfc_code *code)
   gfc_add_block_to_block (&block, &expr1se.post);
 
   tmp = gfc_finish_block (&body);
-  tmp = build3_v (SWITCH_EXPR, case_num, tmp, NULL_TREE);
+  tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
+                        case_num, tmp, NULL_TREE);
   gfc_add_expr_to_block (&block, tmp);
 
   tmp = build1_v (LABEL_EXPR, end_label);
index 8e353fe3737247f9b4d92dfa2ede714ab1ed2b49..9e7b8461cc8f3713675ab30ec5da66f86e64653a 100644 (file)
@@ -1575,6 +1575,10 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
   tree switch_expr = *expr_p;
   gimple_seq switch_body_seq = NULL;
   enum gimplify_status ret;
+  tree index_type = TREE_TYPE (switch_expr);
+  if (index_type == NULL_TREE)
+    index_type = TREE_TYPE (SWITCH_COND (switch_expr));
+  gcc_assert (INTEGRAL_TYPE_P (index_type));
 
   ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
                        fb_rvalue);
@@ -1585,6 +1589,7 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
     {
       VEC (tree,heap) *labels;
       VEC (tree,heap) *saved_labels;
+      tree min_value, max_value;
       tree default_case = NULL_TREE;
       size_t i, len;
       gimple gimple_switch;
@@ -1593,7 +1598,7 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
         be bothered to null out the body too.  */
       gcc_assert (!SWITCH_LABELS (switch_expr));
 
-      /* save old labels, get new ones from body, then restore the old
+      /* Save old labels, get new ones from body, then restore the old
          labels.  Save all the things from the switch body to append after.  */
       saved_labels = gimplify_ctxp->case_labels;
       gimplify_ctxp->case_labels = VEC_alloc (tree, heap, 8);
@@ -1603,18 +1608,82 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
       gimplify_ctxp->case_labels = saved_labels;
 
       i = 0;
+      min_value = TYPE_MIN_VALUE (index_type);
+      max_value = TYPE_MAX_VALUE (index_type);
       while (i < VEC_length (tree, labels))
        {
          tree elt = VEC_index (tree, labels, i);
          tree low = CASE_LOW (elt);
+         tree high = CASE_HIGH (elt);
          bool remove_element = FALSE;
 
+
          if (low)
            {
-             /* Discard empty ranges.  */
-             tree high = CASE_HIGH (elt);
-             if (high && tree_int_cst_lt (high, low))
-               remove_element = TRUE;
+             gcc_checking_assert (TREE_CODE (low) == INTEGER_CST);
+             gcc_checking_assert (!high || TREE_CODE (high) == INTEGER_CST);
+
+             /* This is a non-default case label, i.e. it has a value.
+
+                See if the case label is reachable within the range of
+                the index type.  Remove out-of-range case values.  Turn
+                case ranges into a canonical form (high > low strictly)
+                and convert the case label values to the index type.
+
+                NB: The type of gimple_switch_index() may be the promoted
+                type, but the case labels retain the original type.  */
+
+             if (high)
+               {
+                 /* This is a case range.  Discard empty ranges.
+                    If the bounds or the range are equal, turn this
+                    into a simple (one-value) case.  */
+                 int cmp = tree_int_cst_compare (high, low);
+                 if (cmp < 0)
+                   remove_element = TRUE;
+                 else if (cmp == 0)
+                   high = NULL_TREE;
+               }
+
+             if (! high)
+               {
+                 /* If the simple case value is unreachable, ignore it.  */
+                 if ((TREE_CODE (min_value) == INTEGER_CST
+                      && tree_int_cst_compare (low, min_value) < 0)
+                     || (TREE_CODE (max_value) == INTEGER_CST
+                         && tree_int_cst_compare (low, max_value) > 0))
+                   remove_element = TRUE;
+                 else
+                   low = fold_convert (index_type, low);
+               }
+             else
+               {
+                 /* If the entire case range is unreachable, ignore it.  */
+                 if ((TREE_CODE (min_value) == INTEGER_CST
+                      && tree_int_cst_compare (high, min_value) < 0)
+                     || (TREE_CODE (max_value) == INTEGER_CST
+                         && tree_int_cst_compare (low, max_value) > 0))
+                   remove_element = TRUE;
+                 else
+                   {
+                     /* If the lower bound is less than the index type's
+                        minimum value, truncate the range bounds.  */
+                     if (TREE_CODE (min_value) == INTEGER_CST
+                         && tree_int_cst_compare (low, min_value) < 0)
+                       low = min_value;
+                     low = fold_convert (index_type, low);
+
+                     /* If the upper bound is greater than the index type's
+                        maximum value, truncate the range bounds.  */
+                     if (TREE_CODE (max_value) == INTEGER_CST
+                         && tree_int_cst_compare (high, max_value) > 0)
+                       high = max_value;
+                     high = fold_convert (index_type, high);
+                   }
+               }
+
+             CASE_LOW (elt) = low;
+             CASE_HIGH (elt) = high;
            }
          else
            {
@@ -1636,25 +1705,20 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
 
       if (!default_case)
        {
-         tree type = TREE_TYPE (switch_expr);
-
          /* If the switch has no default label, add one, so that we jump
             around the switch body.  If the labels already cover the whole
-            range of type, add the default label pointing to one of the
-            existing labels.  */
-         if (type == void_type_node)
-           type = TREE_TYPE (SWITCH_COND (switch_expr));
+            range of the switch index_type, add the default label pointing
+            to one of the existing labels.  */
          if (len
-             && INTEGRAL_TYPE_P (type)
-             && TYPE_MIN_VALUE (type)
-             && TYPE_MAX_VALUE (type)
+             && TYPE_MIN_VALUE (index_type)
+             && TYPE_MAX_VALUE (index_type)
              && tree_int_cst_equal (CASE_LOW (VEC_index (tree, labels, 0)),
-                                    TYPE_MIN_VALUE (type)))
+                                    TYPE_MIN_VALUE (index_type)))
            {
              tree low, high = CASE_HIGH (VEC_index (tree, labels, len - 1));
              if (!high)
                high = CASE_LOW (VEC_index (tree, labels, len - 1));
-             if (tree_int_cst_equal (high, TYPE_MAX_VALUE (type)))
+             if (tree_int_cst_equal (high, TYPE_MAX_VALUE (index_type)))
                {
                  for (i = 1; i < len; i++)
                    {
index f779e9b89cf3934f1bd9622f9f67603837824aa3..2991cb957b610e63cdf601a3f35e542737ef4004 100644 (file)
@@ -1,3 +1,8 @@
+2012-04-18  Steven Bosscher  <steven@gcc.gnu.org>
+
+       * go-gcc.cc (Gcc_backend::switch_statement): Build SWITCH_EXPR
+       with NULL_TREE type instead of void_type_node.
+
 2012-03-09  Ian Lance Taylor  <iant@google.com>
 
        * go-gcc.cc (Gcc_backend::assignment_statement): Convert the rhs
index 96c171835c420e4efc55412fec087f9ab9dfddc7..08950b8e1d997ab022fbdb320e420111f41d3679 100644 (file)
@@ -1087,7 +1087,7 @@ Gcc_backend::switch_statement(
   if (tv == error_mark_node)
     return this->error_statement();
   tree t = build3_loc(switch_location.gcc_location(), SWITCH_EXPR,
-                      void_type_node, tv, stmt_list, NULL_TREE);
+                      NULL_TREE, tv, stmt_list, NULL_TREE);
   return this->make_statement(t);
 }
 
index a519f0bbe14ea737f78711d17c4cd87e6d7e4e52..8f7b1506eef168a701185360ea92a3d7c36d717d 100644 (file)
@@ -1822,66 +1822,25 @@ expand_stack_restore (tree var)
    fed to us in descending order from the sorted vector of case labels used
    in the tree part of the middle end.  So the list we construct is
    sorted in ascending order.  The bounds on the case range, LOW and HIGH,
-   are converted to case's index type TYPE.  */
+   are converted to case's index type TYPE.  Note that the original type
+   of the case index in the source code is usually "lost" during
+   gimplification due to type promotion, but the case labels retain the
+   original type.  */
 
 static struct case_node *
 add_case_node (struct case_node *head, tree type, tree low, tree high,
                tree label, alloc_pool case_node_pool)
 {
-  tree min_value, max_value;
   struct case_node *r;
 
-  gcc_assert (TREE_CODE (low) == INTEGER_CST);
-  gcc_assert (!high || TREE_CODE (high) == INTEGER_CST);
-
-  min_value = TYPE_MIN_VALUE (type);
-  max_value = TYPE_MAX_VALUE (type);
-
-  /* If there's no HIGH value, then this is not a case range; it's
-     just a simple case label.  But that's just a degenerate case
-     range.
-     If the bounds are equal, turn this into the one-value case.  */
-  if (!high || tree_int_cst_equal (low, high))
-    {
-      /* If the simple case value is unreachable, ignore it.  */
-      if ((TREE_CODE (min_value) == INTEGER_CST
-            && tree_int_cst_compare (low, min_value) < 0)
-         || (TREE_CODE (max_value) == INTEGER_CST
-             && tree_int_cst_compare (low, max_value) > 0))
-       return head;
-      low = fold_convert (type, low);
-      high = low;
-    }
-  else
-    {
-      /* If the entire case range is unreachable, ignore it.  */
-      if ((TREE_CODE (min_value) == INTEGER_CST
-            && tree_int_cst_compare (high, min_value) < 0)
-         || (TREE_CODE (max_value) == INTEGER_CST
-             && tree_int_cst_compare (low, max_value) > 0))
-       return head;
-
-      /* If the lower bound is less than the index type's minimum
-        value, truncate the range bounds.  */
-      if (TREE_CODE (min_value) == INTEGER_CST
-            && tree_int_cst_compare (low, min_value) < 0)
-       low = min_value;
-      low = fold_convert (type, low);
-
-      /* If the upper bound is greater than the index type's maximum
-        value, truncate the range bounds.  */
-      if (TREE_CODE (max_value) == INTEGER_CST
-         && tree_int_cst_compare (high, max_value) > 0)
-       high = max_value;
-      high = fold_convert (type, high);
-    }
-
+  gcc_checking_assert (low);
+  gcc_checking_assert (! high || (TREE_TYPE (low) == TREE_TYPE (high)));
 
   /* Add this label to the chain.  Make sure to drop overflow flags.  */
   r = (struct case_node *) pool_alloc (case_node_pool);
-  r->low = build_int_cst_wide (TREE_TYPE (low), TREE_INT_CST_LOW (low),
+  r->low = build_int_cst_wide (type, TREE_INT_CST_LOW (low),
                               TREE_INT_CST_HIGH (low));
-  r->high = build_int_cst_wide (TREE_TYPE (high), TREE_INT_CST_LOW (high),
+  r->high = build_int_cst_wide (type, TREE_INT_CST_LOW (high),
                                TREE_INT_CST_HIGH (high));
   r->code_label = label;
   r->parent = r->left = NULL;
@@ -2151,9 +2110,12 @@ expand_case (gimple stmt)
          gcc_assert (low);
          high = CASE_HIGH (elt);
 
-         /* Discard empty ranges.  */
-         if (high && tree_int_cst_lt (high, low))
-           continue;
+         /* The canonical from of a case label in GIMPLE is that a simple case
+            has an empty CASE_HIGH.  For the casesi and tablejump expanders,
+            the back ends want simple cases to have high == low.  */
+         gcc_assert (! high || tree_int_cst_lt (low, high));
+         if (! high)
+           high = low;
 
          case_list = add_case_node (case_list, index_type, low, high,
                                      CASE_LABEL (elt), case_node_pool);
@@ -2199,16 +2161,10 @@ expand_case (gimple stmt)
       BITMAP_FREE (label_bitmap);
 
       /* cleanup_tree_cfg removes all SWITCH_EXPR with a single
-        destination, such as one with a default case only.  However,
-        it doesn't remove cases that are out of range for the switch
-        type, so we may still get a zero here.  */
-      if (count == 0)
-       {
-         if (default_label)
-           emit_jump (default_label);
-          free_alloc_pool (case_node_pool);
-         return;
-       }
+        destination, such as one with a default case only.
+        It also removes cases that are out of range for the switch
+        type, so we should never get a zero here.  */
+      gcc_assert (count > 0);
 
       /* Compute span of values.  */
       range = fold_build2 (MINUS_EXPR, index_type, maxval, minval);
index 8e3d74ea356645c3c94f9a0b293cd67ea993f0ac..da0b029cdbe64022a69f3dde60e17500376f5b94 100644 (file)
@@ -1200,7 +1200,8 @@ default_target_can_inline_p (tree caller, tree callee)
    this means extra overhead for dispatch tables, which raises the
    threshold for using them.  */
 
-unsigned int default_case_values_threshold (void)
+unsigned int
+default_case_values_threshold (void)
 {
   return (HAVE_casesi ? 4 : 5);
 }