]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/function.c
* reorg.c: Finish deleting half-deleted comment.
[gcc.git] / gcc / function.c
index 1cb8c44bbcd3829d2c47d8cf45eeb56e5268edd7..c9ec569c57063c47a1b277017d6fe0a042bdafb2 100644 (file)
@@ -148,6 +148,10 @@ int current_function_contains_functions;
 
 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.  */
@@ -520,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;
@@ -592,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;
@@ -1631,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
@@ -2670,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);
@@ -2860,13 +2873,14 @@ 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 ();
@@ -2877,9 +2891,15 @@ purge_addressof_1 (loc, insn, force, store)
   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))
@@ -2923,7 +2943,20 @@ purge_addressof_1 (loc, insn, force, store)
                              < GET_MODE_SIZE (GET_MODE (y)))
                            abort ();
 
-                         z = gen_lowpart (GET_MODE (x), z);
+                         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;
@@ -4083,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
@@ -4105,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));
@@ -4179,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.
@@ -5546,6 +5581,7 @@ init_function_start (subr, filename, line)
   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;
@@ -5947,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.  */
@@ -6400,7 +6443,6 @@ reposition_prologue_and_epilogue_notes (f)
   /* Reposition the prologue and epilogue notes.  */
   if (n_basic_blocks)
     {
-      rtx next, prev;
       int len;
 
       if (prologue)
@@ -6421,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)
@@ -6432,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 BLOCK_HEAD, 
                     attempt to keep it up-to-date.  */
                  if (BLOCK_HEAD (0) == note)
                    BLOCK_HEAD (0) = next;
 
+                 remove_insn (note);
                  add_insn_after (note, insn);
                }
            }
@@ -6475,12 +6514,6 @@ 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 BLOCK_HEAD, 
                     attempt to keep it up-to-date.  */
@@ -6488,6 +6521,7 @@ reposition_prologue_and_epilogue_notes (f)
                      && 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.039259 seconds and 5 git commands to generate.