OSDN Git Service

* fixinc/server.c (load_data, run_shell): Use xmalloc, xrealloc &
[pf3gnuchains/gcc-fork.git] / gcc / stmt.c
index 25382cc..4ca2c97 100644 (file)
@@ -106,8 +106,12 @@ typedef struct case_node *case_node_ptr;
 
 /* This must be a signed type, and non-ANSI compilers lack signed char.  */
 static short cost_table_[129];
-static short *cost_table;
 static int use_cost_table;
+static int cost_table_initialized;
+
+/* Special care is needed because we allow -1, but TREE_INT_CST_LOW
+   is unsigned.  */
+#define COST_TABLE(I)  cost_table_[(unsigned HOST_WIDE_INT)((I) + 1)]
 \f
 /* Stack of control and binding constructs we are currently inside.
 
@@ -393,9 +397,6 @@ struct stmt_status
 /* Non-zero if we are using EH to handle cleanus.  */
 static int using_eh_for_cleanups_p = 0;
 
-/* Character strings, each containing a single decimal digit.  */
-static char *digit_strings[10];
-
 static int n_occurrences               PARAMS ((int, const char *));
 static void expand_goto_internal       PARAMS ((tree, rtx, rtx));
 static int expand_fixup                        PARAMS ((tree, rtx, rtx));
@@ -426,7 +427,7 @@ static void mark_block_nesting          PARAMS ((struct nesting *));
 static void mark_case_nesting           PARAMS ((struct nesting *));
 static void mark_case_node             PARAMS ((struct case_node *));
 static void mark_goto_fixup             PARAMS ((struct goto_fixup *));
-
+static void free_case_nodes             PARAMS ((case_node_ptr));
 \f
 void
 using_eh_for_cleanups ()
@@ -485,8 +486,11 @@ mark_block_nesting (n)
       ggc_mark_tree (n->data.block.cleanups);
       ggc_mark_tree (n->data.block.outer_cleanups);
 
-      for (l = n->data.block.label_chain; l != NULL; l = l->next)
-       ggc_mark_tree (l->label);
+      for (l = n->data.block.label_chain; l != NULL; l = l->next) 
+       {
+         ggc_mark (l);
+         ggc_mark_tree (l->label);
+       }
 
       ggc_mark_rtx (n->data.block.last_unconditional_cleanup);
 
@@ -594,16 +598,7 @@ mark_stmt_status (p)
 void
 init_stmt ()
 {
-  int i;
-
   gcc_obstack_init (&stmt_obstack);
-
-  for (i = 0; i < 10; i++)
-    {
-      digit_strings[i] = ggc_alloc_string (NULL, 1);
-      digit_strings[i][0] = '0' + i;
-    }
-  ggc_add_string_root (digit_strings, 10);
 }
 
 void
@@ -713,7 +708,7 @@ expand_computed_goto (exp)
   emit_queue ();
   /* Be sure the function is executable.  */
   if (current_function_check_memory_usage)
-    emit_library_call (chkr_check_exec_libfunc, 1,
+    emit_library_call (chkr_check_exec_libfunc, LCT_CONST_MAKE_BLOCK,
                       VOIDmode, 1, x, ptr_mode);
 
   do_pending_stack_adjust ();
@@ -748,7 +743,7 @@ expand_label (label)
 
   if (stack_block_stack != 0)
     {
-      p = (struct label_chain *) oballoc (sizeof (struct label_chain));
+      p = (struct label_chain *) ggc_alloc (sizeof (struct label_chain));
       p->next = stack_block_stack->data.block.label_chain;
       stack_block_stack->data.block.label_chain = p;
       p->label = label;
@@ -792,7 +787,7 @@ expand_goto (label)
     {
       struct function *p = find_function_data (context);
       rtx label_ref = gen_rtx_LABEL_REF (Pmode, label_rtx (label));
-      rtx handler_slot, static_chain, save_area;
+      rtx handler_slot, static_chain, save_area, insn;
       tree link;
 
       /* Find the corresponding handler slot for this label.  */
@@ -845,6 +840,15 @@ expand_goto (label)
          emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
          emit_indirect_jump (handler_slot);
        }
+
+      /* Search backwards to the jump insn and mark it as a 
+        non-local goto.  */
+      for (insn = get_last_insn ();
+          GET_CODE (insn) != JUMP_INSN; 
+          insn = PREV_INSN (insn))
+       continue;
+      REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
+                                         REG_NOTES (insn));
     }
   else
     expand_goto_internal (label, label_rtx (label), NULL_RTX);
@@ -1405,7 +1409,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
     {
       tree val = TREE_VALUE (tail);
       tree type = TREE_TYPE (val);
-      char *constraint;
+      const char *constraint;
       char *p;
       int c_len;
       int j;
@@ -1422,8 +1426,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
         the worst that happens if we get it wrong is we issue an error
         message.  */
 
-      c_len = strlen (TREE_STRING_POINTER (TREE_PURPOSE (tail)));
       constraint = TREE_STRING_POINTER (TREE_PURPOSE (tail));
+      c_len = strlen (constraint);
 
       /* Allow the `=' or `+' to not be at the beginning of the string,
         since it wasn't explicitly documented that way, and there is a
@@ -1440,19 +1444,25 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
          error ("output operand constraint lacks `='");
          return;
        }
+      j = p - constraint;
+      is_inout = *p == '+';
 
-      if (p != constraint)
+      if (j || is_inout)
        {
-         j = *p;
-         bcopy (constraint, constraint+1, p-constraint);
-         *constraint = j;
-
-         warning ("output constraint `%c' for operand %d is not at the beginning", j, i);
+         /* Have to throw away this constraint string and get a new one.  */
+         char *buf = alloca (c_len + 1);
+         buf[0] = '=';
+         if (j)
+           memcpy (buf + 1, constraint, j);
+         memcpy (buf + 1 + j, p + 1, c_len - j);  /* not -j-1 - copy null */
+         constraint = ggc_alloc_string (buf, c_len);
+
+         if (j)
+           warning (
+               "output constraint `%c' for operand %d is not at the beginning",
+               *p, i);
        }
 
-      is_inout = constraint[0] == '+';
-      /* Replace '+' with '='.  */
-      constraint[0] = '=';
       /* Make sure we can specify the matching operand.  */
       if (is_inout && i > 9)
        {
@@ -1476,7 +1486,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
              }
            break;
 
-         case '?':  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':
@@ -1608,7 +1618,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
     {
       int j;
       int allows_reg = 0, allows_mem = 0;
-      char *constraint, *orig_constraint;
+      const char *constraint, *orig_constraint;
       int c_len;
       rtx op;
 
@@ -1626,8 +1636,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
          return;
        }
 
-      c_len = strlen (TREE_STRING_POINTER (TREE_PURPOSE (tail)));
       constraint = TREE_STRING_POINTER (TREE_PURPOSE (tail));
+      c_len = strlen (constraint);
       orig_constraint = constraint;
 
       /* Make sure constraint has neither `=', `+', nor '&'.  */
@@ -1658,7 +1668,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
            break;
 
          case '<':  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':
@@ -1688,8 +1698,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
                for (j = constraint[j] - '0'; j > 0; --j)
                  o = TREE_CHAIN (o);
 
-               c_len = strlen (TREE_STRING_POINTER (TREE_PURPOSE (o)));
                constraint = TREE_STRING_POINTER (TREE_PURPOSE (o));
+               c_len = strlen (constraint);
                j = 0;
                break;
              }
@@ -1751,7 +1761,10 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
                   || GET_CODE (op) == CONCAT)
            {
              tree type = TREE_TYPE (TREE_VALUE (tail));
-             rtx memloc = assign_temp (type, 1, 1, 1);
+             tree qual_type = build_qualified_type (type,
+                                                    (TYPE_QUALS (type)
+                                                     | TYPE_QUAL_CONST));
+             rtx memloc = assign_temp (qual_type, 1, 1, 1);
 
              emit_move_insn (memloc, op);
              op = memloc;
@@ -1798,7 +1811,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
       ASM_OPERANDS_INPUT (body, ninputs - ninout + i)
        = output_rtx[j];
       ASM_OPERANDS_INPUT_CONSTRAINT_EXP (body, ninputs - ninout + i)
-       = gen_rtx_ASM_INPUT (inout_mode[i], digit_strings[j]);
+       = gen_rtx_ASM_INPUT (inout_mode[i], digit_string (j));
     }
 
   generating_concat_p = old_generating_concat_p;
@@ -1908,12 +1921,14 @@ expand_expr_stmt (exp)
      except inside a ({...}) where they may be useful.  */
   if (expr_stmts_for_value == 0 && exp != error_mark_node)
     {
-      if (! TREE_SIDE_EFFECTS (exp)
-         && (extra_warnings || warn_unused_value)
-         && !(TREE_CODE (exp) == CONVERT_EXPR
-              && VOID_TYPE_P (TREE_TYPE (exp))))
-       warning_with_file_and_line (emit_filename, emit_lineno,
-                                   "statement with no effect");
+      if (! TREE_SIDE_EFFECTS (exp))
+       {
+         if ((extra_warnings || warn_unused_value)
+             && !(TREE_CODE (exp) == CONVERT_EXPR
+                  && VOID_TYPE_P (TREE_TYPE (exp))))
+           warning_with_file_and_line (emit_filename, emit_lineno,
+                                       "statement with no effect");
+       }
       else if (warn_unused_value)
        warn_if_unused_value (exp);
     }
@@ -1978,6 +1993,16 @@ warn_if_unused_value (exp)
   if (TREE_USED (exp))
     return 0;
 
+  /* Don't warn about void constructs.  This includes casting to void,
+     void function calls, and statement expressions with a final cast
+     to void.  */
+  if (VOID_TYPE_P (TREE_TYPE (exp)))
+    return 0;
+
+  /* If this is an expression with side effects, don't warn.  */
+  if (TREE_SIDE_EFFECTS (exp))
+    return 0;
+
   switch (TREE_CODE (exp))
     {
     case PREINCREMENT_EXPR:
@@ -1993,9 +2018,6 @@ warn_if_unused_value (exp)
     case TRY_CATCH_EXPR:
     case WITH_CLEANUP_EXPR:
     case EXIT_EXPR:
-      /* We don't warn about COND_EXPR because it may be a useful
-        construct if either arm contains a side effect.  */
-    case COND_EXPR:
       return 0;
 
     case BIND_EXPR:
@@ -2023,9 +2045,6 @@ warn_if_unused_value (exp)
     case NOP_EXPR:
     case CONVERT_EXPR:
     case NON_LVALUE_EXPR:
-      /* Don't warn about values cast to void.  */
-      if (VOID_TYPE_P (TREE_TYPE (exp)))
-       return 0;
       /* Don't warn about conversions not explicit in the user's program.  */
       if (TREE_NO_UNUSED_WARNING (exp))
        return 0;
@@ -2088,14 +2107,11 @@ clear_last_expr ()
 tree
 expand_start_stmt_expr ()
 {
-  int momentary;
   tree t;
 
   /* Make the RTL_EXPR node temporary, not momentary,
      so that rtl_expr_chain doesn't become garbage.  */
-  momentary = suspend_momentary ();
   t = make_node (RTL_EXPR);
-  resume_momentary (momentary);
   do_pending_stack_adjust ();
   start_sequence_for_rtl_expr (t);
   NO_DEFER_POP;
@@ -2289,6 +2305,30 @@ expand_start_loop_continue_elsewhere (exit_flag)
   return thisloop;
 }
 
+/* Begin a null, aka do { } while (0) "loop".  But since the contents
+   of said loop can still contain a break, we must frob the loop nest.  */
+
+struct nesting *
+expand_start_null_loop ()
+{
+  register struct nesting *thisloop = ALLOC_NESTING ();
+
+  /* Make an entry on loop_stack for the loop we are entering.  */
+
+  thisloop->next = loop_stack;
+  thisloop->all = nesting_stack;
+  thisloop->depth = ++nesting_depth;
+  thisloop->data.loop.start_label = emit_note (NULL, NOTE_INSN_DELETED);
+  thisloop->data.loop.end_label = gen_label_rtx ();
+  thisloop->data.loop.alt_end_label = NULL_RTX;
+  thisloop->data.loop.continue_label = thisloop->data.loop.end_label;
+  thisloop->exit_label = thisloop->data.loop.end_label;
+  loop_stack = thisloop;
+  nesting_stack = thisloop;
+
+  return thisloop;
+}
+
 /* Specify the continuation point for a loop started with
    expand_start_loop_continue_elsewhere.
    Use this at the point in the code to which a continue statement
@@ -2615,6 +2655,19 @@ expand_end_loop ()
   last_expr_type = 0;
 }
 
+/* Finish a null loop, aka do { } while (0).  */
+
+void
+expand_end_null_loop ()
+{
+  do_pending_stack_adjust ();
+  emit_label (loop_stack->data.loop.end_label);
+
+  POPSTACK (loop_stack);
+
+  last_expr_type = 0;
+}
+
 /* Generate a jump to the current loop's continue-point.
    This is usually the top of the loop, but may be specified
    explicitly elsewhere.  If not currently inside a loop,
@@ -2893,7 +2946,12 @@ expand_return (retval)
 #endif
 
   if (retval == error_mark_node)
-    retval_rhs = NULL_TREE;
+    {
+      /* Treat this like a return of no value from a function that
+        returns a value.  */
+      expand_null_return ();
+      return; 
+    }
   else if (TREE_CODE (retval) == RESULT_DECL)
     retval_rhs = retval;
   else if ((TREE_CODE (retval) == MODIFY_EXPR || TREE_CODE (retval) == INIT_EXPR)
@@ -2967,6 +3025,12 @@ expand_return (retval)
       rtx result_val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0);
       enum machine_mode tmpmode, result_reg_mode;
 
+      if (bytes == 0)
+       {
+         expand_null_return ();
+         return;
+       }
+
       /* Structures whose size is not a multiple of a word are aligned
         to the least significant byte (to the right).  On a BYTES_BIG_ENDIAN
         machine, this means we must skip the empty high order bytes when
@@ -3014,15 +3078,12 @@ expand_return (retval)
       /* Find the smallest integer mode large enough to hold the
         entire structure and use that mode instead of BLKmode
         on the USE insn for the return register.   */
-      bytes = int_size_in_bytes (TREE_TYPE (retval_rhs));
       for (tmpmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
           tmpmode != VOIDmode;
           tmpmode = GET_MODE_WIDER_MODE (tmpmode))
-       {
-         /* Have we found a large enough mode?  */
-         if (GET_MODE_SIZE (tmpmode) >= bytes)
-           break;
-       }
+       /* Have we found a large enough mode?  */
+       if (GET_MODE_SIZE (tmpmode) >= bytes)
+         break;
 
       /* No suitable mode found.  */
       if (tmpmode == VOIDmode)
@@ -3054,8 +3115,10 @@ expand_return (retval)
     {
       /* Calculate the return value into a temporary (usually a pseudo
          reg).  */
-      val = assign_temp (TREE_TYPE (DECL_RESULT (current_function_decl)),
-                        0, 0, 1);
+      tree ot = TREE_TYPE (DECL_RESULT (current_function_decl));
+      tree nt = build_qualified_type (ot, TYPE_QUALS (ot) | TYPE_QUAL_CONST);
+
+      val = assign_temp (nt, 0, 0, 1);
       val = expand_expr (retval_rhs, val, GET_MODE (val), 0);
       val = force_not_mem (val);
       emit_queue ();
@@ -3776,12 +3839,13 @@ expand_decl (decl)
 
   if (type == error_mark_node)
     DECL_RTL (decl) = gen_rtx_MEM (BLKmode, const0_rtx);
+
   else if (DECL_SIZE (decl) == 0)
     /* Variable with incomplete type.  */
     {
       if (DECL_INITIAL (decl) == 0)
        /* Error message was already done; now avoid a crash.  */
-       DECL_RTL (decl) = assign_stack_temp (DECL_MODE (decl), 0, 1);
+       DECL_RTL (decl) = gen_rtx_MEM (BLKmode, const0_rtx);
       else
        /* An initializer is going to decide the size of this array.
           Until we know the size, represent its address with a reg.  */
@@ -3795,7 +3859,6 @@ expand_decl (decl)
           && !(flag_float_store
                && TREE_CODE (type) == REAL_TYPE)
           && ! TREE_THIS_VOLATILE (decl)
-          && ! TREE_ADDRESSABLE (decl)
           && (DECL_REGISTER (decl) || optimize)
           /* if -fcheck-memory-usage, check all variables.  */
           && ! current_function_check_memory_usage)
@@ -3813,6 +3876,10 @@ expand_decl (decl)
                          TYPE_ALIGN (TREE_TYPE (TREE_TYPE (decl))));
 
       maybe_set_unchanging (DECL_RTL (decl), decl);
+
+      /* If something wants our address, try to use ADDRESSOF.  */
+      if (TREE_ADDRESSABLE (decl))
+       put_var_into_stack (decl);
     }
 
   else if (TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST
@@ -3993,10 +4060,6 @@ expand_decl_cleanup (decl, cleanup)
 
          emit_move_insn (flag, const1_rtx);
 
-         /* All cleanups must be on the function_obstack.  */
-         push_obstacks_nochange ();
-         resume_temporary_allocation ();
-
          cond = build_decl (VAR_DECL, NULL_TREE, type_for_mode (word_mode, 1));
          DECL_RTL (cond) = flag;
 
@@ -4006,18 +4069,12 @@ expand_decl_cleanup (decl, cleanup)
                           cleanup, integer_zero_node);
          cleanup = fold (cleanup);
 
-         pop_obstacks ();
-
          cleanups = thisblock->data.block.cleanup_ptr;
        }
 
-      /* All cleanups must be on the function_obstack.  */
-      push_obstacks_nochange ();
-      resume_temporary_allocation ();
       cleanup = unsave_expr (cleanup);
-      pop_obstacks ();
 
-      t = *cleanups = temp_tree_cons (decl, cleanup, *cleanups);
+      t = *cleanups = tree_cons (decl, cleanup, *cleanups);
 
       if (! cond_context)
        /* If this block has a cleanup, it belongs in stack_block_stack.  */
@@ -4109,15 +4166,11 @@ expand_dcc_cleanup (decl)
 
   /* Record the cleanup for the dynamic handler chain.  */
 
-  /* All cleanups must be on the function_obstack.  */
-  push_obstacks_nochange ();
-  resume_temporary_allocation ();
   cleanup = make_node (POPDCC_EXPR);
-  pop_obstacks ();
 
   /* Add the cleanup in a manner similar to expand_decl_cleanup.  */
   thisblock->data.block.cleanups
-    = temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups);
+    = tree_cons (decl, cleanup, thisblock->data.block.cleanups);
 
   /* If this block has a cleanup, it belongs in stack_block_stack.  */
   stack_block_stack = thisblock;
@@ -4151,15 +4204,11 @@ expand_dhc_cleanup (decl)
 
   /* Record the cleanup for the dynamic handler chain.  */
 
-  /* All cleanups must be on the function_obstack.  */
-  push_obstacks_nochange ();
-  resume_temporary_allocation ();
   cleanup = make_node (POPDHC_EXPR);
-  pop_obstacks ();
 
   /* Add the cleanup in a manner similar to expand_decl_cleanup.  */
   thisblock->data.block.cleanups
-    = temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups);
+    = tree_cons (decl, cleanup, thisblock->data.block.cleanups);
 
   /* If this block has a cleanup, it belongs in stack_block_stack.  */
   stack_block_stack = thisblock;
@@ -4234,8 +4283,8 @@ expand_anon_union_decl (decl, cleanup, decl_elts)
 
       if (cleanup != 0)
        thisblock->data.block.cleanups
-         = temp_tree_cons (decl_elt, cleanup_elt,
-                           thisblock->data.block.cleanups);
+         = tree_cons (decl_elt, cleanup_elt,
+                      thisblock->data.block.cleanups);
     }
 }
 \f
@@ -4704,18 +4753,16 @@ add_case_node (low, high, label, duplicate)
        }
     }
 
-  /* Add this label to the chain, and succeed.
-     Copy LOW, HIGH so they are on temporary rather than momentary
-     obstack and will thus survive till the end of the case statement.  */
+  /* Add this label to the chain, and succeed.  */
 
-  r = (struct case_node *) oballoc (sizeof (struct case_node));
-  r->low = copy_node (low);
+  r = (struct case_node *) xmalloc (sizeof (struct case_node));
+  r->low = low;
 
   /* If the bounds are equal, turn this into the one-value case.  */
   if (tree_int_cst_equal (low, high))
     r->high = r->low;
   else
-    r->high = copy_node (high);
+    r->high = high;
 
   r->code_label = label;
   expand_label (label);
@@ -5146,7 +5193,8 @@ check_for_full_enumeration_handling (type)
       /* We deliberately use calloc here, not cmalloc, so that we can suppress
         this optimization if we don't have enough memory rather than
         aborting, as xmalloc would do.  */
-      && (cases_seen = (unsigned char *) calloc (bytes_needed, 1)) != NULL)
+      && (cases_seen =
+         (unsigned char *) really_call_calloc (bytes_needed, 1)) != NULL)
     {
       HOST_WIDE_INT i;
       tree v = TYPE_VALUES (type);
@@ -5242,6 +5290,20 @@ check_for_full_enumeration_handling (type)
 #endif /* 0 */
 }
 
+/* Free CN, and its children.  */
+
+static void 
+free_case_nodes (cn)
+     case_node_ptr cn;
+{
+  if (cn) 
+    {
+      free_case_nodes (cn->left);
+      free_case_nodes (cn->right);
+      free (cn);
+    }
+}
+
 \f
 /* Terminate a case (Pascal) or switch (C) statement
    in which ORIG_INDEX is the expression to be tested.
@@ -5574,7 +5636,7 @@ expand_end_case (orig_index)
 
          ncases = TREE_INT_CST_LOW (range) + 1;
          labelvec = (rtx *) alloca (ncases * sizeof (rtx));
-         bzero ((char *) labelvec, ncases * sizeof (rtx));
+         memset ((char *) labelvec, 0, ncases * sizeof (rtx));
 
          for (n = thiscase->data.case_stmt.case_list; n; n = n->right)
            {
@@ -5629,6 +5691,7 @@ expand_end_case (orig_index)
   if (thiscase->exit_label)
     emit_label (thiscase->exit_label);
 
+  free_case_nodes (case_stack->data.case_stmt.case_list);
   POPSTACK (case_stack);
 
   free_temp_slots ();
@@ -5707,7 +5770,7 @@ static int
 estimate_case_costs (node)
      case_node_ptr node;
 {
-  tree min_ascii = build_int_2 (-1, -1);
+  tree min_ascii = integer_minus_one_node;
   tree max_ascii = convert (TREE_TYPE (node->high), build_int_2 (127, 0));
   case_node_ptr n;
   int i;
@@ -5715,27 +5778,27 @@ estimate_case_costs (node)
   /* If we haven't already made the cost table, make it now.  Note that the
      lower bound of the table is -1, not zero.  */
 
-  if (cost_table == NULL)
+  if (! cost_table_initialized)
     {
-      cost_table = cost_table_ + 1;
+      cost_table_initialized = 1;
 
       for (i = 0; i < 128; i++)
        {
          if (ISALNUM (i))
-           cost_table[i] = 16;
+           COST_TABLE (i) = 16;
          else if (ISPUNCT (i))
-           cost_table[i] = 8;
+           COST_TABLE (i) = 8;
          else if (ISCNTRL (i))
-           cost_table[i] = -1;
+           COST_TABLE (i) = -1;
        }
 
-      cost_table[' '] = 8;
-      cost_table['\t'] = 4;
-      cost_table['\0'] = 4;
-      cost_table['\n'] = 2;
-      cost_table['\f'] = 1;
-      cost_table['\v'] = 1;
-      cost_table['\b'] = 1;
+      COST_TABLE (' ') = 8;
+      COST_TABLE ('\t') = 4;
+      COST_TABLE ('\0') = 4;
+      COST_TABLE ('\n') = 2;
+      COST_TABLE ('\f') = 1;
+      COST_TABLE ('\v') = 1;
+      COST_TABLE ('\b') = 1;
     }
 
   /* See if all the case expressions look like text.  It is text if the
@@ -5751,7 +5814,7 @@ estimate_case_costs (node)
 
       for (i = (HOST_WIDE_INT) TREE_INT_CST_LOW (n->low);
           i <= (HOST_WIDE_INT) TREE_INT_CST_LOW (n->high); i++)
-       if (cost_table[i] < 0)
+       if (COST_TABLE (i) < 0)
          return 0;
     }
 
@@ -5842,11 +5905,11 @@ balance_case_nodes (head, parent)
            {
              ranges++;
              if (use_cost_table)
-               cost += cost_table[TREE_INT_CST_LOW (np->high)];
+               cost += COST_TABLE (TREE_INT_CST_LOW (np->high));
            }
 
          if (use_cost_table)
-           cost += cost_table[TREE_INT_CST_LOW (np->low)];
+           cost += COST_TABLE (TREE_INT_CST_LOW (np->low));
 
          i++;
          np = np->right;
@@ -5867,8 +5930,8 @@ balance_case_nodes (head, parent)
                {
                  /* Skip nodes while their cost does not reach that amount.  */
                  if (!tree_int_cst_equal ((*npp)->low, (*npp)->high))
-                   i -= cost_table[TREE_INT_CST_LOW ((*npp)->high)];
-                 i -= cost_table[TREE_INT_CST_LOW ((*npp)->low)];
+                   i -= COST_TABLE (TREE_INT_CST_LOW ((*npp)->high));
+                 i -= COST_TABLE (TREE_INT_CST_LOW ((*npp)->low));
                  if (i <= 0)
                    break;
                  npp = &(*npp)->right;
@@ -6200,7 +6263,7 @@ emit_case_nodes (index, node, default_label, index_type)
             a branch-greater-than will get us to the default
             label correctly.  */
          if (use_cost_table
-             && cost_table[TREE_INT_CST_LOW (node->high)] < 12)
+             && COST_TABLE (TREE_INT_CST_LOW (node->high)) < 12)
            ;
 #endif /* 0 */
          if (node->left->left || node->left->right