function.c (assign_parms): Save and restore setting of TREE_USED (parm).
[gcc.git] / gcc / function.c
index d4f29dbf73f49d277c5edd85a17633369a9b2e1a..1cb8c44bbcd3829d2c47d8cf45eeb56e5268edd7 100644 (file)
@@ -1,5 +1,5 @@
 /* Expands front end tree to back end RTL for GNU C-Compiler
-   Copyright (C) 1987, 88, 89, 91-97, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 89, 91-98, 1999 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -57,6 +57,10 @@ Boston, MA 02111-1307, USA.  */
 #include "obstack.h"
 #include "toplev.h"
 
+#if !defined PREFERRED_STACK_BOUNDARY && defined STACK_BOUNDARY
+#define PREFERRED_STACK_BOUNDARY STACK_BOUNDARY
+#endif
+
 #ifndef TRAMPOLINE_ALIGNMENT
 #define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
 #endif
@@ -138,6 +142,12 @@ int current_function_has_computed_jump;
 
 int current_function_contains_functions;
 
+/* Nonzero if function being compiled doesn't modify the stack pointer
+   (ignoring the prologue and epilogue).  This is only valid after
+   life_analysis has run. */
+
+int current_function_sp_is_unchanging;
+
 /* Nonzero if the current function is a thunk (a lightweight function that
    just adjusts one of its arguments and forwards to another function), so
    we should try to cut corners where we can.  */
@@ -221,6 +231,9 @@ char *current_function_cannot_inline;
    generated.  */
 int current_function_instrument_entry_exit;
 
+/* Nonzero if memory access checking be enabled in the current function.  */
+int current_function_check_memory_usage;
+
 /* The FUNCTION_DECL for an inline function currently being expanded.  */
 tree inline_function_decl;
 
@@ -234,10 +247,12 @@ int function_call_count;
 
 tree nonlocal_labels;
 
-/* RTX for stack slot that holds the current handler for nonlocal gotos.
+/* List (chain of EXPR_LIST) of stack slots that hold the current handlers
+   for nonlocal gotos.  There is one for every nonlocal label in the function;
+   this list matches the one in nonlocal_labels.
    Zero when function does not have nonlocal labels.  */
 
-rtx nonlocal_goto_handler_slot;
+rtx nonlocal_goto_handler_slots;
 
 /* RTX for stack slot that holds the stack pointer value to restore
    for a nonlocal goto.
@@ -519,7 +534,7 @@ push_function_context_to (context)
   p->parm_reg_stack_loc = parm_reg_stack_loc;
   p->outgoing_args_size = current_function_outgoing_args_size;
   p->return_rtx = current_function_return_rtx;
-  p->nonlocal_goto_handler_slot = nonlocal_goto_handler_slot;
+  p->nonlocal_goto_handler_slots = nonlocal_goto_handler_slots;
   p->nonlocal_goto_stack_level = nonlocal_goto_stack_level;
   p->nonlocal_labels = nonlocal_labels;
   p->cleanup_label = cleanup_label;
@@ -543,6 +558,7 @@ push_function_context_to (context)
   p->fixup_var_refs_queue = 0;
   p->epilogue_delay_list = current_function_epilogue_delay_list;
   p->args_info = current_function_args_info;
+  p->check_memory_usage = current_function_check_memory_usage;
   p->instrument_entry_exit = current_function_instrument_entry_exit;
 
   save_tree_status (p, context);
@@ -602,7 +618,7 @@ pop_function_context_from (context)
   parm_reg_stack_loc = p->parm_reg_stack_loc;
   current_function_outgoing_args_size = p->outgoing_args_size;
   current_function_return_rtx = p->return_rtx;
-  nonlocal_goto_handler_slot = p->nonlocal_goto_handler_slot;
+  nonlocal_goto_handler_slots = p->nonlocal_goto_handler_slots;
   nonlocal_goto_stack_level = p->nonlocal_goto_stack_level;
   nonlocal_labels = p->nonlocal_labels;
   cleanup_label = p->cleanup_label;
@@ -626,6 +642,7 @@ pop_function_context_from (context)
   current_function_epilogue_delay_list = p->epilogue_delay_list;
   reg_renumber = 0;
   current_function_args_info = p->args_info;
+  current_function_check_memory_usage = p->check_memory_usage;
   current_function_instrument_entry_exit = p->instrument_entry_exit;
 
   restore_tree_status (p, context);
@@ -658,7 +675,7 @@ void pop_function_context ()
 /* Allocate fixed slots in the stack frame of the current function.  */
 
 /* Return size needed for stack frame based on slots so far allocated.
-   This size counts from zero.  It is not rounded to STACK_BOUNDARY;
+   This size counts from zero.  It is not rounded to PREFERRED_STACK_BOUNDARY;
    the caller may have to do that.  */
 
 HOST_WIDE_INT
@@ -951,6 +968,8 @@ assign_stack_temp (mode, size, keep)
      set from before.  */
   RTX_UNCHANGING_P (p->slot) = 0;
   MEM_IN_STRUCT_P (p->slot) = 0;
+  MEM_SCALAR_P (p->slot) = 0;
+  MEM_ALIAS_SET (p->slot) = 0;
   return p->slot;
 }
 \f
@@ -986,7 +1005,7 @@ assign_temp (type, keep, memory_required, dont_promote)
        size = TREE_INT_CST_LOW (TYPE_ARRAY_MAX_SIZE (type));
 
       tmp = assign_stack_temp (mode, size, keep);
-      MEM_IN_STRUCT_P (tmp) = AGGREGATE_TYPE_P (type);
+      MEM_SET_IN_STRUCT_P (tmp, AGGREGATE_TYPE_P (type));
       return tmp;
     }
 
@@ -1484,7 +1503,7 @@ put_var_into_stack (decl)
   else
     return;
   
-  if (flag_check_memory_usage)
+  if (current_function_check_memory_usage)
     emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
                       XEXP (reg, 0), ptr_mode,
                       GEN_INT (GET_MODE_SIZE (GET_MODE (reg))),
@@ -1544,7 +1563,8 @@ put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
      previously generated stack slot, then we need to copy the bit in
      case it was set for other reasons.  For instance, it is set for
      __builtin_va_alist.  */
-  MEM_IN_STRUCT_P (reg) = AGGREGATE_TYPE_P (type) | MEM_IN_STRUCT_P (new);
+  MEM_SET_IN_STRUCT_P (reg,
+                      AGGREGATE_TYPE_P (type) || MEM_IN_STRUCT_P (new));
   MEM_ALIAS_SET (reg) = get_alias_set (type);
 
   /* Now make sure that all refs to the variable, previously made
@@ -2008,8 +2028,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
                  newmem = gen_rtx_MEM (wanted_mode,
                                        plus_constant (XEXP (tem, 0), offset));
                  RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (tem);
-                 MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (tem);
-                 MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (tem);
+                 MEM_COPY_ATTRIBUTES (newmem, tem);
 
                  /* Make the change and see if the insn remains valid.  */
                  INSN_CODE (insn) = -1;
@@ -2200,8 +2219,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
                    newmem = gen_rtx_MEM (wanted_mode,
                                          plus_constant (XEXP (tem, 0), offset));
                    RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (tem);
-                   MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (tem);
-                   MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (tem);
+                   MEM_COPY_ATTRIBUTES (newmem, tem);
 
                    /* Make the change and see if the insn remains valid.  */
                    INSN_CODE (insn) = -1;
@@ -2766,7 +2784,7 @@ gen_mem_addressof (reg, decl)
   PUT_CODE (reg, MEM);
   PUT_MODE (reg, DECL_MODE (decl));
   MEM_VOLATILE_P (reg) = TREE_SIDE_EFFECTS (decl);
-  MEM_IN_STRUCT_P (reg) = AGGREGATE_TYPE_P (type);
+  MEM_SET_IN_STRUCT_P (reg, AGGREGATE_TYPE_P (type));
   MEM_ALIAS_SET (reg) = get_alias_set (decl);
 
   if (TREE_USED (decl) || DECL_INITIAL (decl) != 0)
@@ -2807,6 +2825,10 @@ put_addressof_into_stack (r)
                      TREE_USED (decl) || DECL_INITIAL (decl) != 0);
 }
 
+/* List of replacements made below in purge_addressof_1 when creating
+   bitfield insertions.  */
+static rtx purge_addressof_replacements;
+
 /* Helper function for purge_addressof.  See if the rtx expression at *LOC
    in INSN needs to be changed.  If FORCE, always put any ADDRESSOFs into
    the stack.  */
@@ -2849,7 +2871,7 @@ purge_addressof_1 (loc, insn, force, store)
 
       insns = gen_sequence ();
       end_sequence ();
-      emit_insns_before (insns, insn);
+      emit_insn_before (insns, insn);
       return;
     }
   else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force)
@@ -2869,48 +2891,95 @@ purge_addressof_1 (loc, insn, force, store)
        {
          int size_x, size_sub;
 
+         if (!insn)
+           {
+             /* When processing REG_NOTES look at the list of
+                replacements done on the insn to find the register that X
+                was replaced by.  */
+             rtx tem;
+
+             for (tem = purge_addressof_replacements; tem != NULL_RTX;
+                  tem = XEXP (XEXP (tem, 1), 1))
+               {
+                 rtx y = XEXP (tem, 0);
+                 if (GET_CODE (y) == MEM
+                     && rtx_equal_p (XEXP (x, 0), XEXP (y, 0)))
+                   {
+                     /* It can happen that the note may speak of things in
+                        a wider (or just different) mode than the code did. 
+                        This is especially true of REG_RETVAL.  */
+
+                     rtx z = XEXP (XEXP (tem, 1), 0);
+                     if (GET_MODE (x) != GET_MODE (y))
+                       {
+                         if (GET_CODE (z) == SUBREG && SUBREG_WORD (z) == 0)
+                           z = SUBREG_REG (z);
+
+                         /* ??? If we'd gotten into any of the really complex
+                            cases below, I'm not sure we can do a proper
+                            replacement.  Might we be able to delete the
+                            note in some cases?  */
+                         if (GET_MODE_SIZE (GET_MODE (x))
+                             < GET_MODE_SIZE (GET_MODE (y)))
+                           abort ();
+
+                         z = gen_lowpart (GET_MODE (x), z);
+                       }
+
+                     *loc = z;
+                     return;
+                   }
+               }
+
+             /* There should always be such a replacement.  */
+             abort ();
+           }
+
          size_x = GET_MODE_BITSIZE (GET_MODE (x));
          size_sub = GET_MODE_BITSIZE (GET_MODE (sub));
 
          /* Don't even consider working with paradoxical subregs,
             or the moral equivalent seen here.  */
-         if (size_x < size_sub)
+         if (size_x <= size_sub
+             && int_mode_for_mode (GET_MODE (sub)) != BLKmode)
            {
              /* Do a bitfield insertion to mirror what would happen
                 in memory.  */
 
-             int bitpos;
              rtx val, seq;
 
-             bitpos = 0;
-             if (WORDS_BIG_ENDIAN)
-               {
-                 bitpos += (size_sub / BITS_PER_WORD) * BITS_PER_WORD;
-                 bitpos -= (size_x / BITS_PER_WORD) * BITS_PER_WORD;
-               }
-             if (BYTES_BIG_ENDIAN)
-               {
-                 bitpos += size_sub % BITS_PER_WORD;
-                 bitpos -= size_x % BITS_PER_WORD;
-               }
-
              if (store)
                {
-                 /* If we can't replace with a register, be afraid.  */
+                 rtx p;
 
                  start_sequence ();
                  val = gen_reg_rtx (GET_MODE (x));
                  if (! validate_change (insn, loc, val, 0))
-                   abort ();
+                   {
+                     /* Discard the current sequence and put the
+                        ADDRESSOF on stack.  */
+                     end_sequence ();
+                     goto give_up;
+                   }
                  seq = gen_sequence ();
                  end_sequence ();
                  emit_insn_before (seq, insn);
              
                  start_sequence ();
-                 store_bit_field (sub, size_x, bitpos, GET_MODE (x),
+                 store_bit_field (sub, size_x, 0, GET_MODE (x),
                                   val, GET_MODE_SIZE (GET_MODE (sub)),
                                   GET_MODE_SIZE (GET_MODE (sub)));
 
+                 /* Make sure to unshare any shared rtl that store_bit_field
+                    might have created.  */
+                 for (p = get_insns(); p; p = NEXT_INSN (p))
+                   {
+                     reset_used_flags (PATTERN (p));
+                     reset_used_flags (REG_NOTES (p));
+                     reset_used_flags (LOG_LINKS (p));
+                   }
+                 unshare_all_rtl (get_insns ());
+
                  seq = gen_sequence ();
                  end_sequence ();
                  emit_insn_after (seq, insn);
@@ -2918,26 +2987,46 @@ purge_addressof_1 (loc, insn, force, store)
              else
                {
                  start_sequence ();
-                 val = extract_bit_field (sub, size_x, bitpos, 1, NULL_RTX,
+                 val = extract_bit_field (sub, size_x, 0, 1, NULL_RTX,
                                           GET_MODE (x), GET_MODE (x),
                                           GET_MODE_SIZE (GET_MODE (sub)),
                                           GET_MODE_SIZE (GET_MODE (sub)));
 
-                 /* If we can't replace with a register, be afraid.  */
                  if (! validate_change (insn, loc, val, 0))
-                   abort ();
+                   {
+                     /* Discard the current sequence and put the
+                        ADDRESSOF on stack.  */
+                     end_sequence ();
+                     goto give_up;
+                   }
 
                  seq = gen_sequence ();
                  end_sequence ();
                  emit_insn_before (seq, insn);
                }
 
+             /* Remember the replacement so that the same one can be done
+                on the REG_NOTES.  */
+             purge_addressof_replacements
+               = gen_rtx_EXPR_LIST (VOIDmode, x,
+                                    gen_rtx_EXPR_LIST (VOIDmode, val,
+                                                       purge_addressof_replacements));
+
              /* We replaced with a reg -- all done.  */
              return;
            }
        }
       else if (validate_change (insn, loc, sub, 0))
-       goto restart;
+       {
+         /* Remember the replacement so that the same one can be done
+            on the REG_NOTES.  */
+         purge_addressof_replacements
+           = gen_rtx_EXPR_LIST (VOIDmode, x,
+                                gen_rtx_EXPR_LIST (VOIDmode, sub,
+                                                   purge_addressof_replacements));
+         goto restart;
+       }
+    give_up:;
       /* else give up and put it into the stack */
     }
   else if (code == ADDRESSOF)
@@ -2981,6 +3070,7 @@ purge_addressof (insns)
                           asm_noperands (PATTERN (insn)) > 0, 0);
        purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0);
       }
+  purge_addressof_replacements = 0;
 }
 \f
 /* Pass through the INSNS of function FNDECL and convert virtual register
@@ -3610,13 +3700,22 @@ delete_handlers ()
                TREE_CHAIN (last_t) = TREE_CHAIN (t);
            }
        }
-      if (GET_CODE (insn) == INSN
-         && ((nonlocal_goto_handler_slot != 0
-              && reg_mentioned_p (nonlocal_goto_handler_slot, PATTERN (insn)))
+      if (GET_CODE (insn) == INSN)
+       {
+         int can_delete = 0;
+         rtx t;
+         for (t = nonlocal_goto_handler_slots; t != 0; t = XEXP (t, 1))
+           if (reg_mentioned_p (t, PATTERN (insn)))
+             {
+               can_delete = 1;
+               break;
+             }
+         if (can_delete
              || (nonlocal_goto_stack_level != 0
                  && reg_mentioned_p (nonlocal_goto_stack_level,
-                                     PATTERN (insn)))))
-       delete_insn (insn);
+                                     PATTERN (insn))))
+           delete_insn (insn);
+       }
     }
 }
 
@@ -4016,7 +4115,7 @@ assign_parms (fndecl, second_time)
          /* If this is a memory ref that contains aggregate components,
             mark it as such for cse and loop optimize.  Likewise if it
             is readonly.  */
-         MEM_IN_STRUCT_P (stack_parm) = aggregate;
+         MEM_SET_IN_STRUCT_P (stack_parm, aggregate);
          RTX_UNCHANGING_P (stack_parm) = TREE_READONLY (parm);
          MEM_ALIAS_SET (stack_parm) = get_alias_set (parm);
        }
@@ -4156,7 +4255,7 @@ assign_parms (fndecl, second_time)
 
          /* If this is a memory ref that contains aggregate components,
             mark it as such for cse and loop optimize.  */
-         MEM_IN_STRUCT_P (stack_parm) = aggregate;
+         MEM_SET_IN_STRUCT_P (stack_parm, aggregate);
        }
 #endif /* 0 */
 
@@ -4213,7 +4312,7 @@ assign_parms (fndecl, second_time)
 
                  /* If this is a memory ref that contains aggregate
                     components, mark it as such for cse and loop optimize.  */
-                 MEM_IN_STRUCT_P (stack_parm) = aggregate;
+                 MEM_SET_IN_STRUCT_P (stack_parm, aggregate);
                }
 
              else if (PARM_BOUNDARY % BITS_PER_WORD != 0)
@@ -4270,7 +4369,7 @@ assign_parms (fndecl, second_time)
            {
              DECL_RTL (parm)
                = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (passed_type)), parmreg);
-             MEM_IN_STRUCT_P (DECL_RTL (parm)) = aggregate;
+             MEM_SET_IN_STRUCT_P (DECL_RTL (parm), aggregate);
            }
          else
            DECL_RTL (parm) = parmreg;
@@ -4279,6 +4378,7 @@ assign_parms (fndecl, second_time)
          if (nominal_mode != passed_mode
              || promoted_nominal_mode != promoted_mode)
            {
+             int save_tree_used;
              /* ENTRY_PARM has been converted to PROMOTED_MODE, its
                 mode, by the caller.  We now have to convert it to 
                 NOMINAL_MODE, if different.  However, PARMREG may be in
@@ -4305,8 +4405,11 @@ assign_parms (fndecl, second_time)
              push_to_sequence (conversion_insns);
              tempreg = convert_to_mode (nominal_mode, tempreg, unsignedp);
 
+             /* TREE_USED gets set erroneously during expand_assignment.  */
+             save_tree_used = TREE_USED (parm);
              expand_assignment (parm,
                                 make_tree (nominal_type, tempreg), 0, 0);
+             TREE_USED (parm) = save_tree_used;
              conversion_insns = get_insns ();
              did_conversion = 1;
              end_sequence ();
@@ -4371,12 +4474,12 @@ assign_parms (fndecl, second_time)
              else
                copy = assign_stack_temp (TYPE_MODE (type),
                                          int_size_in_bytes (type), 1);
-             MEM_IN_STRUCT_P (copy) = AGGREGATE_TYPE_P (type);
+             MEM_SET_IN_STRUCT_P (copy, AGGREGATE_TYPE_P (type));
              RTX_UNCHANGING_P (copy) = TREE_READONLY (parm);
 
              store_expr (parm, copy, 0);
              emit_move_insn (parmreg, XEXP (copy, 0));
-             if (flag_check_memory_usage)
+             if (current_function_check_memory_usage)
                emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
                                   XEXP (copy, 0), ptr_mode,
                                   GEN_INT (int_size_in_bytes (type)),
@@ -4526,7 +4629,7 @@ assign_parms (fndecl, second_time)
                                          GET_MODE_SIZE (GET_MODE (entry_parm)), 0);
                  /* If this is a memory ref that contains aggregate components,
                     mark it as such for cse and loop optimize.  */
-                 MEM_IN_STRUCT_P (stack_parm) = aggregate;
+                 MEM_SET_IN_STRUCT_P (stack_parm, aggregate);
                }
 
              if (promoted_mode != nominal_mode)
@@ -4541,7 +4644,7 @@ assign_parms (fndecl, second_time)
                emit_move_insn (validize_mem (stack_parm),
                                validize_mem (entry_parm));
            }
-         if (flag_check_memory_usage)
+         if (current_function_check_memory_usage)
            {
              push_to_sequence (conversion_insns);
              emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
@@ -4568,7 +4671,8 @@ assign_parms (fndecl, second_time)
          DECL_RTL (result)
            = gen_rtx_MEM (DECL_MODE (result), DECL_RTL (parm));
 
-         MEM_IN_STRUCT_P (DECL_RTL (result)) = AGGREGATE_TYPE_P (restype);
+         MEM_SET_IN_STRUCT_P (DECL_RTL (result), 
+                              AGGREGATE_TYPE_P (restype));
        }
 
       if (TREE_THIS_VOLATILE (parm))
@@ -4595,8 +4699,8 @@ assign_parms (fndecl, second_time)
 #endif
 #endif
 
-#ifdef STACK_BOUNDARY
-#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
+#ifdef PREFERRED_STACK_BOUNDARY
+#define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
 
   current_function_args_size
     = ((current_function_args_size + STACK_BYTES - 1)
@@ -4902,6 +5006,14 @@ uninitialized_vars_warning (block)
          && ! AGGREGATE_TYPE_P (TREE_TYPE (decl))
          && DECL_RTL (decl) != 0
          && GET_CODE (DECL_RTL (decl)) == REG
+         /* Global optimizations can make it difficult to determine if a
+            particular variable has been initialized.  However, a VAR_DECL
+            with a nonzero DECL_INITIAL had an initializer, so do not
+            claim it is potentially uninitialized.
+
+            We do not care about the actual value in DECL_INITIAL, so we do
+            not worry that it may be a dangling pointer.  */
+         && DECL_INITIAL (decl) == NULL_TREE
          && regno_uninitialized (REGNO (DECL_RTL (decl))))
        warning_with_decl (decl,
                           "`%s' might be used uninitialized in this function");
@@ -5390,7 +5502,7 @@ init_function_start (subr, filename, line)
   stack_slot_list = 0;
 
   /* There is no stack slot for handling nonlocal gotos.  */
-  nonlocal_goto_handler_slot = 0;
+  nonlocal_goto_handler_slots = 0;
   nonlocal_goto_stack_level = 0;
 
   /* No labels have been declared for nonlocal use.  */
@@ -5433,6 +5545,7 @@ init_function_start (subr, filename, line)
   current_function_has_nonlocal_label = 0;
   current_function_has_nonlocal_goto = 0;
   current_function_contains_functions = 0;
+  current_function_sp_is_unchanging = 0;
   current_function_is_thunk = 0;
 
   current_function_returns_pcc_struct = 0;
@@ -5562,6 +5675,11 @@ expand_function_start (subr, parms_have_cleanups)
      valid operands of arithmetic insns.  */
   init_recog_no_volatile ();
 
+  /* Set this before generating any memory accesses.  */
+  current_function_check_memory_usage
+    = (flag_check_memory_usage
+       && ! DECL_NO_CHECK_MEMORY_USAGE (current_function_decl));
+
   current_function_instrument_entry_exit
     = (flag_instrument_function_entry_exit
        && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (subr));
@@ -5634,8 +5752,10 @@ expand_function_start (subr, parms_have_cleanups)
        {
          DECL_RTL (DECL_RESULT (subr))
            = gen_rtx_MEM (DECL_MODE (DECL_RESULT (subr)), value_address);
-         MEM_IN_STRUCT_P (DECL_RTL (DECL_RESULT (subr)))
-           = AGGREGATE_TYPE_P (TREE_TYPE (DECL_RESULT (subr)));
+         MEM_SET_IN_STRUCT_P (DECL_RTL (DECL_RESULT (subr)),
+                              AGGREGATE_TYPE_P (TREE_TYPE
+                                                (DECL_RESULT
+                                                 (subr))));
        }
     }
   else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode)
@@ -5904,7 +6024,8 @@ expand_function_end (filename, line, end_bindings)
     }
 
   /* Delete handlers for nonlocal gotos if nothing uses them.  */
-  if (nonlocal_goto_handler_slot != 0 && !current_function_has_nonlocal_label)
+  if (nonlocal_goto_handler_slots != 0
+      && ! current_function_has_nonlocal_label)
     delete_handlers ();
 
   /* End any sequences that failed to be closed due to syntax errors.  */
@@ -6172,7 +6293,7 @@ contains (insn, vec)
 
 void
 thread_prologue_and_epilogue_insns (f)
-     rtx f;
+     rtx f ATTRIBUTE_UNUSED;
 {
 #ifdef HAVE_prologue
   if (HAVE_prologue)
@@ -6187,9 +6308,9 @@ thread_prologue_and_epilogue_insns (f)
 
       /* Include the new prologue insns in the first block.  Ignore them
         if they form a basic block unto themselves.  */
-      if (basic_block_head && n_basic_blocks
-         && GET_CODE (basic_block_head[0]) != CODE_LABEL)
-       basic_block_head[0] = NEXT_INSN (f);
+      if (x_basic_block_head && n_basic_blocks
+         && GET_CODE (BLOCK_HEAD (0)) != CODE_LABEL)
+       BLOCK_HEAD (0) = NEXT_INSN (f);
 
       /* Retain a map of the prologue insns.  */
       prologue = record_insns (GET_CODE (seq) == SEQUENCE ? seq : head);
@@ -6255,9 +6376,9 @@ thread_prologue_and_epilogue_insns (f)
 
          /* Include the new epilogue insns in the last block.  Ignore
             them if they form a basic block unto themselves.  */
-         if (basic_block_end && n_basic_blocks
-             && GET_CODE (basic_block_end[n_basic_blocks - 1]) != JUMP_INSN)
-           basic_block_end[n_basic_blocks - 1] = tail;
+         if (x_basic_block_end && n_basic_blocks
+             && GET_CODE (BLOCK_END (n_basic_blocks - 1)) != JUMP_INSN)
+           BLOCK_END (n_basic_blocks - 1) = tail;
 
          /* Retain a map of the epilogue insns.  */
          epilogue = record_insns (GET_CODE (seq) == SEQUENCE ? seq : tail);
@@ -6273,7 +6394,7 @@ thread_prologue_and_epilogue_insns (f)
 
 void
 reposition_prologue_and_epilogue_notes (f)
-     rtx f;
+     rtx f ATTRIBUTE_UNUSED;
 {
 #if defined (HAVE_prologue) || defined (HAVE_epilogue)
   /* Reposition the prologue and epilogue notes.  */
@@ -6317,10 +6438,10 @@ reposition_prologue_and_epilogue_notes (f)
                  if (next)
                    PREV_INSN (next) = prev;
 
-                 /* Whether or not we can depend on basic_block_head
+                 /* Whether or not we can depend on BLOCK_HEAD
                     attempt to keep it up-to-date.  */
-                 if (basic_block_head[0] == note)
-                   basic_block_head[0] = next;
+                 if (BLOCK_HEAD (0) == note)
+                   BLOCK_HEAD (0) = next;
 
                  add_insn_after (note, insn);
                }
@@ -6361,11 +6482,11 @@ reposition_prologue_and_epilogue_notes (f)
                  if (next)
                    PREV_INSN (next) = prev;
 
-                 /* Whether or not we can depend on basic_block_head
+                 /* Whether or not we can depend on BLOCK_HEAD
                     attempt to keep it up-to-date.  */
                  if (n_basic_blocks
-                     && basic_block_head[n_basic_blocks-1] == insn)
-                   basic_block_head[n_basic_blocks-1] = note;
+                     && BLOCK_HEAD (n_basic_blocks-1) == insn)
+                   BLOCK_HEAD (n_basic_blocks-1) = note;
 
                  add_insn_before (note, insn);
                }