]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/stmt.c
Update copyright years.
[thirdparty/gcc.git] / gcc / stmt.c
index 0aae085aa892e3d1ef06e4261f438063cc3ff46e..3d4e383c91c8a61a5adfc06b9a6656a84fe82c89 100644 (file)
@@ -1,5 +1,5 @@
 /* Expands front end tree to back end RTL for GCC
-   Copyright (C) 1987-2014 Free Software Foundation, Inc.
+   Copyright (C) 1987-2017 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -25,38 +25,30 @@ 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 "target.h"
 #include "rtl.h"
-#include "hard-reg-set.h"
 #include "tree.h"
-#include "varasm.h"
-#include "stor-layout.h"
-#include "tm_p.h"
-#include "flags.h"
-#include "except.h"
-#include "function.h"
-#include "insn-config.h"
-#include "expr.h"
-#include "libfuncs.h"
-#include "recog.h"
-#include "machmode.h"
-#include "diagnostic-core.h"
-#include "output.h"
-#include "langhooks.h"
+#include "gimple.h"
 #include "predict.h"
+#include "alloc-pool.h"
+#include "memmodel.h"
+#include "tm_p.h"
 #include "optabs.h"
-#include "target.h"
-#include "pointer-set.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 "regs.h"
-#include "alloc-pool.h"
+#include "emit-rtl.h"
 #include "pretty-print.h"
+#include "diagnostic-core.h"
+
+#include "fold-const.h"
+#include "varasm.h"
+#include "stor-layout.h"
+#include "dojump.h"
+#include "explow.h"
+#include "stmt.h"
+#include "expr.h"
+#include "langhooks.h"
+#include "cfganal.h"
 #include "params.h"
 #include "dumpfile.h"
 #include "builtins.h"
@@ -104,7 +96,6 @@ struct case_node
   int                   subtree_prob;
 };
 
-typedef struct case_node case_node;
 typedef struct case_node *case_node_ptr;
 
 extern basic_block label_to_block_fn (struct function *, tree);
@@ -115,48 +106,56 @@ static void balance_case_nodes (case_node_ptr *, case_node_ptr);
 static int node_has_low_bound (case_node_ptr, tree);
 static int node_has_high_bound (case_node_ptr, tree);
 static int node_is_bounded (case_node_ptr, tree);
-static void emit_case_nodes (rtx, case_node_ptr, rtx, int, tree);
+static void emit_case_nodes (rtx, case_node_ptr, rtx_code_label *, int, tree);
 \f
 /* Return the rtx-label that corresponds to a LABEL_DECL,
    creating it if necessary.  */
 
-rtx
+rtx_insn *
 label_rtx (tree label)
 {
   gcc_assert (TREE_CODE (label) == LABEL_DECL);
 
   if (!DECL_RTL_SET_P (label))
     {
-      rtx r = gen_label_rtx ();
+      rtx_code_label *r = gen_label_rtx ();
       SET_DECL_RTL (label, r);
       if (FORCED_LABEL (label) || DECL_NONLOCAL (label))
        LABEL_PRESERVE_P (r) = 1;
     }
 
-  return DECL_RTL (label);
+  return as_a <rtx_insn *> (DECL_RTL (label));
 }
 
 /* As above, but also put it on the forced-reference list of the
    function that contains it.  */
-rtx
+rtx_insn *
 force_label_rtx (tree label)
 {
-  rtx ref = label_rtx (label);
+  rtx_insn *ref = label_rtx (label);
   tree function = decl_function_context (label);
 
   gcc_assert (function);
 
-  forced_labels = gen_rtx_EXPR_LIST (VOIDmode, ref, forced_labels);
+  vec_safe_push (forced_labels, ref);
   return ref;
 }
 
+/* As label_rtx, but ensures (in check build), that returned value is
+   an existing label (i.e. rtx with code CODE_LABEL).  */
+rtx_code_label *
+jump_target_rtx (tree label)
+{
+  return as_a <rtx_code_label *> (label_rtx (label));
+}
+
 /* Add an unconditional jump to LABEL as the next sequential instruction.  */
 
 void
 emit_jump (rtx label)
 {
   do_pending_stack_adjust ();
-  emit_jump_insn (gen_jump (label));
+  emit_jump_insn (targetm.gen_jump (label));
   emit_barrier ();
 }
 \f
@@ -176,7 +175,7 @@ emit_jump (rtx label)
 void
 expand_label (tree label)
 {
-  rtx label_r = label_rtx (label);
+  rtx_code_label *label_r = jump_target_rtx (label);
 
   do_pending_stack_adjust ();
   emit_label (label_r);
@@ -187,12 +186,12 @@ expand_label (tree label)
     {
       expand_builtin_setjmp_receiver (NULL);
       nonlocal_goto_handler_labels
-       = gen_rtx_EXPR_LIST (VOIDmode, label_r,
+       = gen_rtx_INSN_LIST (VOIDmode, label_r,
                             nonlocal_goto_handler_labels);
     }
 
   if (FORCED_LABEL (label))
-    forced_labels = gen_rtx_EXPR_LIST (VOIDmode, label_r, forced_labels);
+    vec_safe_push<rtx_insn *> (forced_labels, label_r);
 
   if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
     maybe_set_first_label_num (label_r);
@@ -287,6 +286,7 @@ parse_output_constraint (const char **constraint_p, int operand_num,
        break;
 
       case '?':  case '!':  case '*':  case '&':  case '#':
+      case '$':  case '^':
       case 'E':  case 'F':  case 'G':  case 'H':
       case 's':  case 'i':  case 'n':
       case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
@@ -321,13 +321,7 @@ parse_output_constraint (const char **constraint_p, int operand_num,
        else if (insn_extra_memory_constraint (cn))
          *allows_mem = true;
        else
-         {
-           /* Otherwise we can't assume anything about the nature of
-              the constraint except that it isn't purely registers.
-              Treat it like "g" and hope for the best.  */
-           *allows_reg = true;
-           *allows_mem = true;
-         }
+         insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
        break;
       }
 
@@ -377,6 +371,7 @@ parse_input_constraint (const char **constraint_p, int input_num,
 
       case '<':  case '>':
       case '?':  case '!':  case '*':  case '#':
+      case '$':  case '^':
       case 'E':  case 'F':  case 'G':  case 'H':
       case 's':  case 'i':  case 'n':
       case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
@@ -440,16 +435,11 @@ parse_input_constraint (const char **constraint_p, int input_num,
        if (reg_class_for_constraint (cn) != NO_REGS
            || insn_extra_address_constraint (cn))
          *allows_reg = true;
-       else if (insn_extra_memory_constraint (cn))
+       else if (insn_extra_memory_constraint (cn)
+                || insn_extra_special_memory_constraint (cn))
          *allows_mem = true;
        else
-         {
-           /* Otherwise we can't assume anything about the nature of
-              the constraint except that it isn't purely registers.
-              Treat it like "g" and hope for the best.  */
-           *allows_reg = true;
-           *allows_mem = true;
-         }
+         insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
        break;
       }
 
@@ -469,7 +459,7 @@ decl_overlaps_hard_reg_set_p (tree *declp, int *walk_subtrees ATTRIBUTE_UNUSED,
   tree decl = *declp;
   const HARD_REG_SET *const regs = (const HARD_REG_SET *) data;
 
-  if (TREE_CODE (decl) == VAR_DECL)
+  if (VAR_P (decl))
     {
       if (DECL_HARD_REGISTER (decl)
          && REG_P (DECL_RTL (decl))
@@ -552,9 +542,10 @@ check_unique_operand_names (tree outputs, tree inputs, tree labels)
   return false;
 }
 
-/* A subroutine of expand_asm_operands.  Resolve the names of the operands
-   in *POUTPUTS and *PINPUTS to numbers, and replace the name expansions in
-   STRING and in the constraints to those numbers.  */
+/* Resolve the names of the operands in *POUTPUTS and *PINPUTS to numbers,
+   and replace the name expansions in STRING and in the constraints to
+   those numbers.  This is generally done in the front end while creating
+   the ASM_EXPR generic tree that eventually becomes the GIMPLE_ASM.  */
 
 tree
 resolve_asm_operand_names (tree string, tree outputs, tree inputs, tree labels)
@@ -695,7 +686,7 @@ resolve_operand_name_1 (char *p, tree outputs, tree inputs, tree labels)
 void
 expand_naked_return (void)
 {
-  rtx end_label;
+  rtx_code_label *end_label;
 
   clear_pending_stack_adjust ();
   do_pending_stack_adjust ();
@@ -710,12 +701,12 @@ expand_naked_return (void)
 /* Generate code to jump to LABEL if OP0 and OP1 are equal in mode MODE. PROB
    is the probability of jumping to LABEL.  */
 static void
-do_jump_if_equal (enum machine_mode mode, rtx op0, rtx op1, rtx label,
+do_jump_if_equal (machine_mode mode, rtx op0, rtx op1, rtx_code_label *label,
                  int unsignedp, int prob)
 {
   gcc_assert (prob <= REG_BR_PROB_BASE);
   do_compare_rtx_and_jump (op0, op1, EQ, unsignedp, mode,
-                          NULL_RTX, NULL_RTX, label, prob);
+                          NULL_RTX, NULL, label, prob);
 }
 \f
 /* Do the insertion of a case label into case_list.  The labels are
@@ -729,7 +720,8 @@ do_jump_if_equal (enum machine_mode mode, rtx op0, rtx op1, rtx label,
 
 static struct case_node *
 add_case_node (struct case_node *head, tree low, tree high,
-               tree label, int prob, alloc_pool case_node_pool)
+              tree label, int prob,
+              object_allocator<case_node> &case_node_pool)
 {
   struct case_node *r;
 
@@ -737,7 +729,7 @@ add_case_node (struct case_node *head, tree low, tree high,
   gcc_checking_assert (high && (TREE_TYPE (low) == TREE_TYPE (high)));
 
   /* Add this label to the chain.  */
-  r = (struct case_node *) pool_alloc (case_node_pool);
+  r = case_node_pool.allocate ();
   r->low = low;
   r->high = high;
   r->code_label = label;
@@ -773,14 +765,6 @@ dump_case_nodes (FILE *f, struct case_node *root,
   dump_case_nodes (f, root->right, indent_step, indent_level);
 }
 \f
-#ifndef HAVE_casesi
-#define HAVE_casesi 0
-#endif
-
-#ifndef HAVE_tablejump
-#define HAVE_tablejump 0
-#endif
-
 /* Return the smallest number of different values for which it is best to use a
    jump-table instead of a tree of conditional branches.  */
 
@@ -809,7 +793,7 @@ expand_switch_as_decision_tree_p (tree range,
 
   /* If neither casesi or tablejump is available, or flag_jump_tables
      over-ruled us, we really have no choice.  */
-  if (!HAVE_casesi && !HAVE_tablejump)
+  if (!targetm.have_casesi () && !targetm.have_tablejump ())
     return true;
   if (!flag_jump_tables)
     return true;
@@ -872,8 +856,8 @@ expand_switch_as_decision_tree_p (tree range,
 
 static void
 emit_case_decision_tree (tree index_expr, tree index_type,
-                        struct case_node *case_list, rtx default_label,
-                         int default_prob)
+                        case_node_ptr case_list, rtx_code_label *default_label,
+                        int default_prob)
 {
   rtx index = expand_normal (index_expr);
 
@@ -881,7 +865,7 @@ emit_case_decision_tree (tree index_expr, tree index_type,
       && ! have_insn_for (COMPARE, GET_MODE (index)))
     {
       int unsignedp = TYPE_UNSIGNED (index_type);
-      enum machine_mode wider_mode;
+      machine_mode wider_mode;
       for (wider_mode = GET_MODE (index); wider_mode != VOIDmode;
           wider_mode = GET_MODE_WIDER_MODE (wider_mode))
        if (have_insn_for (COMPARE, wider_mode))
@@ -897,7 +881,7 @@ emit_case_decision_tree (tree index_expr, tree index_type,
     {
       index = copy_to_reg (index);
       if (TREE_CODE (index_expr) == SSA_NAME)
-       set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (index_expr), index);
+       set_reg_attrs_for_decl_rtl (index_expr, index);
     }
 
   balance_case_nodes (&case_list, NULL);
@@ -970,8 +954,8 @@ emit_case_dispatch_table (tree index_expr, tree index_type,
   int i, ncases;
   struct case_node *n;
   rtx *labelvec;
-  rtx fallback_label = label_rtx (case_list->code_label);
-  rtx table_label = gen_label_rtx ();
+  rtx_insn *fallback_label = label_rtx (case_list->code_label);
+  rtx_code_label *table_label = gen_label_rtx ();
   bool has_gaps = false;
   edge default_edge = stmt_bb ? EDGE_SUCC (stmt_bb, 0) : NULL;
   int default_prob = default_edge ? default_edge->probability : 0;
@@ -1106,7 +1090,7 @@ reset_out_edges_aux (basic_block bb)
    STMT. Record this information in the aux field of the edge.  */
 
 static inline void
-compute_cases_per_edge (gimple stmt)
+compute_cases_per_edge (gswitch *stmt)
 {
   basic_block bb = gimple_bb (stmt);
   reset_out_edges_aux (bb);
@@ -1128,10 +1112,10 @@ compute_cases_per_edge (gimple stmt)
    Generate the code to test it and jump to the right place.  */
 
 void
-expand_case (gimple stmt)
+expand_case (gswitch *stmt)
 {
   tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE;
-  rtx default_label = NULL_RTX;
+  rtx_code_label *default_label = NULL;
   unsigned int count, uniq;
   int i;
   int ncases = gimple_switch_num_labels (stmt);
@@ -1145,7 +1129,7 @@ expand_case (gimple stmt)
   struct case_node *case_list = 0;
 
   /* A pool for case nodes.  */
-  alloc_pool case_node_pool;
+  object_allocator<case_node> case_node_pool ("struct case_node pool");
 
   /* An ERROR_MARK occurs for various reasons including invalid data type.
      ??? Can this still happen, with GIMPLE and all?  */
@@ -1156,14 +1140,12 @@ expand_case (gimple stmt)
      expressions being INTEGER_CST.  */
   gcc_assert (TREE_CODE (index_expr) != INTEGER_CST);
   
-  case_node_pool = create_alloc_pool ("struct case_node pool",
-                                     sizeof (struct case_node),
-                                     100);
 
   do_pending_stack_adjust ();
 
   /* Find the default case target label.  */
-  default_label = label_rtx (CASE_LABEL (gimple_switch_default_label (stmt)));
+  default_label = jump_target_rtx
+      (CASE_LABEL (gimple_switch_default_label (stmt)));
   edge default_edge = EDGE_SUCC (bb, 0);
   int default_prob = default_edge->probability;
 
@@ -1183,7 +1165,7 @@ expand_case (gimple stmt)
      how to expand this switch().  */
   uniq = 0;
   count = 0;
-  struct pointer_set_t *seen_labels = pointer_set_create ();
+  hash_set<tree> seen_labels;
   compute_cases_per_edge (stmt);
 
   for (i = ncases - 1; i >= 1; --i)
@@ -1203,7 +1185,7 @@ expand_case (gimple stmt)
 
       /* If we have not seen this label yet, then increase the
         number of unique case node targets seen.  */
-      if (!pointer_set_insert (seen_labels, lab))
+      if (!seen_labels.add (lab))
        uniq++;
 
       /* The bounds on the case range, LOW and HIGH, have to be converted
@@ -1231,7 +1213,6 @@ expand_case (gimple stmt)
           case_edge->probability / (intptr_t)(case_edge->aux),
           case_node_pool);
     }
-  pointer_set_destroy (seen_labels);
   reset_out_edges_aux (bb);
 
   /* cleanup_tree_cfg removes all SWITCH_EXPR with a single
@@ -1240,7 +1221,7 @@ expand_case (gimple stmt)
      type, so we should never get a zero here.  */
   gcc_assert (count > 0);
 
-  rtx before_case = get_last_insn ();
+  rtx_insn *before_case = get_last_insn ();
 
   /* Decide how to expand this switch.
      The two options at this point are a dispatch table (casesi or
@@ -1258,7 +1239,6 @@ expand_case (gimple stmt)
   reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
 
   free_temp_slots ();
-  free_alloc_pool (case_node_pool);
 }
 
 /* Expand the dispatch to a short decrement chain if there are few cases
@@ -1279,12 +1259,12 @@ expand_sjlj_dispatch_table (rtx dispatch_index,
                            vec<tree> dispatch_table)
 {
   tree index_type = integer_type_node;
-  enum machine_mode index_mode = TYPE_MODE (index_type);
+  machine_mode index_mode = TYPE_MODE (index_type);
 
   int ncases = dispatch_table.length ();
 
   do_pending_stack_adjust ();
-  rtx before_case = get_last_insn ();
+  rtx_insn *before_case = get_last_insn ();
 
   /* Expand as a decrement-chain if there are 5 or fewer dispatch
      labels.  This covers more than 98% of the cases in libjava,
@@ -1292,7 +1272,7 @@ expand_sjlj_dispatch_table (rtx dispatch_index,
      of expanding as a decision tree or dispatch table vs. the "new
      way" with decrement chain or dispatch table.  */
   if (dispatch_table.length () <= 5
-      || (!HAVE_casesi && !HAVE_tablejump)
+      || (!targetm.have_casesi () && !targetm.have_tablejump ())
       || !flag_jump_tables)
     {
       /* Expand the dispatch as a decrement chain:
@@ -1314,7 +1294,7 @@ expand_sjlj_dispatch_table (rtx dispatch_index,
       for (int i = 0; i < ncases; i++)
         {
          tree elt = dispatch_table[i];
-         rtx lab = label_rtx (CASE_LABEL (elt));
+         rtx_code_label *lab = jump_target_rtx (CASE_LABEL (elt));
          do_jump_if_equal (index_mode, index, zero, lab, 0, -1);
          force_expand_binop (index_mode, sub_optab,
                              index, CONST1_RTX (index_mode),
@@ -1325,14 +1305,12 @@ expand_sjlj_dispatch_table (rtx dispatch_index,
     {
       /* Similar to expand_case, but much simpler.  */
       struct case_node *case_list = 0;
-      alloc_pool case_node_pool = create_alloc_pool ("struct sjlj_case pool",
-                                                    sizeof (struct case_node),
-                                                    ncases);
+      object_allocator<case_node> case_node_pool ("struct sjlj_case pool");
       tree index_expr = make_tree (index_type, dispatch_index);
       tree minval = build_int_cst (index_type, 0);
       tree maxval = CASE_LOW (dispatch_table.last ());
       tree range = maxval;
-      rtx default_label = gen_label_rtx ();
+      rtx_code_label *default_label = gen_label_rtx ();
 
       for (int i = ncases - 1; i >= 0; --i)
        {
@@ -1347,7 +1325,6 @@ expand_sjlj_dispatch_table (rtx dispatch_index,
                                minval, maxval, range,
                                 BLOCK_FOR_INSN (before_case));
       emit_label (default_label);
-      free_alloc_pool (case_node_pool);
     }
 
   /* Dispatching something not handled?  Trap!  */
@@ -1583,15 +1560,15 @@ node_is_bounded (case_node_ptr node, tree index_type)
    tests for the value 50, then this node need not test anything.  */
 
 static void
-emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
+emit_case_nodes (rtx index, case_node_ptr node, rtx_code_label *default_label,
                 int default_prob, tree index_type)
 {
   /* If INDEX has an unsigned type, we must make unsigned branches.  */
   int unsignedp = TYPE_UNSIGNED (index_type);
   int probability;
   int prob = node->prob, subtree_prob = node->subtree_prob;
-  enum machine_mode mode = GET_MODE (index);
-  enum machine_mode imode = TYPE_MODE (index_type);
+  machine_mode mode = GET_MODE (index);
+  machine_mode imode = TYPE_MODE (index_type);
 
   /* Handle indices detected as constant during RTL expansion.  */
   if (mode == VOIDmode)
@@ -1611,7 +1588,8 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
                        convert_modes (mode, imode,
                                       expand_normal (node->low),
                                       unsignedp),
-                       label_rtx (node->code_label), unsignedp, probability);
+                       jump_target_rtx (node->code_label),
+                       unsignedp, probability);
       /* Since this case is taken at this point, reduce its weight from
          subtree_weight.  */
       subtree_prob -= prob;
@@ -1653,7 +1631,8 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
                                       LT, NULL_RTX, mode, unsignedp,
                                       label_rtx (node->left->code_label),
                                        probability);
-             emit_case_nodes (index, node->right, default_label, default_prob, index_type);
+             emit_case_nodes (index, node->right, default_label, default_prob,
+                              index_type);
            }
 
          /* If both children are single-valued cases with no
@@ -1678,7 +1657,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
                                convert_modes (mode, imode,
                                               expand_normal (node->right->low),
                                               unsignedp),
-                               label_rtx (node->right->code_label),
+                               jump_target_rtx (node->right->code_label),
                                unsignedp, probability);
 
              /* See if the value matches what the left hand side
@@ -1690,7 +1669,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
                                convert_modes (mode, imode,
                                               expand_normal (node->left->low),
                                               unsignedp),
-                               label_rtx (node->left->code_label),
+                               jump_target_rtx (node->left->code_label),
                                unsignedp, probability);
            }
 
@@ -1701,7 +1680,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
 
              tree test_label
                = build_decl (curr_insn_location (),
-                             LABEL_DECL, NULL_TREE, NULL_TREE);
+                             LABEL_DECL, NULL_TREE, void_type_node);
 
               /* The default label could be reached either through the right
                  subtree or the left subtree. Divide the probability
@@ -1777,7 +1756,8 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
                                (mode, imode,
                                 expand_normal (node->right->low),
                                 unsignedp),
-                               label_rtx (node->right->code_label), unsignedp, probability);
+                               jump_target_rtx (node->right->code_label),
+                               unsignedp, probability);
             }
          }
 
@@ -1819,7 +1799,8 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
                                (mode, imode,
                                 expand_normal (node->left->low),
                                 unsignedp),
-                               label_rtx (node->left->code_label), unsignedp, probability);
+                               jump_target_rtx (node->left->code_label),
+                               unsignedp, probability);
             }
        }
     }
@@ -1860,7 +1841,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
                 Branch to a label where we will handle it later.  */
 
              test_label = build_decl (curr_insn_location (),
-                                      LABEL_DECL, NULL_TREE, NULL_TREE);
+                                      LABEL_DECL, NULL_TREE, void_type_node);
               probability = conditional_probability (
                   node->right->subtree_prob + default_prob/2,
                   subtree_prob + default_prob);
@@ -2042,7 +2023,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
                                       mode, 1, default_label, probability);
            }
 
-         emit_jump (label_rtx (node->code_label));
+         emit_jump (jump_target_rtx (node->code_label));
        }
     }
 }