OSDN Git Service

* c-decl.c (grokdeclarator): Don't frob current_function_decl
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 3 Jul 2004 00:15:50 +0000 (00:15 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 3 Jul 2004 00:15:50 +0000 (00:15 +0000)
        around variable_size.
        (set_decl_nonlocal): Remove.
        (store_parm_decls): Add stmts for pending sizes.
        * calls.c (calls_function, calls_function_1): Remove.
        (precompute_arguments): Don't call it.
        * cfgexpand.c (set_save_expr_context): Remove.
        (tree_expand_cfg): Don't call it.
        * dwarf2out.c (add_bound_info): Don't handle SAVE_EXPR.
        (dwarf2out_finish): Likewise.
        * expr.c (emit_block_move): Adjust addresses to BLKmode.
        (store_constructor): Don't pre-evaluate SAVE_EXPR.
        (safe_from_p): Don't queue SAVE_EXPRs.
        (expand_expr_real_1 <case SAVE_EXPR>): Rewrite to expect,
        or build plain VAR_DECLs.
        * fold-const.c (twoval_comparison_p): Don't look at SAVE_EXPR_RTL.
        (fold): Likewise.
        (fold_checksum_tree): Don't special-case SAVE_EXPR.
        * function.c (free_after_compilation): Don't clear x_save_expr_regs.
        (put_var_into_stack): Don't handle SAVE_EXPR.
        (gen_mem_addressof): Likewise.
        * function.h (struct function): Remove x_save_expr_regs.
        (save_expr_regs): Remove.
        * gengtype.c (adjust_field_tree_exp): Don't special-case SAVE_EXPR.
        * print-tree.c (print_node): Don't dump SAVE_EXPR_NOPLACEHOLDER.
        * stor-layout.c (variable_size): Don't set it.
        (force_type_save_exprs, force_type_save_exprs_1): Remove.
        * tree-inline.c (remap_save_expr): Remove fn argument.  Update
        all callers.  Don't set SAVE_EXPR_CONTEXT.
        * tree-inline.h (remap_save_expr): Update decl.
        * tree.c (save_expr): Update build size.
        (first_rtl_op): Don't handle SAVE_EXPR.
        (unsave_expr_1, contains_placeholder_p): Likewise.
        (decl_function_context): Likewise.
        * tree.def (SAVE_EXPR): Remove args 1 and 2.
        * tree.h (SAVE_EXPR_CONTEXT, SAVE_EXPR_RTL): Remove.
        (SAVE_EXPR_NOPLACEHOLDER, SAVE_EXPR_PERSISTENT_P): Remove.
cp/
        * tree.c (cp_unsave_r): Update remap_save_expr call.
java/
        * jcf-write.c (generate_bytecode_insns <case SAVE_EXPR>): Rewrite.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@84036 138bc75d-0d04-0410-961f-82ee72b054a4

21 files changed:
gcc/ChangeLog
gcc/c-decl.c
gcc/calls.c
gcc/cfgexpand.c
gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/dwarf2out.c
gcc/expr.c
gcc/fold-const.c
gcc/function.c
gcc/function.h
gcc/gengtype.c
gcc/java/ChangeLog
gcc/java/jcf-write.c
gcc/print-tree.c
gcc/stor-layout.c
gcc/tree-inline.c
gcc/tree-inline.h
gcc/tree.c
gcc/tree.def
gcc/tree.h

index 479cec5..bce517a 100644 (file)
@@ -1,3 +1,43 @@
+2004-07-02  Richard Henderson  <rth@redhat.com>
+
+       * c-decl.c (grokdeclarator): Don't frob current_function_decl
+       around variable_size.
+       (set_decl_nonlocal): Remove.
+       (store_parm_decls): Add stmts for pending sizes.
+       * calls.c (calls_function, calls_function_1): Remove.
+       (precompute_arguments): Don't call it.
+       * cfgexpand.c (set_save_expr_context): Remove.
+       (tree_expand_cfg): Don't call it.
+       * dwarf2out.c (add_bound_info): Don't handle SAVE_EXPR.
+       (dwarf2out_finish): Likewise.
+       * expr.c (emit_block_move): Adjust addresses to BLKmode.
+       (store_constructor): Don't pre-evaluate SAVE_EXPR.
+       (safe_from_p): Don't queue SAVE_EXPRs.
+       (expand_expr_real_1 <case SAVE_EXPR>): Rewrite to expect,
+       or build plain VAR_DECLs.
+       * fold-const.c (twoval_comparison_p): Don't look at SAVE_EXPR_RTL.
+       (fold): Likewise.
+       (fold_checksum_tree): Don't special-case SAVE_EXPR.
+       * function.c (free_after_compilation): Don't clear x_save_expr_regs.
+       (put_var_into_stack): Don't handle SAVE_EXPR.
+       (gen_mem_addressof): Likewise.
+       * function.h (struct function): Remove x_save_expr_regs.
+       (save_expr_regs): Remove.
+       * gengtype.c (adjust_field_tree_exp): Don't special-case SAVE_EXPR.
+       * print-tree.c (print_node): Don't dump SAVE_EXPR_NOPLACEHOLDER.
+       * stor-layout.c (variable_size): Don't set it.
+       (force_type_save_exprs, force_type_save_exprs_1): Remove.
+       * tree-inline.c (remap_save_expr): Remove fn argument.  Update
+       all callers.  Don't set SAVE_EXPR_CONTEXT.
+       * tree-inline.h (remap_save_expr): Update decl.
+       * tree.c (save_expr): Update build size.
+       (first_rtl_op): Don't handle SAVE_EXPR.
+       (unsave_expr_1, contains_placeholder_p): Likewise.
+       (decl_function_context): Likewise.
+       * tree.def (SAVE_EXPR): Remove args 1 and 2.
+       * tree.h (SAVE_EXPR_CONTEXT, SAVE_EXPR_RTL): Remove.
+       (SAVE_EXPR_NOPLACEHOLDER, SAVE_EXPR_PERSISTENT_P): Remove.
+
 2004-07-03  Joseph S. Myers  <jsm@polyomino.org.uk>
 
        * doc/bugreport.texi, doc/configterms.texi, doc/contrib.texi,
index 00bb587..329c862 100644 (file)
@@ -3990,20 +3990,7 @@ grokdeclarator (tree declarator, tree declspecs,
                    }
 
                  if (size_varies)
-                   {
-                     /* We must be able to distinguish the
-                        SAVE_EXPR_CONTEXT for the variably-sized type
-                        so that we can set it correctly in
-                        set_save_expr_context.  The convention is
-                        that all SAVE_EXPRs that need to be reset
-                        have NULL_TREE for their SAVE_EXPR_CONTEXT.  */
-                     tree cfd = current_function_decl;
-                     if (decl_context == PARM)
-                       current_function_decl = NULL_TREE;
-                     itype = variable_size (itype);
-                     if (decl_context == PARM)
-                       current_function_decl = cfd;
-                   }
+                   itype = variable_size (itype);
                  itype = build_index_type (itype);
                }
            }
@@ -6065,25 +6052,6 @@ store_parm_decls_oldstyle (tree fndecl, tree arg_info)
     }
 }
 
-/* A subroutine of store_parm_decls called via walk_tree.  Mark all
-   decls non-local.  */
-
-static tree
-set_decl_nonlocal (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
-{
-  tree t = *tp;
-
-  if (DECL_P (t))
-    {
-      DECL_NONLOCAL (t) = 1;
-      *walk_subtrees = 0;
-    }
-  else if (TYPE_P (t))
-    *walk_subtrees = 0;
-
-  return NULL;
-}
-
 /* Store the parameter declarations into the current function declaration.
    This is called after parsing the parameter declarations, before
    digesting the body of the function.
@@ -6096,9 +6064,6 @@ store_parm_decls (void)
 {
   tree fndecl = current_function_decl;
 
-  /* The function containing FNDECL, if any.  */
-  tree context = decl_function_context (fndecl);
-
   /* The argument information block for FNDECL.  */
   tree arg_info = DECL_ARGUMENTS (fndecl);
 
@@ -6129,27 +6094,14 @@ store_parm_decls (void)
   /* Begin the statement tree for this function.  */
   DECL_SAVED_TREE (fndecl) = push_stmt_list ();
 
-  /* If this is a nested function, save away the sizes of any
-     variable-size types so that we can expand them when generating
-     RTL.  */
-  if (context)
-    {
-      tree t;
-
-      DECL_LANG_SPECIFIC (fndecl)->pending_sizes
-       = nreverse (get_pending_sizes ());
-      for (t = DECL_LANG_SPECIFIC (fndecl)->pending_sizes;
-          t;
-          t = TREE_CHAIN (t))
-       {
-         /* We will have a nonlocal use of whatever variables are
-            buried inside here.  */
-         walk_tree (&TREE_OPERAND (TREE_VALUE (t), 0),
-                    set_decl_nonlocal, NULL, NULL);
-
-         SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = context;
-       }
-    }
+  /* ??? Insert the contents of the pending sizes list into the function
+     to be evaluated.  This just changes mis-behaviour until assign_parms
+     phase ordering problems are resolved.  */
+  {
+    tree t;
+    for (t = nreverse (get_pending_sizes ()); t ; t = TREE_CHAIN (t))
+      add_stmt (TREE_VALUE (t));
+  }
 
   /* Even though we're inside a function body, we still don't want to
      call expand_expr to calculate the size of a variable-sized array.
index 11d8b26..328488e 100644 (file)
@@ -117,9 +117,6 @@ static sbitmap stored_args_map;
    argument list for the constructor call.  */
 int stack_arg_under_construction;
 
-static int calls_function (tree, int);
-static int calls_function_1 (tree, int);
-
 static void emit_call_1 (rtx, tree, tree, tree, HOST_WIDE_INT, HOST_WIDE_INT,
                         HOST_WIDE_INT, rtx, rtx, int, rtx, int,
                         CUMULATIVE_ARGS *);
@@ -155,123 +152,6 @@ static rtx save_fixed_argument_area (int, rtx, int *, int *);
 static void restore_fixed_argument_area (rtx, rtx, int, int);
 #endif
 \f
-/* If WHICH is 1, return 1 if EXP contains a call to the built-in function
-   `alloca'.
-
-   If WHICH is 0, return 1 if EXP contains a call to any function.
-   Actually, we only need return 1 if evaluating EXP would require pushing
-   arguments on the stack, but that is too difficult to compute, so we just
-   assume any function call might require the stack.  */
-
-static tree calls_function_save_exprs;
-
-static int
-calls_function (tree exp, int which)
-{
-  int val;
-
-  calls_function_save_exprs = 0;
-  val = calls_function_1 (exp, which);
-  calls_function_save_exprs = 0;
-  return val;
-}
-
-/* Recursive function to do the work of above function.  */
-
-static int
-calls_function_1 (tree exp, int which)
-{
-  int i;
-  enum tree_code code = TREE_CODE (exp);
-  int class = TREE_CODE_CLASS (code);
-  int length = first_rtl_op (code);
-
-  /* If this code is language-specific, we don't know what it will do.  */
-  if ((int) code >= NUM_TREE_CODES)
-    return 1;
-
-  switch (code)
-    {
-    case CALL_EXPR:
-      if (which == 0)
-       return 1;
-      else if ((TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))
-               == FUNCTION_TYPE)
-              && (TYPE_RETURNS_STACK_DEPRESSED
-                  (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))))
-       return 1;
-      else if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
-              && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
-                  == FUNCTION_DECL)
-              && (special_function_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
-                                      0)
-                  & ECF_MAY_BE_ALLOCA))
-       return 1;
-
-      break;
-
-    case CONSTRUCTOR:
-      {
-       tree tem;
-
-       for (tem = CONSTRUCTOR_ELTS (exp); tem != 0; tem = TREE_CHAIN (tem))
-         if (calls_function_1 (TREE_VALUE (tem), which))
-           return 1;
-      }
-
-      return 0;
-
-    case SAVE_EXPR:
-      if (SAVE_EXPR_RTL (exp) != 0)
-       return 0;
-      if (value_member (exp, calls_function_save_exprs))
-       return 0;
-      calls_function_save_exprs = tree_cons (NULL_TREE, exp,
-                                            calls_function_save_exprs);
-      return (TREE_OPERAND (exp, 0) != 0
-             && calls_function_1 (TREE_OPERAND (exp, 0), which));
-
-    case BLOCK:
-      {
-       tree local;
-       tree subblock;
-
-       for (local = BLOCK_VARS (exp); local; local = TREE_CHAIN (local))
-         if (DECL_INITIAL (local) != 0
-             && calls_function_1 (DECL_INITIAL (local), which))
-           return 1;
-
-       for (subblock = BLOCK_SUBBLOCKS (exp);
-            subblock;
-            subblock = TREE_CHAIN (subblock))
-         if (calls_function_1 (subblock, which))
-           return 1;
-      }
-      return 0;
-
-    case TREE_LIST:
-      for (; exp != 0; exp = TREE_CHAIN (exp))
-       if (calls_function_1 (TREE_VALUE (exp), which))
-         return 1;
-      return 0;
-
-    default:
-      break;
-    }
-
-  /* Only expressions and blocks can contain calls.
-     Blocks were handled above.  */
-  if (! IS_EXPR_CODE_CLASS (class))
-    return 0;
-
-  for (i = 0; i < length; i++)
-    if (TREE_OPERAND (exp, i) != 0
-       && calls_function_1 (TREE_OPERAND (exp, i), which))
-      return 1;
-
-  return 0;
-}
-\f
 /* Force FUNEXP into a form suitable for the address of a CALL,
    and return that as an rtx.  Also load the static chain register
    if FNDECL is a nested function.
@@ -1372,58 +1252,50 @@ precompute_arguments (int flags, int num_actuals, struct arg_data *args)
   int i;
 
   /* If this is a libcall, then precompute all arguments so that we do not
-     get extraneous instructions emitted as part of the libcall sequence.
-
-     If this target defines ACCUMULATE_OUTGOING_ARGS to true, then we must
-     precompute all arguments that contain function calls.  Otherwise,
-     computing arguments for a subcall may clobber arguments for this call.
-
-     If this target defines ACCUMULATE_OUTGOING_ARGS to false, then we only
-     need to precompute arguments that change the stack pointer, such as calls
-     to alloca, and calls that do not pop all of their arguments.  */
-
+     get extraneous instructions emitted as part of the libcall sequence.  */
+  if ((flags & ECF_LIBCALL_BLOCK) == 0)
+    return;
+    
   for (i = 0; i < num_actuals; i++)
-    if ((flags & ECF_LIBCALL_BLOCK)
-       || calls_function (args[i].tree_value, !ACCUMULATE_OUTGOING_ARGS))
-      {
-       enum machine_mode mode;
+    {
+      enum machine_mode mode;
 
-       /* If this is an addressable type, we cannot pre-evaluate it.  */
-       if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))
-         abort ();
+      /* If this is an addressable type, we cannot pre-evaluate it.  */
+      if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))
+       abort ();
 
-       args[i].value
-         = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0);
+      args[i].value
+       = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0);
 
-       /* ANSI doesn't require a sequence point here,
-          but PCC has one, so this will avoid some problems.  */
-       emit_queue ();
+      /* ANSI doesn't require a sequence point here,
+        but PCC has one, so this will avoid some problems.  */
+      emit_queue ();
 
-       args[i].initial_value = args[i].value
-         = protect_from_queue (args[i].value, 0);
+      args[i].initial_value = args[i].value
+       = protect_from_queue (args[i].value, 0);
 
-       mode = TYPE_MODE (TREE_TYPE (args[i].tree_value));
-       if (mode != args[i].mode)
-         {
-           args[i].value
-             = convert_modes (args[i].mode, mode,
-                              args[i].value, args[i].unsignedp);
+      mode = TYPE_MODE (TREE_TYPE (args[i].tree_value));
+      if (mode != args[i].mode)
+       {
+         args[i].value
+           = convert_modes (args[i].mode, mode,
+                            args[i].value, args[i].unsignedp);
 #if defined(PROMOTE_FUNCTION_MODE) && !defined(PROMOTE_MODE)
-           /* CSE will replace this only if it contains args[i].value
-              pseudo, so convert it down to the declared mode using
-              a SUBREG.  */
-           if (REG_P (args[i].value)
-               && GET_MODE_CLASS (args[i].mode) == MODE_INT)
-             {
-               args[i].initial_value
-                 = gen_lowpart_SUBREG (mode, args[i].value);
-               SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1;
-               SUBREG_PROMOTED_UNSIGNED_SET (args[i].initial_value,
-                 args[i].unsignedp);
-             }
+         /* CSE will replace this only if it contains args[i].value
+            pseudo, so convert it down to the declared mode using
+            a SUBREG.  */
+         if (REG_P (args[i].value)
+             && GET_MODE_CLASS (args[i].mode) == MODE_INT)
+           {
+             args[i].initial_value
+               = gen_lowpart_SUBREG (mode, args[i].value);
+             SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1;
+             SUBREG_PROMOTED_UNSIGNED_SET (args[i].initial_value,
+                                           args[i].unsignedp);
+           }
 #endif
-         }
-      }
+       }
+    }
 }
 
 /* Given the current state of MUST_PREALLOCATE and information about
index 05b3bc8..01b58a1 100644 (file)
@@ -360,26 +360,6 @@ construct_exit_block (void)
   update_bb_for_insn (exit_block);
 }
 
-/* Called to move the SAVE_EXPRs for parameter declarations in a
-   nested function into the nested function.  DATA is really the
-   nested FUNCTION_DECL.  */
-
-static tree
-set_save_expr_context (tree *tp,
-                       int *walk_subtrees,
-                       void *data)
-{
-  if (TREE_CODE (*tp) == SAVE_EXPR && !SAVE_EXPR_CONTEXT (*tp))
-    SAVE_EXPR_CONTEXT (*tp) = (tree) data;
-  /* Do not walk back into the SAVE_EXPR_CONTEXT; that will cause
-     circularity.  */
-  else if (DECL_P (*tp))
-    *walk_subtrees = 0;
-
-  return NULL;
-}
-
-
 /* Translate the intermediate representation contained in the CFG
    from GIMPLE trees to RTL.
 
@@ -403,15 +383,6 @@ tree_expand_cfg (void)
               IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
     }
 
-  /* If the function has a variably modified type, there may be
-     SAVE_EXPRs in the parameter types.  Their context must be set to
-     refer to this function; they cannot be expanded in the containing
-     function.  */
-  if (decl_function_context (current_function_decl) == current_function_decl
-      && variably_modified_type_p (TREE_TYPE (current_function_decl)))
-    walk_tree (&TREE_TYPE (current_function_decl), set_save_expr_context,
-              current_function_decl, NULL);
-
   /* Prepare the rtl middle end to start recording block changes.  */
   reset_block_changes ();
 
index 8e21875..dbd0ac7 100644 (file)
@@ -1,3 +1,7 @@
+2004-07-02  Richard Henderson  <rth@redhat.com>
+
+       * tree.c (cp_unsave_r): Update remap_save_expr call.
+
 2004-07-02  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/16240
index fb08095..deee9dc 100644 (file)
@@ -2256,7 +2256,7 @@ cp_unsave_r (tree* tp,
        *tp = (tree) n->value;
     }
   else if (TREE_CODE (*tp) == SAVE_EXPR)
-    remap_save_expr (tp, st, current_function_decl, walk_subtrees);
+    remap_save_expr (tp, st, walk_subtrees);
   else
     {
       copy_tree_r (tp, walk_subtrees, NULL);
index 2e3d55e..2fb962c 100644 (file)
@@ -10249,53 +10249,6 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b
       break;
 
     case SAVE_EXPR:
-      /* If optimization is turned on, the SAVE_EXPRs that describe how to
-        access the upper bound values may be bogus.  If they refer to a
-        register, they may only describe how to get at these values at the
-        points in the generated code right after they have just been
-        computed.  Worse yet, in the typical case, the upper bound values
-        will not even *be* computed in the optimized code (though the
-        number of elements will), so these SAVE_EXPRs are entirely
-        bogus. In order to compensate for this fact, we check here to see
-        if optimization is enabled, and if so, we don't add an attribute
-        for the (unknown and unknowable) upper bound.  This should not
-        cause too much trouble for existing (stupid?)  debuggers because
-        they have to deal with empty upper bounds location descriptions
-        anyway in order to be able to deal with incomplete array types.
-        Of course an intelligent debugger (GDB?)  should be able to
-        comprehend that a missing upper bound specification in an array
-        type used for a storage class `auto' local array variable
-        indicates that the upper bound is both unknown (at compile- time)
-        and unknowable (at run-time) due to optimization.
-
-        We assume that a MEM rtx is safe because gcc wouldn't put the
-        value there unless it was going to be used repeatedly in the
-        function, i.e. for cleanups.  */
-      if (SAVE_EXPR_RTL (bound)
-         && (! optimize || MEM_P (SAVE_EXPR_RTL (bound))))
-       {
-         dw_die_ref ctx = lookup_decl_die (current_function_decl);
-         dw_die_ref decl_die = new_die (DW_TAG_variable, ctx, bound);
-         rtx loc = SAVE_EXPR_RTL (bound);
-
-         /* If the RTL for the SAVE_EXPR is memory, handle the case where
-            it references an outer function's frame.  */
-         if (MEM_P (loc))
-           {
-             rtx new_addr = fix_lexical_addr (XEXP (loc, 0), bound);
-
-             if (XEXP (loc, 0) != new_addr)
-               loc = gen_rtx_MEM (GET_MODE (loc), new_addr);
-           }
-
-         add_AT_flag (decl_die, DW_AT_artificial, 1);
-         add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx);
-         add_AT_location_description (decl_die, DW_AT_location,
-                                      loc_descriptor (loc, true));
-         add_AT_die_ref (subrange_die, bound_attr, decl_die);
-       }
-
-      /* Else leave out the attribute.  */
       break;
 
     case VAR_DECL:
@@ -10331,15 +10284,6 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b
        else
          ctx = lookup_decl_die (current_function_decl);
 
-       /* If we weren't able to find a context, it's most likely the case
-          that we are processing the return type of the function.  So
-          make a SAVE_EXPR to point to it and have the limbo DIE code
-          find the proper die.  The save_expr function doesn't always
-          make a SAVE_EXPR, so do it ourselves.  */
-       if (ctx == 0)
-         bound = build (SAVE_EXPR, TREE_TYPE (bound), bound,
-                        current_function_decl, NULL_TREE);
-
        decl_die = new_die (DW_TAG_variable, ctx, bound);
        add_AT_flag (decl_die, DW_AT_artificial, 1);
        add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx);
@@ -13735,15 +13679,6 @@ dwarf2out_finish (const char *filename)
            add_child_die (origin->die_parent, die);
          else if (die == comp_unit_die)
            ;
-         /* If this was an expression for a bound involved in a function
-            return type, it may be a SAVE_EXPR for which we weren't able
-            to find a DIE previously.  So try now.  */
-         else if (node->created_for
-                  && TREE_CODE (node->created_for) == SAVE_EXPR
-                  && 0 != (origin = (lookup_decl_die
-                                     (SAVE_EXPR_CONTEXT
-                                      (node->created_for)))))
-           add_child_die (origin, die);
          else if (errorcount > 0 || sorrycount > 0)
            /* It's OK to be confused by errors in the input.  */
            add_child_die (comp_unit_die, die);
index df35422..d3951fe 100644 (file)
@@ -1349,11 +1349,6 @@ emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method)
 
   align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
 
-  if (GET_MODE (x) != BLKmode)
-    abort ();
-  if (GET_MODE (y) != BLKmode)
-    abort ();
-
   x = protect_from_queue (x, 1);
   y = protect_from_queue (y, 0);
   size = protect_from_queue (size, 0);
@@ -1365,6 +1360,11 @@ emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method)
   if (size == 0)
     abort ();
 
+  /* Make sure we've got BLKmode addresses; store_one_arg can decide that
+     block copy is more efficient for other large modes, e.g. DCmode.  */
+  x = adjust_address (x, BLKmode, 0);
+  y = adjust_address (y, BLKmode, 0);
+
   /* Set MEM_SIZE as appropriate for this block copy.  The main place this
      can be incorrect is coming from __builtin_memcpy.  */
   if (GET_CODE (size) == CONST_INT)
@@ -5090,14 +5090,6 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
                    = gen_reg_rtx (promote_mode (domain, DECL_MODE (index),
                                                 &unsignedp, 0));
                  SET_DECL_RTL (index, index_r);
-                 if (TREE_CODE (value) == SAVE_EXPR
-                     && SAVE_EXPR_RTL (value) == 0)
-                   {
-                     /* Make sure value gets expanded once before the
-                         loop.  */
-                     expand_expr (value, const0_rtx, VOIDmode, 0);
-                     emit_queue ();
-                   }
                  store_expr (lo_index, index_r, 0);
 
                  /* Build the head of the loop.  */
@@ -5986,7 +5978,6 @@ safe_from_p (rtx x, tree exp, int top_p)
 {
   rtx exp_rtl = 0;
   int i, nops;
-  static tree save_expr_list;
 
   if (x == 0
       /* If EXP has varying size, we MUST use a target since we currently
@@ -6018,30 +6009,6 @@ safe_from_p (rtx x, tree exp, int top_p)
        return 0;
     }
 
-  /* A SAVE_EXPR might appear many times in the expression passed to the
-     top-level safe_from_p call, and if it has a complex subexpression,
-     examining it multiple times could result in a combinatorial explosion.
-     E.g. on an Alpha running at least 200MHz, a Fortran testcase compiled
-     with optimization took about 28 minutes to compile -- even though it was
-     only a few lines long.  So we mark each SAVE_EXPR we see with TREE_PRIVATE
-     and turn that off when we are done.  We keep a list of the SAVE_EXPRs
-     we have processed.  Note that the only test of top_p was above.  */
-
-  if (top_p)
-    {
-      int rtn;
-      tree t;
-
-      save_expr_list = 0;
-
-      rtn = safe_from_p (x, exp, 0);
-
-      for (t = save_expr_list; t != 0; t = TREE_CHAIN (t))
-       TREE_PRIVATE (TREE_PURPOSE (t)) = 0;
-
-      return rtn;
-    }
-
   /* Now look at our tree code and possibly recurse.  */
   switch (TREE_CODE_CLASS (TREE_CODE (exp)))
     {
@@ -6139,28 +6106,8 @@ safe_from_p (rtx x, tree exp, int top_p)
          break;
 
        case CLEANUP_POINT_EXPR:
-         return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
-
        case SAVE_EXPR:
-         exp_rtl = SAVE_EXPR_RTL (exp);
-         if (exp_rtl)
-           break;
-
-         /* If we've already scanned this, don't do it again.  Otherwise,
-            show we've scanned it and record for clearing the flag if we're
-            going on.  */
-         if (TREE_PRIVATE (exp))
-           return 1;
-
-         TREE_PRIVATE (exp) = 1;
-         if (! safe_from_p (x, TREE_OPERAND (exp, 0), 0))
-           {
-             TREE_PRIVATE (exp) = 0;
-             return 0;
-           }
-
-         save_expr_list = tree_cons (exp, NULL_TREE, save_expr_list);
-         return 1;
+         return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
 
        case BIND_EXPR:
          /* The only operand we look at is operand 1.  The rest aren't
@@ -6841,88 +6788,30 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
       return temp;
 
     case SAVE_EXPR:
-      context = decl_function_context (exp);
-
-      /* If this SAVE_EXPR was at global context, assume we are an
-        initialization function and move it into our context.  */
-      if (context == 0)
-       SAVE_EXPR_CONTEXT (exp) = current_function_decl;
-
-      if (context == current_function_decl)
-       context = 0;
-
-      /* If this is non-local, handle it.  */
-      if (context)
-       {
-         /* The following call just exists to abort if the context is
-            not of a containing function.  */
-         find_function_data (context);
-
-         temp = SAVE_EXPR_RTL (exp);
-         if (temp && REG_P (temp))
-           {
-             put_var_into_stack (exp, /*rescan=*/true);
-             temp = SAVE_EXPR_RTL (exp);
-           }
-         if (temp == 0 || !MEM_P (temp))
-           abort ();
-         return
-           replace_equiv_address (temp,
-                                  fix_lexical_addr (XEXP (temp, 0), exp));
-       }
-      if (SAVE_EXPR_RTL (exp) == 0)
-       {
-         if (mode == VOIDmode)
-           temp = const0_rtx;
-         else
-           temp = assign_temp (build_qualified_type (type,
-                                                     (TYPE_QUALS (type)
-                                                      | TYPE_QUAL_CONST)),
-                               3, 0, 0);
-
-         SAVE_EXPR_RTL (exp) = temp;
-         if (!optimize && REG_P (temp))
-           save_expr_regs = gen_rtx_EXPR_LIST (VOIDmode, temp,
-                                               save_expr_regs);
-
-         /* If the mode of TEMP does not match that of the expression, it
-            must be a promoted value.  We pass store_expr a SUBREG of the
-            wanted mode but mark it so that we know that it was already
-            extended.  */
-
-         if (REG_P (temp) && GET_MODE (temp) != mode)
-           {
-             temp = gen_lowpart_SUBREG (mode, SAVE_EXPR_RTL (exp));
-             promote_mode (type, mode, &unsignedp, 0);
-             SUBREG_PROMOTED_VAR_P (temp) = 1;
-             SUBREG_PROMOTED_UNSIGNED_SET (temp, unsignedp);
-           }
-
-         if (temp == const0_rtx)
-           expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
-         else
-           store_expr (TREE_OPERAND (exp, 0), temp,
-                       modifier == EXPAND_STACK_PARM ? 2 : 0);
+      {
+       tree val = TREE_OPERAND (exp, 0);
+       rtx ret = expand_expr_real_1 (val, target, tmode, modifier, alt_rtl);
 
-         TREE_USED (exp) = 1;
-       }
+       if (TREE_CODE (val) != VAR_DECL || !DECL_ARTIFICIAL (val))
+         {
+           /* We can indeed still hit this case, typically via builtin
+              expanders calling save_expr immediately before expanding
+              something.  Assume this means that we only have to deal
+              with non-BLKmode values.  */
+           if (GET_MODE (ret) == BLKmode)
+             abort ();
 
-      /* If the mode of SAVE_EXPR_RTL does not match that of the expression, it
-        must be a promoted value.  We return a SUBREG of the wanted mode,
-        but mark it so that we know that it was already extended.  */
+           val = build_decl (VAR_DECL, NULL, TREE_TYPE (exp));
+           DECL_ARTIFICIAL (val) = 1;
+           TREE_OPERAND (exp, 0) = val;
 
-      if (REG_P (SAVE_EXPR_RTL (exp))
-         && GET_MODE (SAVE_EXPR_RTL (exp)) != mode)
-       {
-         /* Compute the signedness and make the proper SUBREG.  */
-         promote_mode (type, mode, &unsignedp, 0);
-         temp = gen_lowpart_SUBREG (mode, SAVE_EXPR_RTL (exp));
-         SUBREG_PROMOTED_VAR_P (temp) = 1;
-         SUBREG_PROMOTED_UNSIGNED_SET (temp, unsignedp);
-         return temp;
-       }
+           if (!CONSTANT_P (ret))
+             ret = copy_to_reg (ret);
+           SET_DECL_RTL (val, ret);
+         }
 
-      return SAVE_EXPR_RTL (exp);
+        return ret;
+      }
 
     case UNSAVE_EXPR:
       {
@@ -7301,25 +7190,13 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
                 && (offset != 0
                     || (code == ARRAY_RANGE_REF && mode == BLKmode)))
          {
-           /* If the operand is a SAVE_EXPR, we can deal with this by
-              forcing the SAVE_EXPR into memory.  */
-           if (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR)
-             {
-               put_var_into_stack (TREE_OPERAND (exp, 0),
-                                   /*rescan=*/true);
-               op0 = SAVE_EXPR_RTL (TREE_OPERAND (exp, 0));
-             }
-           else
-             {
-               tree nt
-                 = build_qualified_type (TREE_TYPE (tem),
-                                         (TYPE_QUALS (TREE_TYPE (tem))
-                                          | TYPE_QUAL_CONST));
-               rtx memloc = assign_temp (nt, 1, 1, 1);
+           tree nt = build_qualified_type (TREE_TYPE (tem),
+                                           (TYPE_QUALS (TREE_TYPE (tem))
+                                            | TYPE_QUAL_CONST));
+           rtx memloc = assign_temp (nt, 1, 1, 1);
 
-               emit_move_insn (memloc, op0);
-               op0 = memloc;
-             }
+           emit_move_insn (memloc, op0);
+           op0 = memloc;
          }
 
        if (offset != 0)
@@ -9045,31 +8922,20 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
                   || GET_CODE (op0) == CONCAT || GET_CODE (op0) == ADDRESSOF
                   || GET_CODE (op0) == PARALLEL || GET_CODE (op0) == LO_SUM)
            {
-             /* If the operand is a SAVE_EXPR, we can deal with this by
-                forcing the SAVE_EXPR into memory.  */
-             if (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR)
-               {
-                 put_var_into_stack (TREE_OPERAND (exp, 0),
-                                     /*rescan=*/true);
-                 op0 = SAVE_EXPR_RTL (TREE_OPERAND (exp, 0));
-               }
+             /* If this object is in a register, it can't be BLKmode.  */
+             tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
+             rtx memloc = assign_temp (inner_type, 1, 1, 1);
+
+             if (GET_CODE (op0) == PARALLEL)
+               /* Handle calls that pass values in multiple
+                  non-contiguous locations.  The Irix 6 ABI has examples
+                  of this.  */
+               emit_group_store (memloc, op0, inner_type,
+                                 int_size_in_bytes (inner_type));
              else
-               {
-                 /* If this object is in a register, it can't be BLKmode.  */
-                 tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
-                 rtx memloc = assign_temp (inner_type, 1, 1, 1);
-
-                 if (GET_CODE (op0) == PARALLEL)
-                   /* Handle calls that pass values in multiple
-                      non-contiguous locations.  The Irix 6 ABI has examples
-                      of this.  */
-                   emit_group_store (memloc, op0, inner_type,
-                                     int_size_in_bytes (inner_type));
-                 else
-                   emit_move_insn (memloc, op0);
+               emit_move_insn (memloc, op0);
 
-                 op0 = memloc;
-               }
+             op0 = memloc;
            }
 
          if (!MEM_P (op0))
index f8408c4..bfd1798 100644 (file)
@@ -2661,7 +2661,7 @@ twoval_comparison_p (tree arg, tree *cval1, tree *cval2, int *save_p)
               || code == COMPOUND_EXPR))
     class = '2';
 
-  else if (class == 'e' && code == SAVE_EXPR && SAVE_EXPR_RTL (arg) == 0
+  else if (class == 'e' && code == SAVE_EXPR
           && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
     {
       /* If we've already found a CVAL1 or CVAL2, this expression is
@@ -5971,10 +5971,6 @@ fold (tree expr)
      if all operands are constant.  */
   int wins = 1;
 
-  /* Don't try to process an SAVE_EXPR that's already been evaluated.  */
-  if (code == SAVE_EXPR && SAVE_EXPR_RTL (t) != 0)
-    return t;
-
   /* Return right away if a constant.  */
   if (kind == 'c')
     return t;
@@ -8985,14 +8981,7 @@ fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht)
     return;
   *slot = expr;
   code = TREE_CODE (expr);
-  if (code == SAVE_EXPR && SAVE_EXPR_NOPLACEHOLDER (expr))
-    {
-      /* Allow SAVE_EXPR_NOPLACEHOLDER flag to be modified.  */
-      memcpy (buf, expr, tree_size (expr));
-      expr = (tree) buf;
-      SAVE_EXPR_NOPLACEHOLDER (expr) = 0;
-    }
-  else if (TREE_CODE_CLASS (code) == 'd' && DECL_ASSEMBLER_NAME_SET_P (expr))
+  if (TREE_CODE_CLASS (code) == 'd' && DECL_ASSEMBLER_NAME_SET_P (expr))
     {
       /* Allow DECL_ASSEMBLER_NAME to be modified.  */
       memcpy (buf, expr, tree_size (expr));
@@ -9051,7 +9040,6 @@ fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht)
     case 'e':
       switch (code)
        {
-       case SAVE_EXPR: len = 2; break;
        case GOTO_SUBROUTINE_EXPR: len = 0; break;
        case WITH_CLEANUP_EXPR: len = 2; break;
        default: break;
index 1d17c4f..b6d3789 100644 (file)
@@ -436,7 +436,6 @@ free_after_compilation (struct function *f)
   f->x_nonlocal_goto_handler_labels = NULL;
   f->x_return_label = NULL;
   f->x_naked_return_label = NULL;
-  f->x_save_expr_regs = NULL;
   f->x_stack_slot_list = NULL;
   f->x_tail_recursion_reentry = NULL;
   f->x_arg_pointer_save_area = NULL;
@@ -1305,9 +1304,7 @@ put_var_into_stack (tree decl, int rescan)
   context = decl_function_context (decl);
 
   /* Get the current rtl used for this object and its original mode.  */
- orig_reg = reg = (TREE_CODE (decl) == SAVE_EXPR
-                  ? SAVE_EXPR_RTL (decl)
-                  : DECL_RTL_IF_SET (decl));
+  orig_reg = reg = DECL_RTL_IF_SET (decl);
 
   /* No need to do anything if decl has no rtx yet
      since in that case caller is setting TREE_ADDRESSABLE
@@ -2824,10 +2821,8 @@ gen_mem_addressof (rtx reg, tree decl, int rescan)
   if (decl)
     {
       tree type = TREE_TYPE (decl);
-      enum machine_mode decl_mode
-       = (DECL_P (decl) ? DECL_MODE (decl) : TYPE_MODE (TREE_TYPE (decl)));
-      rtx decl_rtl = (TREE_CODE (decl) == SAVE_EXPR ? SAVE_EXPR_RTL (decl)
-                     : DECL_RTL_IF_SET (decl));
+      enum machine_mode decl_mode = DECL_MODE (decl);
+      rtx decl_rtl = DECL_RTL_IF_SET (decl);
 
       PUT_MODE (reg, decl_mode);
 
index 7043d0b..4a05762 100644 (file)
@@ -243,10 +243,6 @@ struct function GTY(())
      on machines which require execution of the epilogue on all returns.  */
   rtx x_naked_return_label;
 
-  /* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.
-     So we can mark them all live at the end of the function, if nonopt.  */
-  rtx x_save_expr_regs;
-
   /* List (chain of EXPR_LISTs) of all stack slots in this function.
      Made for the sake of unshare_all_rtl.  */
   rtx x_stack_slot_list;
@@ -506,7 +502,6 @@ extern int trampolines_created;
 #define parm_reg_stack_loc (cfun->x_parm_reg_stack_loc)
 #define return_label (cfun->x_return_label)
 #define naked_return_label (cfun->x_naked_return_label)
-#define save_expr_regs (cfun->x_save_expr_regs)
 #define stack_slot_list (cfun->x_stack_slot_list)
 #define parm_birth_insn (cfun->x_parm_birth_insn)
 #define frame_offset (cfun->x_frame_offset)
index 99b7990..55a26de 100644 (file)
@@ -650,7 +650,6 @@ adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
     int first_rtl;
     int num_rtl;
   } data[] = {
-    { "SAVE_EXPR", 2, 1 },
     { "GOTO_SUBROUTINE_EXPR", 0, 2 },
     { "WITH_CLEANUP_EXPR", 2, 1 },
   };
index 135423a..efa1c0c 100644 (file)
@@ -1,3 +1,7 @@
+2004-07-02  Richard Henderson  <rth@redhat.com>
+
+       * jcf-write.c (generate_bytecode_insns <case SAVE_EXPR>): Rewrite.
+
 2004-07-01  Richard Henderson  <rth@redhat.com>
 
        * class.c (registerClass_libfunc): Remove.
index 42136c6..09b39da 100644 (file)
@@ -2197,35 +2197,24 @@ generate_bytecode_insns (tree exp, int target, struct jcf_partial *state)
       }
       break;
     case SAVE_EXPR:
-      /* Because the state associated with a SAVE_EXPR tree node must
-        be a RTL expression, we use it to store the DECL_LOCAL_INDEX
-        of a temporary variable in a CONST_INT.  */
-      if (! SAVE_EXPR_RTL (exp))
+      /* The first time through, the argument of the SAVE_EXPR will be
+        something complex.  Evaluate it, and replace the argument with
+        a VAR_DECL that holds the result.  */
+      arg = TREE_OPERAND (exp, 0);
+      if (TREE_CODE (arg) != VAR_DECL || DECL_NAME (arg))
        {
          tree type = TREE_TYPE (exp);
          tree decl = build_decl (VAR_DECL, NULL_TREE, type);
-         generate_bytecode_insns (TREE_OPERAND (exp, 0),
-                                  STACK_TARGET, state);
+         generate_bytecode_insns (arg, STACK_TARGET, state);
          localvar_alloc (decl, state);
-         SAVE_EXPR_RTL (exp) = GEN_INT (DECL_LOCAL_INDEX (decl));
+         TREE_OPERAND (exp, 0) = decl;
          emit_dup (TYPE_IS_WIDE (type) ? 2 : 1, 0, state);
          emit_store (decl, state);
        }
       else
        {
-         /* The following code avoids creating a temporary DECL just
-            to pass to emit_load.  This code could be factored with
-            the similar implementation in emit_load_or_store.  */
          tree type = TREE_TYPE (exp);
-         int kind = adjust_typed_op (type, 4);
-         int index = (int) INTVAL (SAVE_EXPR_RTL (exp));
-         if (index <= 3)
-           {
-             RESERVE (1);  /* [ilfda]load_[0123]  */
-             OP1 (OPCODE_iload + 5 + 4*kind + index);
-           }
-         else  /* [ilfda]load  */
-           maybe_wide (OPCODE_iload + kind, index, state);
+         emit_load (arg, state);
          NOTE_PUSH (TYPE_IS_WIDE (type) ? 2 : 1);
        }
       break;
index 055f8f3..3208797 100644 (file)
@@ -578,8 +578,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
     case 's':
       if (TREE_CODE (node) == BIT_FIELD_REF && BIT_FIELD_REF_UNSIGNED (node))
        fputs (" unsigned", file);
-      else if (TREE_CODE (node) == SAVE_EXPR && SAVE_EXPR_NOPLACEHOLDER (node))
-       fputs (" noplaceholder", file);
       if (TREE_CODE (node) == BIND_EXPR)
        {
          print_node (file, "vars", TREE_OPERAND (node, 0), indent + 4);
index 94bc46f..cf97159 100644 (file)
@@ -66,7 +66,6 @@ static void place_union_field (record_layout_info, tree);
 static int excess_unit_span (HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT,
                             HOST_WIDE_INT, tree);
 #endif
-static void force_type_save_exprs_1 (tree);
 extern void debug_rli (record_layout_info);
 \f
 /* SAVE_EXPRs for sizes of types and decls, waiting to be expanded.  */
@@ -146,8 +145,6 @@ variable_size (tree size)
      not wish to do that here; the array-size is the same in both
      places.  */
   save = skip_simple_arithmetic (size);
-  if (TREE_CODE (save) == SAVE_EXPR)
-    SAVE_EXPR_PERSISTENT_P (save) = 1;
 
   if (cfun && cfun->x_dont_save_pending_sizes_p)
     /* The front-end doesn't want us to keep a list of the expressions
@@ -168,60 +165,6 @@ variable_size (tree size)
 
   return size;
 }
-
-/* Given a type T, force elaboration of any SAVE_EXPRs used in the definition
-   of that type.  */
-
-void
-force_type_save_exprs (tree t)
-{
-  tree field;
-
-  switch (TREE_CODE (t))
-    {
-    case ERROR_MARK:
-      return;
-
-    case ARRAY_TYPE:
-    case SET_TYPE:
-    case VECTOR_TYPE:
-      /* It's probably overly-conservative to force elaboration of bounds and
-        also the sizes, but it's better to be safe than sorry.  */
-      force_type_save_exprs_1 (TYPE_MIN_VALUE (TYPE_DOMAIN (t)));
-      force_type_save_exprs_1 (TYPE_MAX_VALUE (TYPE_DOMAIN (t)));
-      break;
-
-    case RECORD_TYPE:
-    case UNION_TYPE:
-    case QUAL_UNION_TYPE:
-      for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
-       if (TREE_CODE (field) == FIELD_DECL)
-         {
-           force_type_save_exprs (TREE_TYPE (field));
-           force_type_save_exprs_1 (DECL_FIELD_OFFSET (field));
-         }
-      break;
-
-    default:
-      break;
-    }
-
-  force_type_save_exprs_1 (TYPE_SIZE (t));
-  force_type_save_exprs_1 (TYPE_SIZE_UNIT (t));
-}
-
-/* Utility routine of above, to verify that SIZE has been elaborated and
-   do so it it is a SAVE_EXPR and has not been.  */
-
-static void
-force_type_save_exprs_1 (tree size)
-{
-  if (size
-      && (size = skip_simple_arithmetic (size))
-      && TREE_CODE (size) == SAVE_EXPR
-      && !SAVE_EXPR_RTL (size))
-    expand_expr (size, NULL_RTX, VOIDmode, 0);
-}
 \f
 #ifndef MAX_FIXED_MODE_SIZE
 #define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode)
index aa579c3..d2d0fd4 100644 (file)
@@ -528,8 +528,7 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
   else if (TREE_CODE (*tp) == STATEMENT_LIST)
     copy_statement_list (tp);
   else if (TREE_CODE (*tp) == SAVE_EXPR)
-    remap_save_expr (tp, id->decl_map, VARRAY_TREE (id->fns, 0),
-                    walk_subtrees);
+    remap_save_expr (tp, id->decl_map, walk_subtrees);
   else if (TREE_CODE (*tp) == UNSAVE_EXPR)
     /* UNSAVE_EXPRs should not be generated until expansion time.  */
     abort ();
@@ -2318,11 +2317,10 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
 
 /* The SAVE_EXPR pointed to by TP is being copied.  If ST contains
    information indicating to what new SAVE_EXPR this one should be mapped,
-   use that one.  Otherwise, create a new node and enter it in ST.  FN is the
-   function into which the copy will be placed.  */
+   use that one.  Otherwise, create a new node and enter it in ST.  */
 
 void
-remap_save_expr (tree *tp, void *st_, tree fn, int *walk_subtrees)
+remap_save_expr (tree *tp, void *st_, int *walk_subtrees)
 {
   splay_tree st = (splay_tree) st_;
   splay_tree_node n;
@@ -2336,11 +2334,6 @@ remap_save_expr (tree *tp, void *st_, tree fn, int *walk_subtrees)
     {
       t = copy_node (*tp);
 
-      /* The SAVE_EXPR is now part of the function into which we
-        are inlining this body.  */
-      SAVE_EXPR_CONTEXT (t) = fn;
-      /* And we haven't evaluated it yet.  */
-      SAVE_EXPR_RTL (t) = NULL_RTX;
       /* Remember this SAVE_EXPR.  */
       splay_tree_insert (st, (splay_tree_key) *tp, (splay_tree_value) t);
       /* Make sure we don't remap an already-remapped SAVE_EXPR.  */
@@ -2412,7 +2405,7 @@ unsave_r (tree *tp, int *walk_subtrees, void *data)
   else if (TREE_CODE (*tp) == BIND_EXPR)
     copy_bind_expr (tp, walk_subtrees, id);
   else if (TREE_CODE (*tp) == SAVE_EXPR)
-    remap_save_expr (tp, st, current_function_decl, walk_subtrees);
+    remap_save_expr (tp, st, walk_subtrees);
   else
     {
       copy_tree_r (tp, walk_subtrees, NULL);
index 142f556..4619e31 100644 (file)
@@ -29,7 +29,7 @@ bool tree_inlinable_function_p (tree);
 tree copy_tree_r (tree*, int*, void*);
 void clone_body (tree, tree, void*);
 tree save_body (tree, tree *);
-void remap_save_expr (tree*, void*, tree, int*);
+void remap_save_expr (tree*, void*, int*);
 int estimate_num_insns (tree expr);
 
 /* 0 if we should not perform inlining.
index 38e94ef..bc6d3ae 100644 (file)
@@ -1375,8 +1375,7 @@ save_expr (tree expr)
   if (contains_placeholder_p (inner))
     return t;
 
-  t = build3 (SAVE_EXPR, TREE_TYPE (expr), t, current_function_decl,
-             NULL_TREE);
+  t = build1 (SAVE_EXPR, TREE_TYPE (expr), t);
 
   /* This expression might be placed ahead of a jump to ensure that the
      value was computed on both sides of the jump.  So make sure it isn't
@@ -1451,8 +1450,6 @@ first_rtl_op (enum tree_code code)
 {
   switch (code)
     {
-    case SAVE_EXPR:
-      return 2;
     case GOTO_SUBROUTINE_EXPR:
       return 0;
     case WITH_CLEANUP_EXPR:
@@ -1511,11 +1508,6 @@ unsave_expr_1 (tree expr)
 {
   switch (TREE_CODE (expr))
     {
-    case SAVE_EXPR:
-      if (! SAVE_EXPR_PERSISTENT_P (expr))
-       SAVE_EXPR_RTL (expr) = 0;
-      break;
-
     case TARGET_EXPR:
       /* Don't mess with a TARGET_EXPR that hasn't been expanded.
          It's OK for this to happen if it was part of a subtree that
@@ -1640,7 +1632,6 @@ bool
 contains_placeholder_p (tree exp)
 {
   enum tree_code code;
-  int result;
 
   if (!exp)
     return 0;
@@ -1678,19 +1669,6 @@ contains_placeholder_p (tree exp)
                  || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1))
                  || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 2)));
 
-       case SAVE_EXPR:
-         /* If we already know this doesn't have a placeholder, don't
-            check again.  */
-         if (SAVE_EXPR_NOPLACEHOLDER (exp) || SAVE_EXPR_RTL (exp) != 0)
-           return 0;
-
-         SAVE_EXPR_NOPLACEHOLDER (exp) = 1;
-         result = CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
-         if (result)
-           SAVE_EXPR_NOPLACEHOLDER (exp) = 0;
-
-         return result;
-
        default:
          break;
        }
@@ -4781,9 +4759,6 @@ decl_function_context (tree decl)
   if (TREE_CODE (decl) == ERROR_MARK)
     return 0;
 
-  if (TREE_CODE (decl) == SAVE_EXPR)
-    context = SAVE_EXPR_CONTEXT (decl);
-
   /* C++ virtual functions use DECL_CONTEXT for the class of the vtable
      where we look up the function at runtime.  Such functions always take
      a first argument of type 'pointer to real context'.
index bf80871..bb49981 100644 (file)
@@ -723,10 +723,9 @@ DEFTREECODE (NON_LVALUE_EXPR, "non_lvalue_expr", '1', 1)
 DEFTREECODE (VIEW_CONVERT_EXPR, "view_convert_expr", '1', 1)
 
 /* Represents something we computed once and will use multiple times.
-   First operand is that expression.  Second is the function decl
-   in which the SAVE_EXPR was created.  The third operand is the RTL,
-   nonzero only after the expression has been computed.  */
-DEFTREECODE (SAVE_EXPR, "save_expr", 'e', 3)
+   First operand is that expression.  After it is evaluated once, it
+   will be replaced by the temporary variable that holds the value.  */
+DEFTREECODE (SAVE_EXPR, "save_expr", 'e', 1)
 
 /* For a UNSAVE_EXPR, operand 0 is the value to unsave.  By unsave, we
    mean that all _EXPRs such as TARGET_EXPRs, SAVE_EXPRs, CALL_EXPRs,
index b91ac6c..eff9068 100644 (file)
@@ -282,8 +282,6 @@ struct tree_common GTY(())
            all decls
        BIT_FIELD_REF_UNSIGNED in
            BIT_FIELD_REF
-       SAVE_EXPR_NOPLACEHOLDER in
-          SAVE_EXPR
 
    asm_written_flag:
 
@@ -1030,19 +1028,6 @@ struct tree_vec GTY(())
                                 && VOID_TYPE_P (TREE_TYPE (NODE)) \
                                 && integer_zerop (TREE_OPERAND (NODE, 0)))
 
-/* In a SAVE_EXPR node.  */
-#define SAVE_EXPR_CONTEXT(NODE) TREE_OPERAND_CHECK_CODE (NODE, SAVE_EXPR, 1)
-#define SAVE_EXPR_RTL(NODE) TREE_RTL_OPERAND_CHECK (NODE, SAVE_EXPR, 2)
-
-#define SAVE_EXPR_NOPLACEHOLDER(NODE) \
-  (SAVE_EXPR_CHECK (NODE)->common.unsigned_flag)
-
-/* Nonzero if the SAVE_EXPRs value should be kept, even if it occurs
-   both in normal code and in a handler.  (Normally, in a handler, all
-   SAVE_EXPRs are unsaved, meaning that their values are
-   recalculated.)  */
-#define SAVE_EXPR_PERSISTENT_P(NODE) TREE_ASM_WRITTEN (SAVE_EXPR_CHECK (NODE))
-
 /* In a WITH_CLEANUP_EXPR node.  */
 #define WITH_CLEANUP_EXPR_RTL(NODE) \
   TREE_RTL_OPERAND_CHECK (NODE, WITH_CLEANUP_EXPR, 2)
@@ -3210,11 +3195,6 @@ extern tree substitute_placeholder_in_expr (tree, tree);
 
 extern tree variable_size (tree);
 
-/* Given a type T, force elaboration of any SAVE_EXPRs used in the definition
-   of that type.  */
-
-extern void force_type_save_exprs (tree);
-
 /* stabilize_reference (EXP) returns a reference equivalent to EXP
    but it can be used multiple times
    and only evaluate the subexpressions once.  */