OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / stmt.c
index f1be5e0..286e566 100644 (file)
@@ -1,6 +1,6 @@
 /* Expands front end tree to back end RTL for GCC
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -151,17 +151,10 @@ force_label_rtx (tree label)
 {
   rtx ref = label_rtx (label);
   tree function = decl_function_context (label);
-  struct function *p;
 
   gcc_assert (function);
 
-  if (function != current_function_decl)
-    p = find_function_data (function);
-  else
-    p = cfun;
-
-  p->expr->x_forced_labels = gen_rtx_EXPR_LIST (VOIDmode, ref,
-                                               p->expr->x_forced_labels);
+  forced_labels = gen_rtx_EXPR_LIST (VOIDmode, ref, forced_labels);
   return ref;
 }
 
@@ -334,7 +327,7 @@ parse_output_constraint (const char **constraint_p, int operand_num,
                 *p, operand_num);
 
       /* Make a copy of the constraint.  */
-      buf = alloca (c_len + 1);
+      buf = XALLOCAVEC (char, c_len + 1);
       strcpy (buf, constraint);
       /* Swap the first character and the `=' or `+'.  */
       buf[p - constraint] = buf[0];
@@ -364,7 +357,7 @@ parse_output_constraint (const char **constraint_p, int operand_num,
          }
        break;
 
-      case 'V':  case 'm':  case 'o':
+      case 'V':  case TARGET_MEM_CONSTRAINT:  case 'o':
        *allows_mem = true;
        break;
 
@@ -463,7 +456,7 @@ parse_input_constraint (const char **constraint_p, int input_num,
          }
        break;
 
-      case 'V':  case 'm':  case 'o':
+      case 'V':  case TARGET_MEM_CONSTRAINT:  case 'o':
        *allows_mem = true;
        break;
 
@@ -566,7 +559,7 @@ decl_overlaps_hard_reg_set_p (tree *declp, int *walk_subtrees ATTRIBUTE_UNUSED,
                              void *data)
 {
   tree decl = *declp;
-  const HARD_REG_SET *regs = data;
+  const HARD_REG_SET *const regs = (const HARD_REG_SET *) data;
 
   if (TREE_CODE (decl) == VAR_DECL)
     {
@@ -623,7 +616,7 @@ tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET *clobbered_regs)
    STRING is the instruction template.
    OUTPUTS is a list of output arguments (lvalues); INPUTS a list of inputs.
    Each output or input has an expression in the TREE_VALUE and
-   and a tree list in TREE_PURPOSE which in turn contains a constraint
+   a tree list in TREE_PURPOSE which in turn contains a constraint
    name in TREE_VALUE (or NULL_TREE) and a constraint string
    in TREE_PURPOSE.
    CLOBBERS is a list of STRING_CST nodes each naming a hard register
@@ -652,13 +645,11 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
   tree t;
   int i;
   /* Vector of RTX's of evaluated output operands.  */
-  rtx *output_rtx = alloca (noutputs * sizeof (rtx));
-  int *inout_opnum = alloca (noutputs * sizeof (int));
-  rtx *real_output_rtx = alloca (noutputs * sizeof (rtx));
-  enum machine_mode *inout_mode
-    = alloca (noutputs * sizeof (enum machine_mode));
-  const char **constraints
-    = alloca ((noutputs + ninputs) * sizeof (const char *));
+  rtx *output_rtx = XALLOCAVEC (rtx, noutputs);
+  int *inout_opnum = XALLOCAVEC (int, noutputs);
+  rtx *real_output_rtx = XALLOCAVEC (rtx, noutputs);
+  enum machine_mode *inout_mode = XALLOCAVEC (enum machine_mode, noutputs);
+  const char **constraints = XALLOCAVEC (const char *, noutputs + ninputs);
   int old_generating_concat_p = generating_concat_p;
 
   /* An ASM with no outputs needs to be treated as volatile, for now.  */
@@ -1078,7 +1069,7 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
     if (real_output_rtx[i])
       emit_move_insn (real_output_rtx[i], output_rtx[i]);
 
-  cfun->has_asm_statement = 1;
+  crtl->has_asm_statement = 1;
   free_temp_slots ();
 }
 
@@ -1359,9 +1350,6 @@ expand_expr_stmt (tree exp)
   tree type;
 
   value = expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
-  if (GIMPLE_TUPLE_P (exp))
-    type = void_type_node;
-  else
   type = TREE_TYPE (exp);
 
   /* If all we do is reference a volatile value in memory,
@@ -1415,7 +1403,6 @@ warn_if_unused_value (const_tree exp, location_t locus)
     case PREDECREMENT_EXPR:
     case POSTDECREMENT_EXPR:
     case MODIFY_EXPR:
-    case GIMPLE_MODIFY_STMT:
     case INIT_EXPR:
     case TARGET_EXPR:
     case CALL_EXPR:
@@ -1584,10 +1571,10 @@ expand_return (tree retval)
       expand_null_return ();
       return;
     }
-  else if ((TREE_CODE (retval) == GIMPLE_MODIFY_STMT
+  else if ((TREE_CODE (retval) == MODIFY_EXPR
            || TREE_CODE (retval) == INIT_EXPR)
-          && TREE_CODE (GENERIC_TREE_OPERAND (retval, 0)) == RESULT_DECL)
-    retval_rhs = GENERIC_TREE_OPERAND (retval, 1);
+          && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
+    retval_rhs = TREE_OPERAND (retval, 1);
   else
     retval_rhs = retval;
 
@@ -1606,7 +1593,7 @@ expand_return (tree retval)
      (and in expand_call).  */
 
   else if (retval_rhs != 0
-          && TYPE_MODE (GENERIC_TREE_TYPE (retval_rhs)) == BLKmode
+          && TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode
           && REG_P (result_rtl))
     {
       int i;
@@ -1617,7 +1604,7 @@ expand_return (tree retval)
       int n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
       unsigned int bitsize
        = MIN (TYPE_ALIGN (TREE_TYPE (retval_rhs)), BITS_PER_WORD);
-      rtx *result_pseudos = alloca (sizeof (rtx) * n_regs);
+      rtx *result_pseudos = XALLOCAVEC (rtx, n_regs);
       rtx result_reg, src = NULL_RTX, dst = NULL_RTX;
       rtx result_val = expand_normal (retval_rhs);
       enum machine_mode tmpmode, result_reg_mode;
@@ -1776,11 +1763,11 @@ expand_nl_goto_receiver (void)
 {
   /* Clobber the FP when we get here, so we have to make sure it's
      marked as used by this function.  */
-  emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
+  emit_use (hard_frame_pointer_rtx);
 
   /* Mark the static chain as clobbered here so life information
      doesn't get messed up for it.  */
-  emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
+  emit_clobber (static_chain_rtx);
 
 #ifdef HAVE_nonlocal_goto
   if (! HAVE_nonlocal_goto)
@@ -1820,8 +1807,8 @@ expand_nl_goto_receiver (void)
        {
          /* Now restore our arg pointer from the address at which it
             was saved in our stack frame.  */
-         emit_move_insn (virtual_incoming_args_rtx,
-                         copy_to_reg (get_arg_pointer_save_area (cfun)));
+         emit_move_insn (crtl->args.internal_arg_pointer,
+                         copy_to_reg (get_arg_pointer_save_area ()));
        }
     }
 #endif
@@ -1874,8 +1861,8 @@ expand_decl (tree decl)
     SET_DECL_RTL (decl, gen_rtx_MEM (BLKmode, const0_rtx));
 
   else if (DECL_SIZE (decl) == 0)
-    /* Variable with incomplete type.  */
     {
+      /* Variable with incomplete type.  */
       rtx x;
       if (DECL_INITIAL (decl) == 0)
        /* Error message was already done; now avoid a crash.  */
@@ -1906,16 +1893,15 @@ expand_decl (tree decl)
                          TYPE_ALIGN (TREE_TYPE (TREE_TYPE (decl))));
     }
 
-  else if (TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST
-          && ! (flag_stack_check && ! STACK_CHECK_BUILTIN
-                && 0 < compare_tree_int (DECL_SIZE_UNIT (decl),
-                                         STACK_CHECK_MAX_VAR_SIZE)))
+  else
     {
-      /* Variable of fixed size that goes on the stack.  */
       rtx oldaddr = 0;
       rtx addr;
       rtx x;
 
+      /* Variable-sized decls are dealt with in the gimplifier.  */
+      gcc_assert (TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST);
+
       /* If we previously made RTL for this decl, it must be an array
         whose size was determined by the initializer.
         The old address was a register; set that register now
@@ -1943,41 +1929,6 @@ expand_decl (tree decl)
            emit_move_insn (oldaddr, addr);
        }
     }
-  else
-    /* Dynamic-size object: must push space on the stack.  */
-    {
-      rtx address, size, x;
-
-      /* Record the stack pointer on entry to block, if have
-        not already done so.  */
-      do_pending_stack_adjust ();
-
-      /* Compute the variable's size, in bytes.  This will expand any
-        needed SAVE_EXPRs for the first time.  */
-      size = expand_normal (DECL_SIZE_UNIT (decl));
-      free_temp_slots ();
-
-      /* Allocate space on the stack for the variable.  Note that
-        DECL_ALIGN says how the variable is to be aligned and we
-        cannot use it to conclude anything about the alignment of
-        the size.  */
-      address = allocate_dynamic_stack_space (size, NULL_RTX,
-                                             TYPE_ALIGN (TREE_TYPE (decl)));
-
-      /* Reference the variable indirect through that rtx.  */
-      x = gen_rtx_MEM (DECL_MODE (decl), address);
-      set_mem_attributes (x, decl, 1);
-      SET_DECL_RTL (decl, x);
-
-
-      /* Indicate the alignment we actually gave this variable.  */
-#ifdef STACK_BOUNDARY
-      DECL_ALIGN (decl) = STACK_BOUNDARY;
-#else
-      DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
-#endif
-      DECL_USER_ALIGN (decl) = 0;
-    }
 }
 \f
 /* Emit code to save the current value of stack.  */
@@ -1995,71 +1946,12 @@ expand_stack_save (void)
 void
 expand_stack_restore (tree var)
 {
-  rtx sa = DECL_RTL (var);
+  rtx sa = expand_normal (var);
 
+  sa = convert_memory_address (Pmode, sa);
   emit_stack_restore (SAVE_BLOCK, sa, NULL_RTX);
 }
 \f
-/* DECL is an anonymous union.  CLEANUP is a cleanup for DECL.
-   DECL_ELTS is the list of elements that belong to DECL's type.
-   In each, the TREE_VALUE is a VAR_DECL, and the TREE_PURPOSE a cleanup.  */
-
-void
-expand_anon_union_decl (tree decl, tree cleanup ATTRIBUTE_UNUSED,
-                       tree decl_elts)
-{
-  rtx x;
-  tree t;
-
-  /* If any of the elements are addressable, so is the entire union.  */
-  for (t = decl_elts; t; t = TREE_CHAIN (t))
-    if (TREE_ADDRESSABLE (TREE_VALUE (t)))
-      {
-       TREE_ADDRESSABLE (decl) = 1;
-       break;
-      }
-
-  expand_decl (decl);
-  x = DECL_RTL (decl);
-
-  /* Go through the elements, assigning RTL to each.  */
-  for (t = decl_elts; t; t = TREE_CHAIN (t))
-    {
-      tree decl_elt = TREE_VALUE (t);
-      enum machine_mode mode = TYPE_MODE (TREE_TYPE (decl_elt));
-      rtx decl_rtl;
-
-      /* If any of the elements are addressable, so is the entire
-        union.  */
-      if (TREE_USED (decl_elt))
-       TREE_USED (decl) = 1;
-
-      /* Propagate the union's alignment to the elements.  */
-      DECL_ALIGN (decl_elt) = DECL_ALIGN (decl);
-      DECL_USER_ALIGN (decl_elt) = DECL_USER_ALIGN (decl);
-
-      /* If the element has BLKmode and the union doesn't, the union is
-         aligned such that the element doesn't need to have BLKmode, so
-         change the element's mode to the appropriate one for its size.  */
-      if (mode == BLKmode && DECL_MODE (decl) != BLKmode)
-       DECL_MODE (decl_elt) = mode
-         = mode_for_size_tree (DECL_SIZE (decl_elt), MODE_INT, 1);
-
-      if (mode == GET_MODE (x))
-       decl_rtl = x;
-      else if (MEM_P (x))
-        /* (SUBREG (MEM ...)) at RTL generation time is invalid, so we
-           instead create a new MEM rtx with the proper mode.  */
-       decl_rtl = adjust_address_nv (x, mode, 0);
-      else
-       {
-         gcc_assert (REG_P (x));
-         decl_rtl = gen_lowpart_SUBREG (mode, x);
-       }
-      SET_DECL_RTL (decl_elt, decl_rtl);
-    }
-}
-\f
 /* Do the insertion of a case label into case_list.  The labels are
    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
@@ -2167,7 +2059,8 @@ bool lshift_cheap_p (void)
   if (!init)
     {
       rtx reg = gen_rtx_REG (word_mode, 10000);
-      int cost = rtx_cost (gen_rtx_ASHIFT (word_mode, const1_rtx, reg), SET);
+      int cost = rtx_cost (gen_rtx_ASHIFT (word_mode, const1_rtx, reg), SET,
+                          optimize_insn_for_speed_p ());
       cheap = cost < COSTS_N_INSNS (3);
       init = true;
     }
@@ -2182,8 +2075,8 @@ bool lshift_cheap_p (void)
 static int
 case_bit_test_cmp (const void *p1, const void *p2)
 {
-  const struct case_bit_test *d1 = p1;
-  const struct case_bit_test *d2 = p2;
+  const struct case_bit_test *const d1 = (const struct case_bit_test *) p1;
+  const struct case_bit_test *const d2 = (const struct case_bit_test *) p2;
 
   if (d2->bits != d1->bits)
     return d2->bits - d1->bits;
@@ -2259,8 +2152,9 @@ emit_case_bit_tests (tree index_type, tree index_expr, tree minval,
 
   mode = TYPE_MODE (index_type);
   expr = expand_normal (range);
-  emit_cmp_and_jump_insns (index, expr, GTU, NULL_RTX, mode, 1,
-                          default_label);
+  if (default_label)
+    emit_cmp_and_jump_insns (index, expr, GTU, NULL_RTX, mode, 1,
+                            default_label);
 
   index = convert_to_mode (word_mode, index, 0);
   index = expand_binop (word_mode, ashl_optab, const1_rtx,
@@ -2275,7 +2169,8 @@ emit_case_bit_tests (tree index_type, tree index_expr, tree minval,
                               word_mode, 1, test[i].label);
     }
 
-  emit_jump (default_label);
+  if (default_label)
+    emit_jump (default_label);
 }
 
 #ifndef HAVE_casesi
@@ -2321,7 +2216,7 @@ expand_case (tree exp)
   struct case_node *case_list = 0;
 
   /* Label to jump to if no case matches.  */
-  tree default_label_decl;
+  tree default_label_decl = NULL_TREE;
 
   alloc_pool case_node_pool = create_alloc_pool ("struct case_node pool",
                                                  sizeof (struct case_node),
@@ -2339,18 +2234,21 @@ expand_case (tree exp)
     {
       tree elt;
       bitmap label_bitmap;
+      int vl = TREE_VEC_LENGTH (vec);
 
       /* cleanup_tree_cfg removes all SWITCH_EXPR with their index
         expressions being INTEGER_CST.  */
       gcc_assert (TREE_CODE (index_expr) != INTEGER_CST);
 
-      /* The default case is at the end of TREE_VEC.  */
-      elt = TREE_VEC_ELT (vec, TREE_VEC_LENGTH (vec) - 1);
-      gcc_assert (!CASE_HIGH (elt));
-      gcc_assert (!CASE_LOW (elt));
-      default_label_decl = CASE_LABEL (elt);
+      /* The default case, if ever taken, is at the end of TREE_VEC.  */
+      elt = TREE_VEC_ELT (vec, vl - 1);
+      if (!CASE_LOW (elt) && !CASE_HIGH (elt))
+       {
+         default_label_decl = CASE_LABEL (elt);
+         --vl;
+       }
 
-      for (i = TREE_VEC_LENGTH (vec) - 1; --i >= 0; )
+      for (i = vl - 1; i >= 0; --i)
        {
          tree low, high;
          elt = TREE_VEC_ELT (vec, i);
@@ -2360,7 +2258,7 @@ expand_case (tree exp)
          high = CASE_HIGH (elt);
 
          /* Discard empty ranges.  */
-         if (high && INT_CST_LT (high, low))
+         if (high && tree_int_cst_lt (high, low))
            continue;
 
          case_list = add_case_node (case_list, index_type, low, high,
@@ -2369,7 +2267,8 @@ expand_case (tree exp)
 
 
       before_case = start = get_last_insn ();
-      default_label = label_rtx (default_label_decl);
+      if (default_label_decl)
+       default_label = label_rtx (default_label_decl);
 
       /* Get upper and lower bounds of case values.  */
 
@@ -2387,9 +2286,9 @@ expand_case (tree exp)
            }
          else
            {
-             if (INT_CST_LT (n->low, minval))
+             if (tree_int_cst_lt (n->low, minval))
                minval = n->low;
-             if (INT_CST_LT (maxval, n->high))
+             if (tree_int_cst_lt (maxval, n->high))
                maxval = n->high;
            }
          /* A range counts double, since it requires two compares.  */
@@ -2414,7 +2313,8 @@ expand_case (tree exp)
         type, so we may still get a zero here.  */
       if (count == 0)
        {
-         emit_jump (default_label);
+         if (default_label)
+           emit_jump (default_label);
           free_alloc_pool (case_node_pool);
          return;
        }
@@ -2454,7 +2354,7 @@ expand_case (tree exp)
 
       else if (count < case_values_threshold ()
               || compare_tree_int (range,
-                                   (optimize_size ? 3 : 10) * count) > 0
+                                   (optimize_insn_for_size_p () ? 3 : 10) * count) > 0
               /* RANGE may be signed, and really large ranges will show up
                  as negative numbers.  */
               || compare_tree_int (range, 0) < 0
@@ -2510,19 +2410,21 @@ expand_case (tree exp)
               && estimate_case_costs (case_list));
          balance_case_nodes (&case_list, NULL);
          emit_case_nodes (index, case_list, default_label, index_type);
-         emit_jump (default_label);
+         if (default_label)
+           emit_jump (default_label);
        }
       else
        {
+         rtx fallback_label = label_rtx (case_list->code_label);
          table_label = gen_label_rtx ();
          if (! try_casesi (index_type, index_expr, minval, range,
-                           table_label, default_label))
+                           table_label, default_label, fallback_label))
            {
              bool ok;
 
              /* Index jumptables from zero for suitable values of
                  minval to avoid a subtraction.  */
-             if (! optimize_size
+             if (optimize_insn_for_speed_p ()
                  && compare_tree_int (minval, 0) > 0
                  && compare_tree_int (minval, 3) < 0)
                {
@@ -2538,7 +2440,7 @@ expand_case (tree exp)
          /* Get table of labels to jump to, in order of case index.  */
 
          ncases = tree_low_cst (range, 0) + 1;
-         labelvec = alloca (ncases * sizeof (rtx));
+         labelvec = XALLOCAVEC (rtx, ncases);
          memset (labelvec, 0, ncases * sizeof (rtx));
 
          for (n = case_list; n; n = n->right)
@@ -2559,7 +2461,12 @@ expand_case (tree exp)
                  = gen_rtx_LABEL_REF (Pmode, label_rtx (n->code_label));
            }
 
-         /* Fill in the gaps with the default.  */
+         /* Fill in the gaps with the default.  We may have gaps at
+            the beginning if we tried to avoid the minval subtraction,
+            so substitute some label even if the default label was
+            deemed unreachable.  */
+         if (!default_label)
+           default_label = fallback_label;
          for (i = 0; i < ncases; i++)
            if (labelvec[i] == 0)
              labelvec[i] = gen_rtx_LABEL_REF (Pmode, default_label);
@@ -2664,7 +2571,8 @@ estimate_case_costs (case_node_ptr node)
 
   for (n = node; n; n = n->right)
     {
-      if ((INT_CST_LT (n->low, min_ascii)) || INT_CST_LT (max_ascii, n->high))
+      if (tree_int_cst_lt (n->low, min_ascii)
+         || tree_int_cst_lt (max_ascii, n->high))
        return 0;
 
       for (i = (HOST_WIDE_INT) TREE_INT_CST_LOW (n->low);
@@ -3043,7 +2951,8 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
              emit_case_nodes (index, node->left, default_label, index_type);
              /* If left-hand subtree does nothing,
                 go to default.  */
-             emit_jump (default_label);
+             if (default_label)
+               emit_jump (default_label);
 
              /* Code branches here for the right-hand subtree.  */
              expand_label (test_label);
@@ -3178,7 +3087,8 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
            {
              /* If the left-hand subtree fell through,
                 don't let it fall into the right-hand subtree.  */
-             emit_jump (default_label);
+             if (default_label)
+               emit_jump (default_label);
 
              expand_label (test_label);
              emit_case_nodes (index, node->right, default_label, index_type);