OSDN Git Service

2004-10-02 James A. Morrison <phython@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / function.c
index 589294f..0545b05 100644 (file)
@@ -831,7 +831,7 @@ assign_temp (tree type_or_decl, int keep, int memory_required,
       if (decl && size == -1
          && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST)
        {
-         error ("%Jsize of variable '%D' is too large", decl, decl);
+         error ("%Jsize of variable %qD is too large", decl, decl);
          size = 1;
        }
 
@@ -1432,7 +1432,7 @@ static void
 instantiate_virtual_regs_lossage (rtx insn)
 {
   gcc_assert (asm_noperands (PATTERN (insn)) >= 0);
-  error_for_asm (insn, "impossible constraint in `asm'");
+  error_for_asm (insn, "impossible constraint in %<asm%>");
   delete_insn (insn);
 }
 /* Given a pointer to a piece of rtx and an optional pointer to the
@@ -1951,6 +1951,18 @@ pass_by_reference (CUMULATIVE_ARGS *ca, enum machine_mode mode,
   return targetm.calls.pass_by_reference (ca, mode, type, named_arg);
 }
 
+/* Return true if TYPE, which is passed by reference, should be callee
+   copied instead of caller copied.  */
+
+bool
+reference_callee_copied (CUMULATIVE_ARGS *ca, enum machine_mode mode,
+                        tree type, bool named_arg)
+{
+  if (type && TREE_ADDRESSABLE (type))
+    return false;
+  return targetm.calls.callee_copies (ca, mode, type, named_arg);
+}
+
 /* Structures to communicate between the subroutines of assign_parms.
    The first holds data persistent across all parameters, the second
    is cleared out for each parameter.  */
@@ -2523,7 +2535,7 @@ assign_parm_setup_block (tree parm, struct assign_parm_data_one *data)
   if (GET_CODE (entry_parm) == PARALLEL
       && data->nominal_mode != BLKmode
       && XVECLEN (entry_parm, 0) > 1
-      && optimize)
+      && use_register_for_decl (parm))
     {
       rtx parmreg = gen_reg_rtx (data->nominal_mode);
 
@@ -2766,9 +2778,8 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
     {
       tree type = TREE_TYPE (data->passed_type);
     
-      if (FUNCTION_ARG_CALLEE_COPIES (all->args_so_far, TYPE_MODE (type),
-                                     type, data->named_arg)
-          && !TREE_ADDRESSABLE (type))
+      if (reference_callee_copied (&all->args_so_far, TYPE_MODE (type),
+                                  type, data->named_arg))
        {
          rtx copy;
 
@@ -3443,7 +3454,8 @@ setjmp_vars_warning (tree block)
          && DECL_RTL_SET_P (decl)
          && REG_P (DECL_RTL (decl))
          && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
-       warning ("%Jvariable '%D' might be clobbered by `longjmp' or `vfork'",
+       warning ("%Jvariable %qD might be clobbered by %<longjmp%>"
+                " or %<vfork%>",
                 decl, decl);
     }
 
@@ -3463,7 +3475,7 @@ setjmp_args_warning (void)
     if (DECL_RTL (decl) != 0
        && REG_P (DECL_RTL (decl))
        && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
-      warning ("%Jargument '%D' might be clobbered by `longjmp' or `vfork'",
+      warning ("%Jargument %qD might be clobbered by %<longjmp%> or %<vfork%>",
               decl, decl);
 }
 
@@ -4187,7 +4199,7 @@ do_warn_unused_parameter (tree fn)
        decl; decl = TREE_CHAIN (decl))
     if (!TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL
        && DECL_NAME (decl) && !DECL_ARTIFICIAL (decl))
-      warning ("%Junused parameter '%D'", decl, decl);
+      warning ("%Junused parameter %qD", decl, decl);
 }
 
 static GTY(()) rtx initial_trampoline;
@@ -4400,20 +4412,19 @@ expand_function_end (void)
 
   /* Emit the actual code to clobber return register.  */
   {
-    rtx seq, after;
+    rtx seq;
 
     start_sequence ();
     clobber_return_register ();
+    expand_naked_return ();
     seq = get_insns ();
     end_sequence ();
 
-    after = emit_insn_after (seq, clobber_after);
+    emit_insn_after (seq, clobber_after);
   }
 
-  /* Output the label for the naked return from the function, if one is
-     expected.  This is currently used only by __builtin_return.  */
-  if (naked_return_label)
-    emit_label (naked_return_label);
+  /* Output the label for the naked return from the function.  */
+  emit_label (naked_return_label);
 
   /* ??? This should no longer be necessary since stupid is no longer with
      us, but there are some parts of the compiler (eg reload_combine, and
@@ -4945,6 +4956,7 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED)
 #if defined (HAVE_epilogue) || defined(HAVE_return)
   rtx epilogue_end = NULL_RTX;
 #endif
+  edge_iterator ei;
 
 #ifdef HAVE_prologue
   if (HAVE_prologue)
@@ -4964,16 +4976,16 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED)
       /* Can't deal with multiple successors of the entry block
          at the moment.  Function should always have at least one
          entry point.  */
-      gcc_assert (ENTRY_BLOCK_PTR->succ && !ENTRY_BLOCK_PTR->succ->succ_next);
+      gcc_assert (EDGE_COUNT (ENTRY_BLOCK_PTR->succs) == 1);
 
-      insert_insn_on_edge (seq, ENTRY_BLOCK_PTR->succ);
+      insert_insn_on_edge (seq, EDGE_SUCC (ENTRY_BLOCK_PTR, 0));
       inserted = 1;
     }
 #endif
 
   /* If the exit block has no non-fake predecessors, we don't need
      an epilogue.  */
-  for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
+  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
     if ((e->flags & EDGE_FAKE) == 0)
       break;
   if (e == NULL)
@@ -4989,10 +5001,9 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED)
         emit (conditional) return instructions.  */
 
       basic_block last;
-      edge e_next;
       rtx label;
 
-      for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
+      FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
        if (e->flags & EDGE_FALLTHRU)
          break;
       if (e == NULL)
@@ -5010,6 +5021,7 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED)
 
       if (BB_HEAD (last) == label && LABEL_P (label))
        {
+         edge_iterator ei2;
          rtx epilogue_line_note = NULL_RTX;
 
          /* Locate the line number associated with the closing brace,
@@ -5023,18 +5035,23 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED)
                break;
              }
 
-         for (e = last->pred; e; e = e_next)
+         for (ei2 = ei_start (last->preds); (e = ei_safe_edge (ei2)); )
            {
              basic_block bb = e->src;
              rtx jump;
 
-             e_next = e->pred_next;
              if (bb == ENTRY_BLOCK_PTR)
-               continue;
+               {
+                 ei_next (&ei2);
+                 continue;
+               }
 
              jump = BB_END (bb);
              if (!JUMP_P (jump) || JUMP_LABEL (jump) != label)
-               continue;
+               {
+                 ei_next (&ei2);
+                 continue;
+               }
 
              /* If we have an unconditional jump, we can replace that
                 with a simple return instruction.  */
@@ -5049,16 +5066,25 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED)
              else if (condjump_p (jump))
                {
                  if (! redirect_jump (jump, 0, 0))
-                   continue;
+                   {
+                     ei_next (&ei2);
+                     continue;
+                   }
 
                  /* If this block has only one successor, it both jumps
                     and falls through to the fallthru block, so we can't
                     delete the edge.  */
-                 if (bb->succ->succ_next == NULL)
-                   continue;
+                 if (EDGE_COUNT (bb->succs) == 1)
+                   {
+                     ei_next (&ei2);
+                     continue;
+                   }
                }
              else
-               continue;
+               {
+                 ei_next (&ei2);
+                 continue;
+               }
 
              /* Fix up the CFG for the successful change we just made.  */
              redirect_edge_succ (e, EXIT_BLOCK_PTR);
@@ -5070,7 +5096,7 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED)
          emit_barrier_after (BB_END (last));
          emit_return_into_block (last, epilogue_line_note);
          epilogue_end = BB_END (last);
-         last->succ->flags &= ~EDGE_FALLTHRU;
+         EDGE_SUCC (last, 0)->flags &= ~EDGE_FALLTHRU;
          goto epilogue_done;
        }
     }
@@ -5080,7 +5106,7 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED)
      There really shouldn't be a mixture -- either all should have
      been converted or none, however...  */
 
-  for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
+  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
     if (e->flags & EDGE_FALLTHRU)
       break;
   if (e == NULL)
@@ -5141,7 +5167,7 @@ epilogue_done:
 
 #ifdef HAVE_sibcall_epilogue
   /* Emit sibling epilogues before any sibling call sites.  */
-  for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
+  for (ei = ei_start (EXIT_BLOCK_PTR->preds); (e = ei_safe_edge (ei)); )
     {
       basic_block bb = e->src;
       rtx insn = BB_END (bb);
@@ -5150,7 +5176,10 @@ epilogue_done:
 
       if (!CALL_P (insn)
          || ! SIBLING_CALL_P (insn))
-       continue;
+       {
+         ei_next (&ei);
+         continue;
+       }
 
       start_sequence ();
       emit_insn (gen_sibcall_epilogue ());
@@ -5165,6 +5194,7 @@ epilogue_done:
 
       i = PREV_INSN (insn);
       newinsn = emit_insn_before (seq, insn);
+      ei_next (&ei);
     }
 #endif