]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/stmt.c
Update copyright years.
[thirdparty/gcc.git] / gcc / stmt.c
index 6c62a129601ccb65d5f7cb289c197d5e653003d8..3d4e383c91c8a61a5adfc06b9a6656a84fe82c89 100644 (file)
@@ -1,5 +1,5 @@
 /* Expands front end tree to back end RTL for GCC
-   Copyright (C) 1987-2015 Free Software Foundation, Inc.
+   Copyright (C) 1987-2017 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -25,58 +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 "hash-set.h"
-#include "machmode.h"
-#include "vec.h"
-#include "double-int.h"
-#include "input.h"
-#include "alias.h"
-#include "symtab.h"
-#include "wide-int.h"
-#include "inchash.h"
 #include "tree.h"
+#include "gimple.h"
+#include "predict.h"
+#include "alloc-pool.h"
+#include "memmodel.h"
+#include "tm_p.h"
+#include "optabs.h"
+#include "regs.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 "tm_p.h"
-#include "flags.h"
-#include "except.h"
-#include "function.h"
-#include "insn-config.h"
-#include "hashtab.h"
-#include "statistics.h"
-#include "real.h"
-#include "fixed-value.h"
-#include "expmed.h"
 #include "dojump.h"
 #include "explow.h"
-#include "calls.h"
-#include "emit-rtl.h"
 #include "stmt.h"
 #include "expr.h"
-#include "libfuncs.h"
-#include "recog.h"
-#include "diagnostic-core.h"
-#include "output.h"
 #include "langhooks.h"
-#include "predict.h"
-#include "insn-codes.h"
-#include "optabs.h"
-#include "target.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 "regs.h"
-#include "alloc-pool.h"
-#include "pretty-print.h"
 #include "params.h"
 #include "dumpfile.h"
 #include "builtins.h"
@@ -124,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);
@@ -135,12 +106,12 @@ 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);
@@ -153,30 +124,38 @@ label_rtx (tree 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_insn *ref = as_a <rtx_insn *> (label_rtx (label));
+  rtx_insn *ref = label_rtx (label);
   tree function = decl_function_context (label);
 
   gcc_assert (function);
 
-  forced_labels = gen_rtx_INSN_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
@@ -196,7 +175,7 @@ emit_jump (rtx label)
 void
 expand_label (tree label)
 {
-  rtx_insn *label_r = as_a <rtx_insn *> (label_rtx (label));
+  rtx_code_label *label_r = jump_target_rtx (label);
 
   do_pending_stack_adjust ();
   emit_label (label_r);
@@ -212,7 +191,7 @@ expand_label (tree label)
     }
 
   if (FORCED_LABEL (label))
-    forced_labels = gen_rtx_INSN_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);
@@ -456,7 +435,8 @@ 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
          insn_extra_constraint_allows_reg_mem (cn, allows_reg, allows_mem);
@@ -479,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))
@@ -562,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)
@@ -705,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 ();
@@ -720,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 (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
@@ -739,7 +720,8 @@ do_jump_if_equal (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;
 
@@ -747,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;
@@ -783,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.  */
 
@@ -819,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;
@@ -882,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);
 
@@ -907,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);
@@ -980,7 +954,7 @@ 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_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;
@@ -1141,7 +1115,7 @@ void
 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);
@@ -1155,7 +1129,7 @@ expand_case (gswitch *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?  */
@@ -1166,14 +1140,12 @@ expand_case (gswitch *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;
 
@@ -1267,7 +1239,6 @@ expand_case (gswitch *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
@@ -1301,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:
@@ -1323,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),
@@ -1334,9 +1305,7 @@ 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 ());
@@ -1356,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!  */
@@ -1592,7 +1560,7 @@ 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.  */
@@ -1620,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;
@@ -1662,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
@@ -1687,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
@@ -1699,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);
            }
 
@@ -1786,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);
             }
          }
 
@@ -1828,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);
             }
        }
     }
@@ -2051,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));
        }
     }
 }