OSDN Git Service

* builtins.c (std_expand_builtin_va_arg): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / stmt.c
index affeb9d..d63dad5 100644 (file)
@@ -164,33 +164,10 @@ struct nesting GTY(())
          /* Sequence number of this binding contour within the function,
             in order of entry.  */
          int block_start_count;
-         /* Nonzero => value to restore stack to on exit.  */
-         rtx stack_level;
          /* The NOTE that starts this contour.
             Used by expand_goto to check whether the destination
             is within each contour or not.  */
          rtx first_insn;
-         /* Innermost containing binding contour that has a stack level.  */
-         struct nesting *innermost_stack_block;
-         /* List of cleanups to be run on exit from this contour.
-            This is a list of expressions to be evaluated.
-            The TREE_PURPOSE of each link is the ..._DECL node
-            which the cleanup pertains to.  */
-         tree cleanups;
-         /* List of cleanup-lists of blocks containing this block,
-            as they were at the locus where this block appears.
-            There is an element for each containing block,
-            ordered innermost containing block first.
-            The tail of this list can be 0,
-            if all remaining elements would be empty lists.
-            The element's TREE_VALUE is the cleanup-list of that block,
-            which may be null.  */
-         tree outer_cleanups;
-         /* Chain of labels defined inside this binding contour.
-            For contours that have stack levels or cleanups.  */
-         struct label_chain *label_chain;
-         /* Nonzero if this is associated with an EH region.  */
-         int exception_region;
          /* The saved target_temp_slot_level from our outer block.
             We may reset target_temp_slot_level to be the level of
             this block, if that is done, target_temp_slot_level
@@ -251,8 +228,6 @@ do { struct nesting *target = STACK;                        \
            cond_stack = cond_stack->next;              \
          if (block_stack == this)                      \
            block_stack = block_stack->next;            \
-         if (stack_block_stack == this)                \
-           stack_block_stack = stack_block_stack->next; \
          if (case_stack == this)                       \
            case_stack = case_stack->next;              \
          nesting_depth = nesting_stack->depth - 1;     \
@@ -284,28 +259,6 @@ struct goto_fixup GTY(())
   /* Number of binding contours started in current function
      before the label reference.  */
   int block_start_count;
-  /* The outermost stack level that should be restored for this jump.
-     Each time a binding contour that resets the stack is exited,
-     if the target label is *not* yet defined, this slot is updated.  */
-  rtx stack_level;
-  /* List of lists of cleanup expressions to be run by this goto.
-     There is one element for each block that this goto is within.
-     The tail of this list can be 0,
-     if all remaining elements would be empty.
-     The TREE_VALUE contains the cleanup list of that block as of the
-     time this goto was seen.
-     The TREE_ADDRESSABLE flag is 1 for a block that has been exited.  */
-  tree cleanup_list_list;
-};
-
-/* Within any binding contour that must restore a stack level,
-   all labels are recorded with a chain of these structures.  */
-
-struct label_chain GTY(())
-{
-  /* Points to following fixup.  */
-  struct label_chain *next;
-  tree label;
 };
 
 struct stmt_status GTY(())
@@ -315,10 +268,6 @@ struct stmt_status GTY(())
 
   /* If any new stacks are added here, add them to POPSTACKS too.  */
 
-  /* Chain of all pending binding contours that restore stack levels
-     or have cleanups.  */
-  struct nesting * x_stack_block_stack;
-
   /* Chain of all pending conditional statements.  */
   struct nesting * x_cond_stack;
 
@@ -335,16 +284,6 @@ struct stmt_status GTY(())
   /* Number of binding contours started so far in this function.  */
   int x_block_start_count;
 
-  /* Each time we expand an expression-statement,
-     record the expr's type and its RTL value here.  */
-  tree x_last_expr_type;
-  rtx x_last_expr_value;
-  rtx x_last_expr_alt_rtl;
-
-  /* Nonzero if within a ({...}) grouping, in which case we must
-     always compute a value for each expr-stmt in case it is the last one.  */
-  int x_expr_stmts_for_value;
-
   /* Location of last line-number note, whether we actually
      emitted it or not.  */
   location_t x_emit_locus;
@@ -353,16 +292,11 @@ struct stmt_status GTY(())
 };
 
 #define block_stack (cfun->stmt->x_block_stack)
-#define stack_block_stack (cfun->stmt->x_stack_block_stack)
 #define cond_stack (cfun->stmt->x_cond_stack)
 #define case_stack (cfun->stmt->x_case_stack)
 #define nesting_stack (cfun->stmt->x_nesting_stack)
 #define nesting_depth (cfun->stmt->x_nesting_depth)
 #define current_block_start_count (cfun->stmt->x_block_start_count)
-#define last_expr_type (cfun->stmt->x_last_expr_type)
-#define last_expr_value (cfun->stmt->x_last_expr_value)
-#define last_expr_alt_rtl (cfun->stmt->x_last_expr_alt_rtl)
-#define expr_stmts_for_value (cfun->stmt->x_expr_stmts_for_value)
 #define emit_locus (cfun->stmt->x_emit_locus)
 #define goto_fixup_chain (cfun->stmt->x_goto_fixup_chain)
 
@@ -371,19 +305,14 @@ int using_eh_for_cleanups_p = 0;
 
 static int n_occurrences (int, const char *);
 static bool decl_conflicts_with_clobbers_p (tree, const HARD_REG_SET);
-static void expand_goto_internal (tree, rtx, rtx);
-static int expand_fixup (tree, rtx, rtx);
 static void expand_nl_goto_receiver (void);
-static void fixup_gotos (struct nesting *, rtx, tree, rtx, int);
 static bool check_operand_nalternatives (tree, tree);
 static bool check_unique_operand_names (tree, tree);
 static char *resolve_operand_name_1 (char *, tree, tree);
-static void expand_null_return_1 (rtx);
+static void expand_null_return_1 (void);
 static enum br_predictor return_prediction (rtx);
 static rtx shift_return_value (rtx);
 static void expand_value_return (rtx);
-static void expand_cleanups (tree, int, int);
-static void check_seenlabel (void);
 static void do_jump_if_equal (rtx, rtx, rtx, int);
 static int estimate_case_costs (case_node_ptr);
 static bool same_case_target_p (rtx, rtx);
@@ -433,8 +362,8 @@ emit_nop (void)
 
   last_insn = get_last_insn ();
   if (!optimize
-      && (GET_CODE (last_insn) == CODE_LABEL
-         || (GET_CODE (last_insn) == NOTE
+      && (LABEL_P (last_insn)
+         || (NOTE_P (last_insn)
              && prev_real_insn (last_insn) == 0)))
     emit_insn (gen_nop ());
 }
@@ -501,7 +430,6 @@ expand_computed_goto (tree exp)
 
   x = convert_memory_address (Pmode, x);
 
-  emit_queue ();
   do_pending_stack_adjust ();
   emit_indirect_jump (x);
 }
@@ -522,7 +450,6 @@ expand_computed_goto (tree exp)
 void
 expand_label (tree label)
 {
-  struct label_chain *p;
   rtx label_r = label_rtx (label);
 
   do_pending_stack_adjust ();
@@ -543,14 +470,6 @@ expand_label (tree label)
       
   if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
     maybe_set_first_label_num (label_r);
-
-  if (stack_block_stack != 0)
-    {
-      p = 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;
-    }
 }
 
 /* Generate RTL code for a `goto' statement with target label LABEL.
@@ -568,385 +487,7 @@ expand_goto (tree label)
     abort ();
 #endif
 
-  expand_goto_internal (label, label_rtx (label), NULL_RTX);
-}
-
-/* Generate RTL code for a `goto' statement with target label BODY.
-   LABEL should be a LABEL_REF.
-   LAST_INSN, if non-0, is the rtx we should consider as the last
-   insn emitted (for the purposes of cleaning up a return).  */
-
-static void
-expand_goto_internal (tree body, rtx label, rtx last_insn)
-{
-  struct nesting *block;
-  rtx stack_level = 0;
-
-  if (GET_CODE (label) != CODE_LABEL)
-    abort ();
-
-  /* If label has already been defined, we can tell now
-     whether and how we must alter the stack level.  */
-
-  if (PREV_INSN (label) != 0)
-    {
-      /* Find the innermost pending block that contains the label.
-        (Check containment by comparing insn-uids.)
-        Then restore the outermost stack level within that block,
-        and do cleanups of all blocks contained in it.  */
-      for (block = block_stack; block; block = block->next)
-       {
-         if (INSN_UID (block->data.block.first_insn) < INSN_UID (label))
-           break;
-         if (block->data.block.stack_level != 0)
-           stack_level = block->data.block.stack_level;
-         /* Execute the cleanups for blocks we are exiting.  */
-         if (block->data.block.cleanups != 0)
-           {
-             expand_cleanups (block->data.block.cleanups, 1, 1);
-             do_pending_stack_adjust ();
-           }
-       }
-
-      if (stack_level)
-       {
-         /* Ensure stack adjust isn't done by emit_jump, as this
-            would clobber the stack pointer.  This one should be
-            deleted as dead by flow.  */
-         clear_pending_stack_adjust ();
-         do_pending_stack_adjust ();
-
-         /* Don't do this adjust if it's to the end label and this function
-            is to return with a depressed stack pointer.  */
-         if (label == return_label
-             && (((TREE_CODE (TREE_TYPE (current_function_decl))
-                  == FUNCTION_TYPE)
-                  && (TYPE_RETURNS_STACK_DEPRESSED
-                      (TREE_TYPE (current_function_decl))))))
-           ;
-         else
-           emit_stack_restore (SAVE_BLOCK, stack_level, NULL_RTX);
-       }
-
-      if (body != 0 && DECL_TOO_LATE (body))
-       error ("jump to `%s' invalidly jumps into binding contour",
-              IDENTIFIER_POINTER (DECL_NAME (body)));
-    }
-  /* Label not yet defined: may need to put this goto
-     on the fixup list.  */
-  else if (! expand_fixup (body, label, last_insn))
-    {
-      /* No fixup needed.  Record that the label is the target
-        of at least one goto that has no fixup.  */
-      if (body != 0)
-       TREE_ADDRESSABLE (body) = 1;
-    }
-
-  emit_jump (label);
-}
-\f
-/* Generate if necessary a fixup for a goto
-   whose target label in tree structure (if any) is TREE_LABEL
-   and whose target in rtl is RTL_LABEL.
-
-   If LAST_INSN is nonzero, we pretend that the jump appears
-   after insn LAST_INSN instead of at the current point in the insn stream.
-
-   The fixup will be used later to insert insns just before the goto.
-   Those insns will restore the stack level as appropriate for the
-   target label, and will (in the case of C++) also invoke any object
-   destructors which have to be invoked when we exit the scopes which
-   are exited by the goto.
-
-   Value is nonzero if a fixup is made.  */
-
-static int
-expand_fixup (tree tree_label, rtx rtl_label, rtx last_insn)
-{
-  struct nesting *block, *end_block;
-
-  /* See if we can recognize which block the label will be output in.
-     This is possible in some very common cases.
-     If we succeed, set END_BLOCK to that block.
-     Otherwise, set it to 0.  */
-
-  if (cond_stack
-      && (rtl_label == cond_stack->data.cond.endif_label
-         || rtl_label == cond_stack->data.cond.next_label))
-    end_block = cond_stack;
-  else
-    end_block = 0;
-
-  /* Now set END_BLOCK to the binding level to which we will return.  */
-
-  if (end_block)
-    {
-      struct nesting *next_block = end_block->all;
-      block = block_stack;
-
-      /* First see if the END_BLOCK is inside the innermost binding level.
-        If so, then no cleanups or stack levels are relevant.  */
-      while (next_block && next_block != block)
-       next_block = next_block->all;
-
-      if (next_block)
-       return 0;
-
-      /* Otherwise, set END_BLOCK to the innermost binding level
-        which is outside the relevant control-structure nesting.  */
-      next_block = block_stack->next;
-      for (block = block_stack; block != end_block; block = block->all)
-       if (block == next_block)
-         next_block = next_block->next;
-      end_block = next_block;
-    }
-
-  /* Does any containing block have a stack level or cleanups?
-     If not, no fixup is needed, and that is the normal case
-     (the only case, for standard C).  */
-  for (block = block_stack; block != end_block; block = block->next)
-    if (block->data.block.stack_level != 0
-       || block->data.block.cleanups != 0)
-      break;
-
-  if (block != end_block)
-    {
-      /* Ok, a fixup is needed.  Add a fixup to the list of such.  */
-      struct goto_fixup *fixup = ggc_alloc (sizeof (struct goto_fixup));
-      /* In case an old stack level is restored, make sure that comes
-        after any pending stack adjust.  */
-      /* ?? If the fixup isn't to come at the present position,
-        doing the stack adjust here isn't useful.  Doing it with our
-        settings at that location isn't useful either.  Let's hope
-        someone does it!  */
-      if (last_insn == 0)
-       do_pending_stack_adjust ();
-      fixup->target = tree_label;
-      fixup->target_rtl = rtl_label;
-
-      /* Create a BLOCK node and a corresponding matched set of
-        NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes at
-        this point.  The notes will encapsulate any and all fixup
-        code which we might later insert at this point in the insn
-        stream.  Also, the BLOCK node will be the parent (i.e. the
-        `SUPERBLOCK') of any other BLOCK nodes which we might create
-        later on when we are expanding the fixup code.
-
-        Note that optimization passes might move the *_BLOCK notes away,
-        so we use a NOTE_INSN_DELETED as a placeholder.  */
-
-      {
-       rtx original_before_jump
-         = last_insn ? last_insn : get_last_insn ();
-       rtx start;
-       rtx end;
-       tree block;
-
-       block = make_node (BLOCK);
-       TREE_USED (block) = 1;
-
-       BLOCK_CHAIN (block)
-         = BLOCK_CHAIN (DECL_INITIAL (current_function_decl));
-       BLOCK_CHAIN (DECL_INITIAL (current_function_decl))
-         = block;
-
-       start_sequence ();
-       start = emit_note (NOTE_INSN_BLOCK_BEG);
-       NOTE_BLOCK (start) = block;
-       fixup->before_jump = emit_note (NOTE_INSN_DELETED);
-       end = emit_note (NOTE_INSN_BLOCK_END);
-       NOTE_BLOCK (end) = block;
-       fixup->context = block;
-       end_sequence ();
-       emit_insn_after (start, original_before_jump);
-      }
-
-      fixup->block_start_count = current_block_start_count;
-      fixup->stack_level = 0;
-      fixup->cleanup_list_list
-       = ((block->data.block.outer_cleanups
-           || block->data.block.cleanups)
-          ? tree_cons (NULL_TREE, block->data.block.cleanups,
-                       block->data.block.outer_cleanups)
-          : 0);
-      fixup->next = goto_fixup_chain;
-      goto_fixup_chain = fixup;
-    }
-
-  return block != 0;
-}
-\f
-/* Expand any needed fixups in the outputmost binding level of the
-   function.  FIRST_INSN is the first insn in the function.  */
-
-void
-expand_fixups (rtx first_insn)
-{
-  fixup_gotos (NULL, NULL_RTX, NULL_TREE, first_insn, 0);
-}
-
-/* When exiting a binding contour, process all pending gotos requiring fixups.
-   THISBLOCK is the structure that describes the block being exited.
-   STACK_LEVEL is the rtx for the stack level to restore exiting this contour.
-   CLEANUP_LIST is a list of expressions to evaluate on exiting this contour.
-   FIRST_INSN is the insn that began this contour.
-
-   Gotos that jump out of this contour must restore the
-   stack level and do the cleanups before actually jumping.
-
-   DONT_JUMP_IN positive means report error if there is a jump into this
-   contour from before the beginning of the contour.  This is also done if
-   STACK_LEVEL is nonzero unless DONT_JUMP_IN is negative.  */
-
-static void
-fixup_gotos (struct nesting *thisblock, rtx stack_level,
-            tree cleanup_list, rtx first_insn, int dont_jump_in)
-{
-  struct goto_fixup *f, *prev;
-
-  /* F is the fixup we are considering; PREV is the previous one.  */
-  /* We run this loop in two passes so that cleanups of exited blocks
-     are run first, and blocks that are exited are marked so
-     afterwards.  */
-
-  for (prev = 0, f = goto_fixup_chain; f; prev = f, f = f->next)
-    {
-      /* Test for a fixup that is inactive because it is already handled.  */
-      if (f->before_jump == 0)
-       {
-         /* Delete inactive fixup from the chain, if that is easy to do.  */
-         if (prev != 0)
-           prev->next = f->next;
-       }
-      /* Has this fixup's target label been defined?
-        If so, we can finalize it.  */
-      else if (PREV_INSN (f->target_rtl) != 0)
-       {
-         rtx cleanup_insns;
-
-         /* If this fixup jumped into this contour from before the beginning
-            of this contour, report an error.   This code used to use
-            the first non-label insn after f->target_rtl, but that's
-            wrong since such can be added, by things like put_var_into_stack
-            and have INSN_UIDs that are out of the range of the block.  */
-         /* ??? Bug: this does not detect jumping in through intermediate
-            blocks that have stack levels or cleanups.
-            It detects only a problem with the innermost block
-            around the label.  */
-         if (f->target != 0
-             && (dont_jump_in > 0 || (dont_jump_in == 0 && stack_level)
-                 || cleanup_list)
-             && INSN_UID (first_insn) < INSN_UID (f->target_rtl)
-             && INSN_UID (first_insn) > INSN_UID (f->before_jump)
-             && ! DECL_ERROR_ISSUED (f->target))
-           {
-             error ("%Jlabel '%D' used before containing binding contour",
-                    f->target, f->target);
-             /* Prevent multiple errors for one label.  */
-             DECL_ERROR_ISSUED (f->target) = 1;
-           }
-
-         /* We will expand the cleanups into a sequence of their own and
-            then later on we will attach this new sequence to the insn
-            stream just ahead of the actual jump insn.  */
-
-         start_sequence ();
-
-         /* Temporarily restore the lexical context where we will
-            logically be inserting the fixup code.  We do this for the
-            sake of getting the debugging information right.  */
-
-         lang_hooks.decls.pushlevel (0);
-         lang_hooks.decls.set_block (f->context);
-
-         /* Expand the cleanups for blocks this jump exits.  */
-         if (f->cleanup_list_list)
-           {
-             tree lists;
-             for (lists = f->cleanup_list_list; lists; lists = TREE_CHAIN (lists))
-               /* Marked elements correspond to blocks that have been closed.
-                  Do their cleanups.  */
-               if (TREE_ADDRESSABLE (lists)
-                   && TREE_VALUE (lists) != 0)
-                 {
-                   expand_cleanups (TREE_VALUE (lists), 1, 1);
-                   /* Pop any pushes done in the cleanups,
-                      in case function is about to return.  */
-                   do_pending_stack_adjust ();
-                 }
-           }
-
-         /* Restore stack level for the biggest contour that this
-            jump jumps out of.  */
-         if (f->stack_level
-             && ! (f->target_rtl == return_label
-                   && ((TREE_CODE (TREE_TYPE (current_function_decl))
-                        == FUNCTION_TYPE)
-                       && (TYPE_RETURNS_STACK_DEPRESSED
-                           (TREE_TYPE (current_function_decl))))))
-           emit_stack_restore (SAVE_BLOCK, f->stack_level, f->before_jump);
-
-         /* Finish up the sequence containing the insns which implement the
-            necessary cleanups, and then attach that whole sequence to the
-            insn stream just ahead of the actual jump insn.  Attaching it
-            at that point insures that any cleanups which are in fact
-            implicit C++ object destructions (which must be executed upon
-            leaving the block) appear (to the debugger) to be taking place
-            in an area of the generated code where the object(s) being
-            destructed are still "in scope".  */
-
-         cleanup_insns = get_insns ();
-         lang_hooks.decls.poplevel (1, 0, 0);
-
-         end_sequence ();
-         emit_insn_after (cleanup_insns, f->before_jump);
-
-         f->before_jump = 0;
-       }
-    }
-
-  /* For any still-undefined labels, do the cleanups for this block now.
-     We must do this now since items in the cleanup list may go out
-     of scope when the block ends.  */
-  for (prev = 0, f = goto_fixup_chain; f; prev = f, f = f->next)
-    if (f->before_jump != 0
-       && PREV_INSN (f->target_rtl) == 0
-       /* Label has still not appeared.  If we are exiting a block with
-          a stack level to restore, that started before the fixup,
-          mark this stack level as needing restoration
-          when the fixup is later finalized.  */
-       && thisblock != 0
-       /* Note: if THISBLOCK == 0 and we have a label that hasn't appeared, it
-          means the label is undefined.  That's erroneous, but possible.  */
-       && (thisblock->data.block.block_start_count
-           <= f->block_start_count))
-      {
-       tree lists = f->cleanup_list_list;
-       rtx cleanup_insns;
-
-       for (; lists; lists = TREE_CHAIN (lists))
-         /* If the following elt. corresponds to our containing block
-            then the elt. must be for this block.  */
-         if (TREE_CHAIN (lists) == thisblock->data.block.outer_cleanups)
-           {
-             start_sequence ();
-             lang_hooks.decls.pushlevel (0);
-             lang_hooks.decls.set_block (f->context);
-             expand_cleanups (TREE_VALUE (lists), 1, 1);
-             do_pending_stack_adjust ();
-             cleanup_insns = get_insns ();
-             lang_hooks.decls.poplevel (1, 0, 0);
-             end_sequence ();
-             if (cleanup_insns != 0)
-               f->before_jump
-                 = emit_insn_after (cleanup_insns, f->before_jump);
-
-             f->cleanup_list_list = TREE_CHAIN (lists);
-           }
-
-       if (stack_level)
-         f->stack_level = stack_level;
-      }
+  emit_jump (label_rtx (label));
 }
 \f
 /* Return the number of times character C occurs in string S.  */
@@ -977,8 +518,6 @@ expand_asm (tree string, int vol)
   MEM_VOLATILE_P (body) = vol;
 
   emit_insn (body);
-
-  clear_last_expr ();
 }
 
 /* Parse the output constraint pointed to by *CONSTRAINT_P.  It is the
@@ -1415,8 +954,6 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
        }
     }
 
-  clear_last_expr ();
-
   /* First pass over inputs and outputs checks validity and sets
      mark_addressable if needed.  */
 
@@ -1514,15 +1051,15 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
          || is_inout)
        {
          op = expand_expr (val, NULL_RTX, VOIDmode, EXPAND_WRITE);
-         if (GET_CODE (op) == MEM)
+         if (MEM_P (op))
            op = validize_mem (op);
 
-         if (! allows_reg && GET_CODE (op) != MEM)
+         if (! allows_reg && !MEM_P (op))
            error ("output number %d not directly addressable", i);
-         if ((! allows_mem && GET_CODE (op) == MEM)
+         if ((! allows_mem && MEM_P (op))
              || GET_CODE (op) == CONCAT)
            {
-             real_output_rtx[i] = protect_from_queue (op, 1);
+             real_output_rtx[i] = op;
              op = gen_reg_rtx (GET_MODE (op));
              if (is_inout)
                emit_move_insn (op, real_output_rtx[i]);
@@ -1588,7 +1125,7 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
       /* Never pass a CONCAT to an ASM.  */
       if (GET_CODE (op) == CONCAT)
        op = force_reg (GET_MODE (op), op);
-      else if (GET_CODE (op) == MEM)
+      else if (MEM_P (op))
        op = validize_mem (op);
 
       if (asm_operand_ok (op, constraint) <= 0)
@@ -1598,7 +1135,7 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
          else if (!allows_mem)
            warning ("asm operand %d probably doesn't match constraints",
                     i + noutputs);
-         else if (GET_CODE (op) == MEM)
+         else if (MEM_P (op))
            {
              /* We won't recognize either volatile memory or memory
                 with a queued address as available a memory_operand
@@ -1619,7 +1156,6 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
                }
              if (REG_P (op)
                  || GET_CODE (op) == SUBREG
-                 || GET_CODE (op) == ADDRESSOF
                  || GET_CODE (op) == CONCAT)
                {
                  tree qual_type = build_qualified_type (type,
@@ -1648,13 +1184,6 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
 
   generating_concat_p = 0;
 
-  for (i = 0; i < ninputs - ninout; i++)
-    ASM_OPERANDS_INPUT (body, i)
-      = protect_from_queue (ASM_OPERANDS_INPUT (body, i), 0);
-
-  for (i = 0; i < noutputs; i++)
-    output_rtx[i] = protect_from_queue (output_rtx[i], 1);
-
   /* For in-out operands, copy output rtx to input rtx.  */
   for (i = 0; i < ninout; i++)
     {
@@ -1825,9 +1354,6 @@ expand_asm_expr (tree exp)
          TREE_VALUE (tail) = o[i];
        }
     }
-
-  /* Those MODIFY_EXPRs could do autoincrements.  */
-  emit_queue ();
 }
 
 /* A subroutine of expand_asm_operands.  Check that all operands have
@@ -2055,61 +1581,20 @@ resolve_operand_name_1 (char *p, tree outputs, tree inputs)
   return p;
 }
 \f
-/* Generate RTL to evaluate the expression EXP
-   and remember it in case this is the VALUE in a ({... VALUE; }) constr.
-   Provided just for backward-compatibility.  expand_expr_stmt_value()
-   should be used for new code.  */
+/* Generate RTL to evaluate the expression EXP.  */
 
 void
 expand_expr_stmt (tree exp)
 {
-  expand_expr_stmt_value (exp, -1, 1);
-}
-
-/* Generate RTL to evaluate the expression EXP.  WANT_VALUE tells
-   whether to (1) save the value of the expression, (0) discard it or
-   (-1) use expr_stmts_for_value to tell.  The use of -1 is
-   deprecated, and retained only for backward compatibility.  */
-
-void
-expand_expr_stmt_value (tree exp, int want_value, int maybe_last)
-{
   rtx value;
   tree type;
-  rtx alt_rtl = NULL;
-
-  if (want_value == -1)
-    want_value = expr_stmts_for_value != 0;
-
-  /* If -Wextra, warn about statements with no side effects,
-     except for an explicit cast to void (e.g. for assert()), and
-     except for last statement in ({...}) where they may be useful.  */
-  if (! want_value
-      && (expr_stmts_for_value == 0 || ! maybe_last)
-      && exp != error_mark_node
-      && warn_unused_value)
-    {
-      if (TREE_SIDE_EFFECTS (exp))
-       warn_if_unused_value (exp, emit_locus);
-      else if (!VOID_TYPE_P (TREE_TYPE (exp)) && !TREE_NO_WARNING (exp))
-       warning ("%Hstatement with no effect", &emit_locus);
-    }
-
-  /* If EXP is of function type and we are expanding statements for
-     value, convert it to pointer-to-function.  */
-  if (want_value && TREE_CODE (TREE_TYPE (exp)) == FUNCTION_TYPE)
-    exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
 
-  /* The call to `expand_expr' could cause last_expr_type and
-     last_expr_value to get reset.  Therefore, we set last_expr_value
-     and last_expr_type *after* calling expand_expr.  */
-  value = expand_expr_real (exp, want_value ? NULL_RTX : const0_rtx,
-                           VOIDmode, 0, &alt_rtl);
+  value = expand_expr (exp, const0_rtx, VOIDmode, 0);
   type = TREE_TYPE (exp);
 
   /* If all we do is reference a volatile value in memory,
      copy it to a register to be sure it is actually touched.  */
-  if (value && GET_CODE (value) == MEM && TREE_THIS_VOLATILE (exp))
+  if (value && MEM_P (value) && TREE_THIS_VOLATILE (exp))
     {
       if (TYPE_MODE (type) == VOIDmode)
        ;
@@ -2128,23 +1613,8 @@ expand_expr_stmt_value (tree exp, int want_value, int maybe_last)
        }
     }
 
-  /* If this expression is part of a ({...}) and is in memory, we may have
-     to preserve temporaries.  */
-  preserve_temp_slots (value);
-
-  /* Free any temporaries used to evaluate this expression.  Any temporary
-     used as a result of this expression will already have been preserved
-     above.  */
+  /* Free any temporaries used to evaluate this expression.  */
   free_temp_slots ();
-
-  if (want_value)
-    {
-      last_expr_value = value;
-      last_expr_alt_rtl = alt_rtl;
-      last_expr_type = type;
-    }
-
-  emit_queue ();
 }
 
 /* Warn if EXP contains any computations whose results are not used.
@@ -2164,8 +1634,8 @@ warn_if_unused_value (tree exp, location_t locus)
   if (VOID_TYPE_P (TREE_TYPE (exp)))
     return 0;
 
-  if (EXPR_LOCUS (exp))
-    locus = *EXPR_LOCUS (exp);
+  if (EXPR_HAS_LOCATION (exp))
+    locus = EXPR_LOCATION (exp);
 
   switch (TREE_CODE (exp))
     {
@@ -2177,7 +1647,6 @@ warn_if_unused_value (tree exp, location_t locus)
     case INIT_EXPR:
     case TARGET_EXPR:
     case CALL_EXPR:
-    case RTL_EXPR:
     case TRY_CATCH_EXPR:
     case WITH_CLEANUP_EXPR:
     case EXIT_EXPR:
@@ -2264,90 +1733,6 @@ warn_if_unused_value (tree exp, location_t locus)
       return 1;
     }
 }
-
-/* Clear out the memory of the last expression evaluated.  */
-
-void
-clear_last_expr (void)
-{
-  last_expr_type = NULL_TREE;
-  last_expr_value = NULL_RTX;
-  last_expr_alt_rtl = NULL_RTX;
-}
-
-/* Begin a statement-expression, i.e., a series of statements which
-   may return a value.  Return the RTL_EXPR for this statement expr.
-   The caller must save that value and pass it to
-   expand_end_stmt_expr.  If HAS_SCOPE is nonzero, temporaries created
-   in the statement-expression are deallocated at the end of the
-   expression.  */
-
-tree
-expand_start_stmt_expr (int has_scope)
-{
-  tree t;
-
-  /* Make the RTL_EXPR node temporary, not momentary,
-     so that rtl_expr_chain doesn't become garbage.  */
-  t = make_node (RTL_EXPR);
-  do_pending_stack_adjust ();
-  if (has_scope)
-    start_sequence_for_rtl_expr (t);
-  else
-    start_sequence ();
-  NO_DEFER_POP;
-  expr_stmts_for_value++;
-  return t;
-}
-
-/* Restore the previous state at the end of a statement that returns a value.
-   Returns a tree node representing the statement's value and the
-   insns to compute the value.
-
-   The nodes of that expression have been freed by now, so we cannot use them.
-   But we don't want to do that anyway; the expression has already been
-   evaluated and now we just want to use the value.  So generate a RTL_EXPR
-   with the proper type and RTL value.
-
-   If the last substatement was not an expression,
-   return something with type `void'.  */
-
-tree
-expand_end_stmt_expr (tree t)
-{
-  OK_DEFER_POP;
-
-  if (! last_expr_value || ! last_expr_type)
-    {
-      last_expr_value = const0_rtx;
-      last_expr_alt_rtl = NULL_RTX;
-      last_expr_type = void_type_node;
-    }
-  else if (!REG_P (last_expr_value) && ! CONSTANT_P (last_expr_value))
-    /* Remove any possible QUEUED.  */
-    last_expr_value = protect_from_queue (last_expr_value, 0);
-
-  emit_queue ();
-
-  TREE_TYPE (t) = last_expr_type;
-  RTL_EXPR_RTL (t) = last_expr_value;
-  RTL_EXPR_ALT_RTL (t) = last_expr_alt_rtl;
-  RTL_EXPR_SEQUENCE (t) = get_insns ();
-
-  rtl_expr_chain = tree_cons (NULL_TREE, t, rtl_expr_chain);
-
-  end_sequence ();
-
-  /* Don't consider deleting this expr or containing exprs at tree level.  */
-  TREE_SIDE_EFFECTS (t) = 1;
-  /* Propagate volatility of the actual RTL expr.  */
-  TREE_THIS_VOLATILE (t) = volatile_refs_p (last_expr_value);
-
-  clear_last_expr ();
-  expr_stmts_for_value--;
-
-  return t;
-}
 \f
 /* Generate RTL for the start of an if-then.  COND is the expression
    whose truth should be tested.
@@ -2431,7 +1816,6 @@ expand_end_cond (void)
     emit_label (thiscond->data.cond.endif_label);
 
   POPSTACK (cond_stack);
-  clear_last_expr ();
 }
 \f
 /* Return nonzero if we should preserve sub-expressions as separate
@@ -2457,16 +1841,12 @@ preserve_subexpressions_p (void)
 void
 expand_null_return (void)
 {
-  rtx last_insn;
-
-  last_insn = get_last_insn ();
-
   /* If this function was declared to return a value, but we
      didn't, clobber the return registers so that they are not
      propagated live to the rest of the function.  */
   clobber_return_register ();
 
-  expand_null_return_1 (last_insn);
+  expand_null_return_1 ();
 }
 
 /* Generate RTL to return directly from the current function.
@@ -2475,18 +1855,16 @@ expand_null_return (void)
 void
 expand_naked_return (void)
 {
-  rtx last_insn, end_label;
-
-  last_insn = get_last_insn ();
-  end_label = naked_return_label;
+  rtx end_label;
 
   clear_pending_stack_adjust ();
   do_pending_stack_adjust ();
-  clear_last_expr ();
 
+  end_label = naked_return_label;
   if (end_label == 0)
     end_label = naked_return_label = gen_label_rtx ();
-  expand_goto_internal (NULL_TREE, end_label, last_insn);
+
+  emit_jump (end_label);
 }
 
 /* Try to guess whether the value of return means error code.  */
@@ -2537,9 +1915,9 @@ shift_return_value (rtx val)
       shift = (GET_MODE_BITSIZE (GET_MODE (target))
               - BITS_PER_UNIT * int_size_in_bytes (type));
       if (shift > 0)
-       val = expand_binop (GET_MODE (target), ashl_optab,
+       val = expand_shift (LSHIFT_EXPR, GET_MODE (target),
                            gen_lowpart (GET_MODE (target), val),
-                           GEN_INT (shift), target, 1, OPTAB_WIDEN);
+                           build_int_2 (shift, 0), target, 1);
     }
   return val;
 }
@@ -2550,7 +1928,6 @@ shift_return_value (rtx val)
 static void
 expand_value_return (rtx val)
 {
-  rtx last_insn;
   rtx return_reg;
   enum br_predictor pred;
 
@@ -2566,7 +1943,6 @@ expand_value_return (rtx val)
 
     }
 
-  last_insn = get_last_insn ();
   return_reg = DECL_RTL (DECL_RESULT (current_function_decl));
 
   /* Copy the value to the return location
@@ -2592,24 +1968,23 @@ expand_value_return (rtx val)
        emit_move_insn (return_reg, val);
     }
 
-  expand_null_return_1 (last_insn);
+  expand_null_return_1 ();
 }
 
-/* Output a return with no value.  If LAST_INSN is nonzero,
-   pretend that the return takes place after LAST_INSN.  */
+/* Output a return with no value.  */
 
 static void
-expand_null_return_1 (rtx last_insn)
+expand_null_return_1 (void)
 {
-  rtx end_label = return_label;
+  rtx end_label;
 
   clear_pending_stack_adjust ();
   do_pending_stack_adjust ();
-  clear_last_expr ();
 
+  end_label = return_label;
   if (end_label == 0)
      end_label = return_label = gen_label_rtx ();
-  expand_goto_internal (NULL_TREE, end_label, last_insn);
+  emit_jump (end_label);
 }
 \f
 /* Generate RTL to evaluate the expression RETVAL and return it
@@ -2618,15 +1993,6 @@ expand_null_return_1 (rtx last_insn)
 void
 expand_return (tree retval)
 {
-  /* If there are any cleanups to be performed, then they will
-     be inserted following LAST_INSN.  It is desirable
-     that the last_insn, for such purposes, should be the
-     last insn before computing the return value.  Otherwise, cleanups
-     which call functions can clobber the return value.  */
-  /* ??? rms: I think that is erroneous, because in C++ it would
-     run destructors on variables that might be used in the subsequent
-     computation of the return value.  */
-  rtx last_insn = 0;
   rtx result_rtl;
   rtx val = 0;
   tree retval_rhs;
@@ -2635,7 +2001,6 @@ expand_return (tree retval)
   if (TREE_CODE (TREE_TYPE (TREE_TYPE (current_function_decl))) == VOID_TYPE)
     {
       expand_expr (retval, NULL_RTX, VOIDmode, 0);
-      emit_queue ();
       expand_null_return ();
       return;
     }
@@ -2649,14 +2014,13 @@ expand_return (tree retval)
     }
   else if (TREE_CODE (retval) == RESULT_DECL)
     retval_rhs = retval;
-  else if ((TREE_CODE (retval) == MODIFY_EXPR || TREE_CODE (retval) == INIT_EXPR)
+  else if ((TREE_CODE (retval) == MODIFY_EXPR
+           || TREE_CODE (retval) == INIT_EXPR)
           && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
     retval_rhs = TREE_OPERAND (retval, 1);
   else
     retval_rhs = retval;
 
-  last_insn = get_last_insn ();
-
   result_rtl = DECL_RTL (DECL_RESULT (current_function_decl));
 
   /* If the result is an aggregate that is being returned in one (or more)
@@ -2664,8 +2028,7 @@ expand_return (tree retval)
      copying a BLKmode value into registers.  We could put this code in a
      more general area (for use by everyone instead of just function
      call/return), but until this feature is generally usable it is kept here
-     (and in expand_call).  The value must go into a pseudo in case there
-     are cleanups that will clobber the real return register.  */
+     (and in expand_call).  */
 
   if (retval_rhs != 0
       && TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode
@@ -2738,9 +2101,7 @@ expand_return (tree retval)
          store_bit_field (dst, bitsize, xbitpos % BITS_PER_WORD, word_mode,
                           extract_bit_field (src, bitsize,
                                              bitpos % BITS_PER_WORD, 1,
-                                             NULL_RTX, word_mode, word_mode,
-                                             BITS_PER_WORD),
-                          BITS_PER_WORD);
+                                             NULL_RTX, word_mode, word_mode));
        }
 
       tmpmode = GET_MODE (result_rtl);
@@ -2769,7 +2130,6 @@ expand_return (tree retval)
        result_reg_mode = tmpmode;
       result_reg = gen_reg_rtx (result_reg_mode);
 
-      emit_queue ();
       for (i = 0; i < n_regs; i++)
        emit_move_insn (operand_subword (result_reg, i, 0, result_reg_mode),
                        result_pseudos[i]);
@@ -2792,16 +2152,13 @@ expand_return (tree retval)
       val = assign_temp (nt, 0, 0, 1);
       val = expand_expr (retval_rhs, val, GET_MODE (val), 0);
       val = force_not_mem (val);
-      emit_queue ();
-      /* Return the calculated value, doing cleanups first.  */
+      /* Return the calculated value.  */
       expand_value_return (shift_return_value (val));
     }
   else
     {
-      /* No cleanups or no hard reg used;
-        calculate value into hard return reg.  */
+      /* No hard reg used; calculate value into hard return reg.  */
       expand_expr (retval, const0_rtx, VOIDmode, 0);
-      emit_queue ();
       expand_value_return (result_rtl);
     }
 }
@@ -2848,9 +2205,6 @@ expand_start_bindings_and_block (int flags, tree block)
   thisblock->next = block_stack;
   thisblock->all = nesting_stack;
   thisblock->depth = ++nesting_depth;
-  thisblock->data.block.stack_level = 0;
-  thisblock->data.block.cleanups = 0;
-  thisblock->data.block.exception_region = 0;
   thisblock->data.block.block_target_temp_slot_level = target_temp_slot_level;
 
   thisblock->data.block.conditional_code = 0;
@@ -2863,16 +2217,6 @@ expand_start_bindings_and_block (int flags, tree block)
      never the last instruction.  */
   emit_note (NOTE_INSN_DELETED);
 
-  if (block_stack
-      && !(block_stack->data.block.cleanups == NULL_TREE
-          && block_stack->data.block.outer_cleanups == NULL_TREE))
-    thisblock->data.block.outer_cleanups
-      = tree_cons (NULL_TREE, block_stack->data.block.cleanups,
-                  block_stack->data.block.outer_cleanups);
-  else
-    thisblock->data.block.outer_cleanups = 0;
-  thisblock->data.block.label_chain = 0;
-  thisblock->data.block.innermost_stack_block = stack_block_stack;
   thisblock->data.block.first_insn = note;
   thisblock->data.block.block_start_count = ++current_block_start_count;
   thisblock->exit_label = exit_flag ? gen_label_rtx () : 0;
@@ -2945,16 +2289,6 @@ is_body_block (tree stmt)
   return 0;
 }
 
-/* True if we are currently emitting insns in an area of output code
-   that is controlled by a conditional expression.  This is used by
-   the cleanup handling code to generate conditional cleanup actions.  */
-
-int
-conditional_context (void)
-{
-  return block_stack && block_stack->data.block.conditional_code;
-}
-
 /* Return an opaque pointer to the current nesting level, so frontend code
    can check its own sanity.  */
 
@@ -3068,7 +2402,7 @@ warn_about_unused_variables (tree vars)
 
 void
 expand_end_bindings (tree vars, int mark_ends ATTRIBUTE_UNUSED,
-                    int dont_jump_in)
+                    int dont_jump_in ATTRIBUTE_UNUSED)
 {
   struct nesting *thisblock = block_stack;
 
@@ -3082,83 +2416,7 @@ expand_end_bindings (tree vars, int mark_ends ATTRIBUTE_UNUSED,
       emit_label (thisblock->exit_label);
     }
 
-  /* Don't allow jumping into a block that has a stack level.
-     Cleanups are allowed, though.  */
-  if (dont_jump_in > 0
-      || (dont_jump_in == 0 && thisblock->data.block.stack_level != 0))
-    {
-      struct label_chain *chain;
-
-      /* Any labels in this block are no longer valid to go to.
-        Mark them to cause an error message.  */
-      for (chain = thisblock->data.block.label_chain; chain; chain = chain->next)
-       {
-         DECL_TOO_LATE (chain->label) = 1;
-         /* If any goto without a fixup came to this label,
-            that must be an error, because gotos without fixups
-            come from outside all saved stack-levels.  */
-         if (TREE_ADDRESSABLE (chain->label))
-           error ("%Jlabel '%D' used before containing binding contour",
-                  chain->label, chain->label);
-       }
-    }
-
-  /* Restore stack level in effect before the block
-     (only if variable-size objects allocated).  */
-  /* Perform any cleanups associated with the block.  */
-
-  if (thisblock->data.block.stack_level != 0
-      || thisblock->data.block.cleanups != 0)
-    {
-      int reachable;
-      rtx insn;
-
-      /* Don't let cleanups affect ({...}) constructs.  */
-      int old_expr_stmts_for_value = expr_stmts_for_value;
-      rtx old_last_expr_value = last_expr_value;
-      rtx old_last_expr_alt_rtl = last_expr_alt_rtl;
-      tree old_last_expr_type = last_expr_type;
-      expr_stmts_for_value = 0;
-
-      /* Only clean up here if this point can actually be reached.  */
-      insn = get_last_insn ();
-      if (GET_CODE (insn) == NOTE)
-       insn = prev_nonnote_insn (insn);
-      reachable = (! insn || GET_CODE (insn) != BARRIER);
-
-      /* Do the cleanups.  */
-      expand_cleanups (thisblock->data.block.cleanups, 0, reachable);
-      if (reachable)
-       do_pending_stack_adjust ();
-
-      expr_stmts_for_value = old_expr_stmts_for_value;
-      last_expr_value = old_last_expr_value;
-      last_expr_alt_rtl = old_last_expr_alt_rtl;
-      last_expr_type = old_last_expr_type;
-
-      /* Restore the stack level.  */
-
-      if (reachable && thisblock->data.block.stack_level != 0)
-       {
-         emit_stack_restore (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION,
-                             thisblock->data.block.stack_level, NULL_RTX);
-         if (cfun->nonlocal_goto_save_area)
-           update_nonlocal_goto_save_area ();
-       }
-
-      /* Any gotos out of this block must also do these things.
-        Also report any gotos with fixups that came to labels in this
-        level.  */
-      fixup_gotos (thisblock,
-                  thisblock->data.block.stack_level,
-                  thisblock->data.block.cleanups,
-                  thisblock->data.block.first_insn,
-                  dont_jump_in);
-    }
-
-  /* Mark the beginning and end of the scope if requested.
-     We do this now, after running cleanups on the variables
-     just going out of scope, so they are in scope for their cleanups.  */
+  /* Mark the beginning and end of the scope if requested.  */
 
   /* Get rid of the beginning-mark if we don't make an end-mark.  */
   NOTE_LINE_NUMBER (thisblock->data.block.first_insn) = NOTE_INSN_DELETED;
@@ -3168,30 +2426,12 @@ expand_end_bindings (tree vars, int mark_ends ATTRIBUTE_UNUSED,
 
   /* Restore block_stack level for containing block.  */
 
-  stack_block_stack = thisblock->data.block.innermost_stack_block;
   POPSTACK (block_stack);
 
   /* Pop the stack slot nesting and free any slots at this level.  */
   pop_temp_slots ();
 }
 \f
-/* Generate code to save the stack pointer at the start of the current block
-   and set up to restore it on exit.  */
-
-void
-save_stack_pointer (void)
-{
-  struct nesting *thisblock = block_stack;
-
-  if (thisblock->data.block.stack_level == 0)
-    {
-      emit_stack_save (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION,
-                      &thisblock->data.block.stack_level,
-                      thisblock->data.block.first_insn);
-      stack_block_stack = thisblock;
-    }
-}
-\f
 /* Generate RTL for the automatic variable declaration DECL.
    (Other kinds of declarations are simply ignored if seen here.)  */
 
@@ -3243,14 +2483,7 @@ expand_decl (tree decl)
       set_mem_attributes (x, decl, 1);
       SET_DECL_RTL (decl, x);
     }
-  else if (DECL_MODE (decl) != BLKmode
-          /* If -ffloat-store, don't put explicit float vars
-             into regs.  */
-          && !(flag_float_store
-               && TREE_CODE (type) == REAL_TYPE)
-          && ! TREE_THIS_VOLATILE (decl)
-          && ! DECL_NONLOCAL (decl)
-          && (DECL_REGISTER (decl) || DECL_ARTIFICIAL (decl) || optimize))
+  else if (use_register_for_decl (decl))
     {
       /* Automatic variable that can go in a register.  */
       int unsignedp = TYPE_UNSIGNED (type);
@@ -3276,10 +2509,6 @@ expand_decl (tree 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, /*rescan=*/false);
     }
 
   else if (TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST
@@ -3298,7 +2527,7 @@ expand_decl (tree decl)
         to the proper address.  */
       if (DECL_RTL_SET_P (decl))
        {
-         if (GET_CODE (DECL_RTL (decl)) != MEM
+         if (!MEM_P (DECL_RTL (decl))
              || !REG_P (XEXP (DECL_RTL (decl), 0)))
            abort ();
          oldaddr = XEXP (DECL_RTL (decl), 0);
@@ -3328,7 +2557,6 @@ expand_decl (tree decl)
       /* Record the stack pointer on entry to block, if have
         not already done so.  */
       do_pending_stack_adjust ();
-      save_stack_pointer ();
 
       /* Compute the variable's size, in bytes.  This will expand any
         needed SAVE_EXPRs for the first time.  */
@@ -3437,13 +2665,11 @@ expand_decl_init (tree decl)
          || code == POINTER_TYPE || code == REFERENCE_TYPE)
        expand_assignment (decl, convert (TREE_TYPE (decl), integer_zero_node),
                           0);
-      emit_queue ();
     }
   else if (DECL_INITIAL (decl) && TREE_CODE (DECL_INITIAL (decl)) != TREE_LIST)
     {
       emit_line_note (DECL_SOURCE_LOCATION (decl));
       expand_assignment (decl, DECL_INITIAL (decl), 0);
-      emit_queue ();
     }
 
   /* Don't let the initialization count as "using" the variable.  */
@@ -3455,133 +2681,15 @@ expand_decl_init (tree decl)
   pop_temp_slots ();
 }
 
-/* CLEANUP is an expression to be executed at exit from this binding contour;
-   for example, in C++, it might call the destructor for this variable.
-
-   We wrap CLEANUP in an UNSAVE_EXPR node, so that we can expand the
-   CLEANUP multiple times, and have the correct semantics.  This
-   happens in exception handling, for gotos, returns, breaks that
-   leave the current scope.
-
-   If CLEANUP is nonzero and DECL is zero, we record a cleanup
-   that is not associated with any particular variable.  */
-
-int
-expand_decl_cleanup (tree decl, tree cleanup)
-{
-  struct nesting *thisblock;
-
-  /* Error if we are not in any block.  */
-  if (cfun == 0 || block_stack == 0)
-    return 0;
-
-  thisblock = block_stack;
-
-  /* Record the cleanup if there is one.  */
-
-  if (cleanup != 0)
-    {
-      tree t;
-      rtx seq;
-      tree *cleanups = &thisblock->data.block.cleanups;
-      int cond_context = conditional_context ();
-
-      if (cond_context)
-       {
-         rtx flag = gen_reg_rtx (word_mode);
-         rtx set_flag_0;
-         tree cond;
-
-         start_sequence ();
-         emit_move_insn (flag, const0_rtx);
-         set_flag_0 = get_insns ();
-         end_sequence ();
-
-         thisblock->data.block.last_unconditional_cleanup
-           = emit_insn_after (set_flag_0,
-                               thisblock->data.block.last_unconditional_cleanup);
-
-         emit_move_insn (flag, const1_rtx);
-
-         cond = build_decl (VAR_DECL, NULL_TREE,
-                            lang_hooks.types.type_for_mode (word_mode, 1));
-         SET_DECL_RTL (cond, flag);
-
-         /* Conditionalize the cleanup.  */
-         cleanup = build (COND_EXPR, void_type_node,
-                          lang_hooks.truthvalue_conversion (cond),
-                          cleanup, integer_zero_node);
-         cleanup = fold (cleanup);
-
-         cleanups = &thisblock->data.block.cleanups;
-       }
-
-      cleanup = unsave_expr (cleanup);
-
-      t = *cleanups = tree_cons (decl, cleanup, *cleanups);
-
-      if (! cond_context)
-       /* If this block has a cleanup, it belongs in stack_block_stack.  */
-       stack_block_stack = thisblock;
-
-      if (cond_context)
-       {
-         start_sequence ();
-       }
-
-      if (! using_eh_for_cleanups_p)
-       TREE_ADDRESSABLE (t) = 1;
-      else
-       expand_eh_region_start ();
-
-      if (cond_context)
-       {
-         seq = get_insns ();
-         end_sequence ();
-         if (seq)
-           thisblock->data.block.last_unconditional_cleanup
-             = emit_insn_after (seq,
-                                thisblock->data.block.last_unconditional_cleanup);
-       }
-      else
-       {
-         thisblock->data.block.last_unconditional_cleanup
-           = get_last_insn ();
-         /* When we insert instructions after the last unconditional cleanup,
-            we don't adjust last_insn.  That means that a later add_insn will
-            clobber the instructions we've just added.  The easiest way to
-            fix this is to just insert another instruction here, so that the
-            instructions inserted after the last unconditional cleanup are
-            never the last instruction.  */
-         emit_note (NOTE_INSN_DELETED);
-       }
-    }
-  return 1;
-}
-
-/* Like expand_decl_cleanup, but maybe only run the cleanup if an exception
-   is thrown.  */
-
-int
-expand_decl_cleanup_eh (tree decl, tree cleanup, int eh_only)
-{
-  int ret = expand_decl_cleanup (decl, cleanup);
-  if (cleanup && ret)
-    {
-      tree node = block_stack->data.block.cleanups;
-      CLEANUP_EH_ONLY (node) = eh_only;
-    }
-  return ret;
-}
 \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, tree decl_elts)
+expand_anon_union_decl (tree decl, tree cleanup ATTRIBUTE_UNUSED,
+                       tree decl_elts)
 {
-  struct nesting *thisblock = cfun == 0 ? 0 : block_stack;
   rtx x;
   tree t;
 
@@ -3594,14 +2702,12 @@ expand_anon_union_decl (tree decl, tree cleanup, tree decl_elts)
       }
 
   expand_decl (decl);
-  expand_decl_cleanup (decl, cleanup);
   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);
-      tree cleanup_elt = TREE_PURPOSE (t);
       enum machine_mode mode = TYPE_MODE (TREE_TYPE (decl_elt));
 
       /* If any of the elements are addressable, so is the entire
@@ -3622,7 +2728,7 @@ expand_anon_union_decl (tree decl, tree cleanup, tree decl_elts)
 
       /* (SUBREG (MEM ...)) at RTL generation time is invalid, so we
          instead create a new MEM rtx with the proper mode.  */
-      if (GET_CODE (x) == MEM)
+      if (MEM_P (x))
        {
          if (mode == GET_MODE (x))
            SET_DECL_RTL (decl_elt, x);
@@ -3638,145 +2744,9 @@ expand_anon_union_decl (tree decl, tree cleanup, tree decl_elts)
        }
       else
        abort ();
-
-      /* Record the cleanup if there is one.  */
-
-      if (cleanup != 0)
-       thisblock->data.block.cleanups
-         = tree_cons (decl_elt, cleanup_elt,
-                      thisblock->data.block.cleanups);
     }
 }
 \f
-/* Expand a list of cleanups LIST.
-   Elements may be expressions or may be nested lists.
-
-   If IN_FIXUP is nonzero, we are generating this cleanup for a fixup
-   goto and handle protection regions specially in that case.
-
-   If REACHABLE, we emit code, otherwise just inform the exception handling
-   code about this finalization.  */
-
-static void
-expand_cleanups (tree list, int in_fixup, int reachable)
-{
-  tree tail;
-  for (tail = list; tail; tail = TREE_CHAIN (tail))
-    if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST)
-      expand_cleanups (TREE_VALUE (tail), in_fixup, reachable);
-    else
-      {
-       if (! in_fixup && using_eh_for_cleanups_p)
-         expand_eh_region_end_cleanup (TREE_VALUE (tail));
-
-       if (reachable && !CLEANUP_EH_ONLY (tail))
-         {
-           /* Cleanups may be run multiple times.  For example,
-              when exiting a binding contour, we expand the
-              cleanups associated with that contour.  When a goto
-              within that binding contour has a target outside that
-              contour, it will expand all cleanups from its scope to
-              the target.  Though the cleanups are expanded multiple
-              times, the control paths are non-overlapping so the
-              cleanups will not be executed twice.  */
-
-           /* We may need to protect from outer cleanups.  */
-           if (in_fixup && using_eh_for_cleanups_p)
-             {
-               expand_eh_region_start ();
-
-               expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
-
-               expand_eh_region_end_fixup (TREE_VALUE (tail));
-             }
-           else
-             expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
-
-           free_temp_slots ();
-         }
-      }
-}
-
-/* Mark when the context we are emitting RTL for as a conditional
-   context, so that any cleanup actions we register with
-   expand_decl_init will be properly conditionalized when those
-   cleanup actions are later performed.  Must be called before any
-   expression (tree) is expanded that is within a conditional context.  */
-
-void
-start_cleanup_deferral (void)
-{
-  /* block_stack can be NULL if we are inside the parameter list.  It is
-     OK to do nothing, because cleanups aren't possible here.  */
-  if (block_stack)
-    ++block_stack->data.block.conditional_code;
-}
-
-/* Mark the end of a conditional region of code.  Because cleanup
-   deferrals may be nested, we may still be in a conditional region
-   after we end the currently deferred cleanups, only after we end all
-   deferred cleanups, are we back in unconditional code.  */
-
-void
-end_cleanup_deferral (void)
-{
-  /* block_stack can be NULL if we are inside the parameter list.  It is
-     OK to do nothing, because cleanups aren't possible here.  */
-  if (block_stack)
-    --block_stack->data.block.conditional_code;
-}
-
-tree
-last_cleanup_this_contour (void)
-{
-  if (block_stack == 0)
-    return 0;
-
-  return block_stack->data.block.cleanups;
-}
-
-
-/* Return nonzero if any containing block has a stack level or
-   cleanups.  */
-
-int
-containing_blocks_have_cleanups_or_stack_level (void)
-{
-  struct nesting *block;
-
-  for (block = block_stack; block; block = block->next)
-    if (block->data.block.stack_level != 0
-        || block->data.block.cleanups != 0)
-      return 1;
-
-  return 0;
-}
-
-/* Return 1 if there are any pending cleanups at this point.
-   Check the current contour as well as contours that enclose
-   the current contour.  */
-
-int
-any_pending_cleanups (void)
-{
-  struct nesting *block;
-
-  if (cfun == NULL || cfun->stmt == NULL || block_stack == 0)
-    return 0;
-
-  if (block_stack->data.block.cleanups != NULL)
-    return 1;
-
-  if (block_stack->data.block.outer_cleanups == 0)
-    return 0;
-
-  for (block = block_stack->next; block; block = block->next)
-    if (block->data.block.cleanups != 0)
-      return 1;
-
-  return 0;
-}
-\f
 /* Enter a case (Pascal) or switch (C) statement.
    Push a block onto case_stack and nesting_stack
    to accumulate the case-labels that are seen
@@ -3812,60 +2782,13 @@ expand_start_case (int exit_flag, tree expr, tree type,
   nesting_stack = thiscase;
 
   do_pending_stack_adjust ();
-  emit_queue ();
 
   /* Make sure case_stmt.start points to something that won't
      need any transformation before expand_end_case.  */
-  if (GET_CODE (get_last_insn ()) != NOTE)
+  if (!NOTE_P (get_last_insn ()))
     emit_note (NOTE_INSN_DELETED);
 
   thiscase->data.case_stmt.start = get_last_insn ();
-
-  start_cleanup_deferral ();
-}
-\f
-static void
-check_seenlabel (void)
-{
-  /* If this is the first label, warn if any insns have been emitted.  */
-  if (case_stack->data.case_stmt.line_number_status >= 0)
-    {
-      rtx insn;
-
-      restore_line_number_status
-       (case_stack->data.case_stmt.line_number_status);
-      case_stack->data.case_stmt.line_number_status = -1;
-
-      for (insn = case_stack->data.case_stmt.start;
-          insn;
-          insn = NEXT_INSN (insn))
-       {
-         if (GET_CODE (insn) == CODE_LABEL)
-           break;
-         if (GET_CODE (insn) != NOTE
-             && (GET_CODE (insn) != INSN || GET_CODE (PATTERN (insn)) != USE))
-           {
-             do
-               insn = PREV_INSN (insn);
-             while (insn && (GET_CODE (insn) != NOTE || NOTE_LINE_NUMBER (insn) < 0));
-
-             /* If insn is zero, then there must have been a syntax error.  */
-             if (insn)
-                {
-                  location_t locus;
-#ifdef USE_MAPPED_LOCATION
-                  locus = NOTE_SOURCE_LOCATION (insn);
-#else
-                  locus.file = NOTE_SOURCE_FILE (insn);
-                  locus.line = NOTE_LINE_NUMBER (insn);
-#endif
-                  warning ("%Hunreachable code at beginning of %s", &locus,
-                           case_stack->data.case_stmt.printname);
-                }
-             break;
-           }
-       }
-    }
 }
 
 /* Accumulate one case or default label inside a case or switch statement.
@@ -3878,7 +2801,6 @@ check_seenlabel (void)
    If VALUE is a duplicate or overlaps, return 2 and do nothing
    except store the (first) duplicate node in *DUPLICATE.
    If VALUE is out of range, return 3 and do nothing.
-   If we are jumping into the scope of a cleanup or var-sized array, return 5.
    Return 0 on success.
 
    Extended to handle range statements.  */
@@ -3894,10 +2816,6 @@ pushcase (tree value, tree (*converter) (tree, tree), tree label,
   if (! (case_stack && case_stack->data.case_stmt.start))
     return 1;
 
-  if (stack_block_stack
-      && stack_block_stack->depth > case_stack->depth)
-    return 5;
-
   index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr);
   nominal_type = case_stack->data.case_stmt.nominal_type;
 
@@ -3909,8 +2827,6 @@ pushcase (tree value, tree (*converter) (tree, tree), tree label,
   if (value != 0)
     value = (*converter) (nominal_type, value);
 
-  check_seenlabel ();
-
   /* Fail if this value is out of range for the actual type of the index
      (which may be narrower than NOMINAL_TYPE).  */
   if (value != 0
@@ -3941,10 +2857,6 @@ pushcase_range (tree value1, tree value2, tree (*converter) (tree, tree),
   if (! (case_stack && case_stack->data.case_stmt.start))
     return 1;
 
-  if (stack_block_stack
-      && stack_block_stack->depth > case_stack->depth)
-    return 5;
-
   index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr);
   nominal_type = case_stack->data.case_stmt.nominal_type;
 
@@ -3952,8 +2864,6 @@ pushcase_range (tree value1, tree value2, tree (*converter) (tree, tree),
   if (index_type == error_mark_node)
     return 0;
 
-  check_seenlabel ();
-
   /* Convert VALUEs to type in which the comparisons are nominally done
      and replace any unspecified value with the corresponding bound.  */
   if (value1 == 0)
@@ -4351,8 +3261,6 @@ emit_case_bit_tests (tree index_type, tree index_expr, tree minval,
                            convert (index_type, index_expr),
                            convert (index_type, minval)));
   index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
-  emit_queue ();
-  index = protect_from_queue (index, 0);
   do_pending_stack_adjust ();
 
   mode = TYPE_MODE (index_type);
@@ -4420,15 +3328,6 @@ expand_end_case_type (tree orig_index, tree orig_type)
 
   do_pending_stack_adjust ();
 
-  /* This might get a spurious warning in the presence of a syntax error;
-     it could be fixed by moving the call to check_seenlabel after the
-     check for error_mark_node, and copying the code of check_seenlabel that
-     deals with case_stack->data.case_stmt.line_number_status /
-     restore_line_number_status in front of the call to end_cleanup_deferral;
-     However, this might miss some useful warnings in the presence of
-     non-syntax errors.  */
-  check_seenlabel ();
-
   /* An ERROR_MARK occurs for various reasons including invalid data type.  */
   if (index_type != error_mark_node)
     {
@@ -4510,12 +3409,9 @@ expand_end_case_type (tree orig_index, tree orig_type)
       if (count != 0)
        range = fold (build (MINUS_EXPR, index_type, maxval, minval));
 
-      end_cleanup_deferral ();
-
       if (count == 0)
        {
          expand_expr (index_expr, const0_rtx, VOIDmode, 0);
-         emit_queue ();
          emit_jump (default_label);
        }
 
@@ -4584,11 +3480,9 @@ expand_end_case_type (tree orig_index, tree orig_type)
                  }
            }
 
-         emit_queue ();
          do_pending_stack_adjust ();
 
-         index = protect_from_queue (index, 0);
-         if (GET_CODE (index) == MEM)
+         if (MEM_P (index))
            index = copy_to_reg (index);
          if (GET_CODE (index) == CONST_INT
              || TREE_CODE (index_expr) == INTEGER_CST)
@@ -4724,8 +3618,6 @@ expand_end_case_type (tree orig_index, tree orig_type)
       reorder_insns (before_case, end,
                     thiscase->data.case_stmt.start);
     }
-  else
-    end_cleanup_deferral ();
 
   if (thiscase->exit_label && !exit_done)
     emit_label (thiscase->exit_label);
@@ -5175,7 +4067,7 @@ node_is_bounded (case_node_ptr node, tree index_type)
 static void
 emit_jump_if_reachable (rtx label)
 {
-  if (GET_CODE (get_last_insn ()) != BARRIER)
+  if (!BARRIER_P (get_last_insn ()))
     emit_jump (label);
 }
 \f