]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/function.c
* reorg.c: Finish deleting half-deleted comment.
[gcc.git] / gcc / function.c
index 5ad113cfc9372cf28961bce14e30cb0fd77a5d8b..c9ec569c57063c47a1b277017d6fe0a042bdafb2 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,16 @@ 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 function being compiled issues a computed jump.  */
+
+int current_function_has_computed_jump;
+
 /* 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 +235,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 +251,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.
@@ -505,6 +524,7 @@ push_function_context_to (context)
   p->has_nonlocal_label = current_function_has_nonlocal_label;
   p->has_nonlocal_goto = current_function_has_nonlocal_goto;
   p->contains_functions = current_function_contains_functions;
+  p->has_computed_jump = current_function_has_computed_jump;
   p->is_thunk = current_function_is_thunk;
   p->args_size = current_function_args_size;
   p->pretend_args_size = current_function_pretend_args_size;
@@ -519,7 +539,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 +563,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);
@@ -576,6 +597,7 @@ pop_function_context_from (context)
   current_function_contains_functions
     = p->contains_functions || p->inline_obstacks
       || context == current_function_decl;
+  current_function_has_computed_jump = p->has_computed_jump;
   current_function_name = p->name;
   current_function_decl = p->decl;
   current_function_pops_args = p->pops_args;
@@ -602,7 +624,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 +648,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 +681,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 +974,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 +1011,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 +1509,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 +1569,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
@@ -1611,6 +1637,11 @@ fixup_var_refs (var, promoted_mode, unsignedp)
          end_sequence ();
        }
     }
+
+  /* Scan the catch clauses for exception handling too.  */
+  push_to_sequence (catch_clauses);
+  fixup_var_refs_insns (var, promoted_mode, unsignedp, catch_clauses, 0);
+  end_sequence ();
 }
 \f
 /* REPLACEMENTS is a pointer to a list of the struct fixup_replacement and X is
@@ -2008,8 +2039,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 +2230,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;
@@ -2652,7 +2681,9 @@ optimize_bit_field (body, insn, equiv_mem)
              while (GET_CODE (dest) == SUBREG
                     && SUBREG_WORD (dest) == 0
                     && (GET_MODE_CLASS (GET_MODE (dest))
-                        == GET_MODE_CLASS (GET_MODE (SUBREG_REG (dest)))))
+                        == GET_MODE_CLASS (GET_MODE (SUBREG_REG (dest))))
+                    && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
+                        <= UNITS_PER_WORD))
                dest = SUBREG_REG (dest);
 
              validate_change (insn, &SET_DEST (body), dest, 1);
@@ -2766,7 +2797,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 +2838,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.  */
@@ -2838,26 +2873,33 @@ purge_addressof_1 (loc, insn, force, store)
         overwriting a REG rtx which is always shared.  */
       rtx sub = copy_rtx (XEXP (XEXP (x, 0), 0));
 
-      if (validate_change (insn, loc, sub, 0))
+      if (validate_change (insn, loc, sub, 0)
+         || validate_replace_rtx (x, sub, insn))
        return;
-
+  
       start_sequence ();
-      if (! validate_change (insn, loc,
-                            force_operand (sub, NULL_RTX),
-                            0))
+      sub = force_operand (sub, NULL_RTX);
+      if (! validate_change (insn, loc, sub, 0)
+         && ! validate_replace_rtx (x, sub, insn))
        abort ();
 
       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)
     {
       rtx sub = XEXP (XEXP (x, 0), 0);
+      rtx sub2;
 
       if (GET_CODE (sub) == MEM)
-       sub = gen_rtx_MEM (GET_MODE (x), copy_rtx (XEXP (sub, 0)));
+       {
+         sub2 = gen_rtx_MEM (GET_MODE (x), copy_rtx (XEXP (sub, 0)));
+         MEM_COPY_ATTRIBUTES (sub2, sub);
+         RTX_UNCHANGING_P (sub2) = RTX_UNCHANGING_P (sub);
+         sub = sub2;
+       }
 
       if (GET_CODE (sub) == REG
          && (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode))
@@ -2869,12 +2911,69 @@ 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 ();
+
+                         if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
+                             && (GET_MODE_SIZE (GET_MODE (x))
+                                 > GET_MODE_SIZE (GET_MODE (z))))
+                           {
+                             /* This can occur as a result in invalid
+                                pointer casts, e.g. float f; ... 
+                                *(long long int *)&f.
+                                ??? We could emit a warning here, but
+                                without a line number that wouldn't be
+                                very helpful.  */
+                             z = gen_rtx_SUBREG (GET_MODE (x), z, 0);
+                           }
+                         else
+                           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
@@ -2884,12 +2983,17 @@ purge_addressof_1 (loc, insn, force, store)
 
              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);
@@ -2899,6 +3003,16 @@ purge_addressof_1 (loc, insn, force, store)
                                   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);
@@ -2911,21 +3025,41 @@ purge_addressof_1 (loc, insn, force, store)
                                           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)
@@ -2969,6 +3103,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
@@ -3598,13 +3733,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);
+       }
     }
 }
 
@@ -3972,7 +4116,7 @@ assign_parms (fndecl, second_time)
         In this case, we call FUNCTION_ARG with NAMED set to 1 instead of
         0 as it was the previous time.  */
 
-      locate_and_pad_parm (promoted_mode, passed_type,
+      locate_and_pad_parm (nominal_mode, passed_type,
 #ifdef STACK_PARMS_IN_REG_PARM_AREA
                           1,
 #else
@@ -3994,9 +4138,9 @@ assign_parms (fndecl, second_time)
          rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);
 
          if (offset_rtx == const0_rtx)
-           stack_parm = gen_rtx_MEM (promoted_mode, internal_arg_pointer);
+           stack_parm = gen_rtx_MEM (nominal_mode, internal_arg_pointer);
          else
-           stack_parm = gen_rtx_MEM (promoted_mode,
+           stack_parm = gen_rtx_MEM (nominal_mode,
                                      gen_rtx_PLUS (Pmode,
                                                    internal_arg_pointer,
                                                    offset_rtx));
@@ -4004,7 +4148,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);
        }
@@ -4068,6 +4212,8 @@ assign_parms (fndecl, second_time)
         to indicate there is no preallocated stack slot for the parm.  */
 
       if (entry_parm == stack_parm
+          || (GET_CODE (entry_parm) == PARALLEL
+              && XEXP (XVECEXP (entry_parm, 0, 0), 0) == NULL_RTX)
 #if defined (REG_PARM_STACK_SPACE) && ! defined (MAYBE_REG_PARM_STACK_SPACE)
          /* On some machines, even if a parm value arrives in a register
             there is still an (uninitialized) stack slot allocated for it.
@@ -4144,7 +4290,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 */
 
@@ -4201,7 +4347,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)
@@ -4258,7 +4404,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;
@@ -4267,6 +4413,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
@@ -4293,8 +4440,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 ();
@@ -4359,12 +4509,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)),
@@ -4514,7 +4664,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)
@@ -4529,7 +4679,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,
@@ -4556,7 +4706,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))
@@ -4583,8 +4734,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)
@@ -4890,6 +5041,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");
@@ -5378,7 +5537,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.  */
@@ -5421,6 +5580,8 @@ 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_has_computed_jump = 0;
   current_function_is_thunk = 0;
 
   current_function_returns_pcc_struct = 0;
@@ -5550,6 +5711,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));
@@ -5622,8 +5788,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)
@@ -5815,8 +5983,15 @@ expand_function_end (filename, line, end_bindings)
   /* Save the argument pointer if a save area was made for it.  */
   if (arg_pointer_save_area)
     {
-      rtx x = gen_move_insn (arg_pointer_save_area, virtual_incoming_args_rtx);
-      emit_insn_before (x, tail_recursion_reentry);
+      /* arg_pointer_save_area may not be a valid memory address, so we
+        have to check it and fix it if necessary.  */
+      rtx seq;
+      start_sequence ();
+      emit_move_insn (validize_mem (arg_pointer_save_area),
+                     virtual_incoming_args_rtx);
+      seq = gen_sequence ();
+      end_sequence ();
+      emit_insn_before (seq, tail_recursion_reentry);
     }
 
   /* Initialize any trampolines required by this function.  */
@@ -5892,7 +6067,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.  */
@@ -6160,7 +6336,7 @@ contains (insn, vec)
 
 void
 thread_prologue_and_epilogue_insns (f)
-     rtx f;
+     rtx f ATTRIBUTE_UNUSED;
 {
 #ifdef HAVE_prologue
   if (HAVE_prologue)
@@ -6175,9 +6351,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);
@@ -6243,9 +6419,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);
@@ -6261,13 +6437,12 @@ 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.  */
   if (n_basic_blocks)
     {
-      rtx next, prev;
       int len;
 
       if (prologue)
@@ -6288,6 +6463,7 @@ reposition_prologue_and_epilogue_notes (f)
                }
              else if ((len -= contains (insn, prologue)) == 0)
                {
+                 rtx next;
                  /* Find the prologue-end note if we haven't already, and
                     move it to just after the last prologue insn.  */
                  if (note == 0)
@@ -6299,17 +6475,13 @@ reposition_prologue_and_epilogue_notes (f)
                    }
 
                  next = NEXT_INSN (note);
-                 prev = PREV_INSN (note);
-                 if (prev)
-                   NEXT_INSN (prev) = next;
-                 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;
 
+                 remove_insn (note);
                  add_insn_after (note, insn);
                }
            }
@@ -6342,19 +6514,14 @@ reposition_prologue_and_epilogue_notes (f)
                            && NOTE_LINE_NUMBER (note) == NOTE_INSN_EPILOGUE_BEG)
                          break;
                    }
-                 next = NEXT_INSN (note);
-                 prev = PREV_INSN (note);
-                 if (prev)
-                   NEXT_INSN (prev) = next;
-                 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;
 
+                 remove_insn (note);
                  add_insn_before (note, insn);
                }
            }
This page took 0.053601 seconds and 5 git commands to generate.