OSDN Git Service

Remove spurious ChangeLog entry
[pf3gnuchains/gcc-fork.git] / gcc / function.c
index 49404c8..c0350be 100644 (file)
@@ -211,8 +211,7 @@ free_after_compilation (struct function *f)
   prologue_insn_hash = NULL;
   epilogue_insn_hash = NULL;
 
-  if (crtl->emit.regno_pointer_align)
-    free (crtl->emit.regno_pointer_align);
+  free (crtl->emit.regno_pointer_align);
 
   memset (crtl, 0, sizeof (struct rtl_data));
   f->eh = NULL;
@@ -1883,7 +1882,7 @@ instantiate_decls (tree fndecl)
 static unsigned int
 instantiate_virtual_regs (void)
 {
-  basic_block bb;
+  rtx insn;
 
   /* Compute the offsets to use for this function.  */
   in_arg_offset = FIRST_PARM_OFFSET (current_function_decl);
@@ -1901,40 +1900,33 @@ instantiate_virtual_regs (void)
 
   /* Scan through all the insns, instantiating every virtual register still
      present.  */
-  FOR_EACH_BB (bb)
-    {
-      rtx insn, curr;
-
-      FOR_BB_INSNS_SAFE (bb, insn, curr)
-       {
-         if (INSN_P (insn))
-           {
-             /* These patterns in the instruction stream can never be recognized.
-                Fortunately, they shouldn't contain virtual registers either.  */
-             if (GET_CODE (PATTERN (insn)) == USE
-                 || GET_CODE (PATTERN (insn)) == CLOBBER
-                 || GET_CODE (PATTERN (insn)) == ADDR_VEC
-                 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
-                 || GET_CODE (PATTERN (insn)) == ASM_INPUT)
-               continue;
-             else if (DEBUG_INSN_P (insn))
-               for_each_rtx (&INSN_VAR_LOCATION (insn),
-                             instantiate_virtual_regs_in_rtx, NULL);
-             else
-               instantiate_virtual_regs_in_insn (insn);
+  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+    if (INSN_P (insn))
+      {
+       /* These patterns in the instruction stream can never be recognized.
+          Fortunately, they shouldn't contain virtual registers either.  */
+       if (GET_CODE (PATTERN (insn)) == USE
+           || GET_CODE (PATTERN (insn)) == CLOBBER
+           || GET_CODE (PATTERN (insn)) == ADDR_VEC
+           || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
+           || GET_CODE (PATTERN (insn)) == ASM_INPUT)
+         continue;
+       else if (DEBUG_INSN_P (insn))
+         for_each_rtx (&INSN_VAR_LOCATION (insn),
+                       instantiate_virtual_regs_in_rtx, NULL);
+       else
+         instantiate_virtual_regs_in_insn (insn);
 
-             if (INSN_DELETED_P (insn))
-               continue;
+       if (INSN_DELETED_P (insn))
+         continue;
 
-             for_each_rtx (&REG_NOTES (insn), instantiate_virtual_regs_in_rtx, NULL);
+       for_each_rtx (&REG_NOTES (insn), instantiate_virtual_regs_in_rtx, NULL);
 
-             /* Instantiate any virtual registers in CALL_INSN_FUNCTION_USAGE.  */
-             if (CALL_P (insn))
-               for_each_rtx (&CALL_INSN_FUNCTION_USAGE (insn),
-                             instantiate_virtual_regs_in_rtx, NULL);
-           }
-       }
-    }
+       /* Instantiate any virtual registers in CALL_INSN_FUNCTION_USAGE.  */
+       if (CALL_P (insn))
+         for_each_rtx (&CALL_INSN_FUNCTION_USAGE (insn),
+                       instantiate_virtual_regs_in_rtx, NULL);
+      }
 
   /* Instantiate the virtual registers in the DECLs for debugging purposes.  */
   instantiate_decls (current_function_decl);
@@ -1947,7 +1939,7 @@ instantiate_virtual_regs (void)
 
   /* See allocate_dynamic_stack_space for the rationale.  */
 #ifdef SETJMP_VIA_SAVE_AREA
-  if (flag_stack_usage && cfun->calls_setjmp)
+  if (flag_stack_usage_info && cfun->calls_setjmp)
     {
       int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
       dynamic_offset = (dynamic_offset + align - 1) / align * align;
@@ -1970,7 +1962,7 @@ struct rtl_opt_pass pass_instantiate_virtual_regs =
   NULL,                                 /* next */
   0,                                    /* static_pass_number */
   TV_NONE,                              /* tv_id */
-  PROP_cfglayout,                       /* properties_required */
+  0,                                    /* properties_required */
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
@@ -2884,9 +2876,7 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
              int by = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
              rtx reg = gen_rtx_REG (word_mode, REGNO (entry_parm));
 
-             x = expand_shift (LSHIFT_EXPR, word_mode, reg,
-                               build_int_cst (NULL_TREE, by),
-                               NULL_RTX, 1);
+             x = expand_shift (LSHIFT_EXPR, word_mode, reg, by, NULL_RTX, 1);
              tem = change_address (mem, word_mode, 0);
              emit_move_insn (tem, x);
            }
@@ -2919,12 +2909,8 @@ static void
 record_hard_reg_sets (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
 {
   HARD_REG_SET *pset = (HARD_REG_SET *)data;
-  if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
-    {
-      int nregs = hard_regno_nregs[REGNO (x)][GET_MODE (x)];
-      while (nregs-- > 0)
-       SET_HARD_REG_BIT (*pset, REGNO (x) + nregs);
-    }
+  if (REG_P (x) && HARD_REGISTER_P (x))
+    add_to_hard_reg_set (pset, GET_MODE (x), REGNO (x));
 }
 
 /* A subroutine of assign_parms.  Allocate a pseudo to hold the current
@@ -3663,7 +3649,7 @@ gimplify_parameters (void)
                  t = built_in_decls[BUILT_IN_ALLOCA];
                  t = build_call_expr (t, 1, DECL_SIZE_UNIT (parm));
                  /* The call has been built for a variable-sized object.  */
-                 ALLOCA_FOR_VAR_P (t) = 1;
+                 CALL_ALLOCA_FOR_VAR_P (t) = 1;
                  t = fold_convert (ptr_type, t);
                  t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
                  gimplify_and_add (t, &stmts);
@@ -4190,6 +4176,34 @@ blocks_nreverse (tree t)
   return prev;
 }
 
+/* Concatenate two chains of blocks (chained through BLOCK_CHAIN)
+   by modifying the last node in chain 1 to point to chain 2.  */
+
+tree
+block_chainon (tree op1, tree op2)
+{
+  tree t1;
+
+  if (!op1)
+    return op2;
+  if (!op2)
+    return op1;
+
+  for (t1 = op1; BLOCK_CHAIN (t1); t1 = BLOCK_CHAIN (t1))
+    continue;
+  BLOCK_CHAIN (t1) = op2;
+
+#ifdef ENABLE_TREE_CHECKING
+  {
+    tree t2;
+    for (t2 = op2; t2; t2 = BLOCK_CHAIN (t2))
+      gcc_assert (t2 != t1);
+  }
+#endif
+
+  return op1;
+}
+
 /* Count the subblocks of the list starting with BLOCK.  If VECTOR is
    non-NULL, list them all into VECTOR, in a depth-first preorder
    traversal of the block tree.  Also clear TREE_ASM_WRITTEN in all
@@ -4362,6 +4376,13 @@ get_next_funcdef_no (void)
   return funcdef_no++;
 }
 
+/* Return value of funcdef.  */
+int
+get_last_funcdef_no (void)
+{
+  return funcdef_no;
+}
+
 /* Allocate a function structure for FNDECL and set its contents
    to the defaults.  Set cfun to the newly-allocated object.
    Some of the helper functions invoked during initialization assume
@@ -4444,7 +4465,7 @@ prepare_function_start (void)
   init_expr ();
   default_rtl_profile ();
 
-  if (flag_stack_usage)
+  if (flag_stack_usage_info)
     {
       cfun->su = ggc_alloc_cleared_stack_usage ();
       cfun->su->static_stack_size = -1;
@@ -4494,6 +4515,7 @@ init_function_start (tree subr)
   else
     allocate_struct_function (subr, false);
   prepare_function_start ();
+  decide_function_section (subr);
 
   /* Warn if this value is an aggregate type,
      regardless of which calling convention we are using for it.  */
@@ -4791,9 +4813,8 @@ expand_function_start (tree subr)
 #endif
     }
 
-  /* After the display initializations is where the stack checking
-     probe should go.  */
-  if(flag_stack_check)
+  /* If we are doing generic stack checking, the probe should go here.  */
+  if (flag_stack_check == GENERIC_STACK_CHECK)
     stack_check_probe_note = emit_note (NOTE_INSN_DELETED);
 
   /* Make sure there is a line number after the function entry setup code.  */
@@ -5270,6 +5291,19 @@ prologue_epilogue_contains (const_rtx insn)
 }
 
 #ifdef HAVE_return
+/* Insert use of return register before the end of BB.  */
+
+static void
+emit_use_return_register_into_block (basic_block bb)
+{
+  rtx seq;
+  start_sequence ();
+  use_return_register ();
+  seq = get_insns ();
+  end_sequence ();
+  emit_insn_before (seq, BB_END (bb));
+}
+
 /* Insert gen_return at the end of block BB.  This also means updating
    block_for_insn appropriately.  */
 
@@ -5289,8 +5323,7 @@ thread_prologue_and_epilogue_insns (void)
 {
   bool inserted;
   rtx seq ATTRIBUTE_UNUSED, epilogue_end ATTRIBUTE_UNUSED;
-  edge entry_edge ATTRIBUTE_UNUSED;
-  edge e;
+  edge entry_edge, e;
   edge_iterator ei;
 
   rtl_profile_for_bb (ENTRY_BLOCK_PTR);
@@ -5322,10 +5355,6 @@ thread_prologue_and_epilogue_insns (void)
       record_insns (seq, NULL, &prologue_insn_hash);
       set_insn_locators (seq, prologue_locator);
 
-      /* This relies on the fact that committing the edge insertion
-        will look for basic blocks within the inserted instructions,
-        which in turn relies on the fact that we are not in CFG
-        layout mode here.  */
       insert_insn_on_edge (seq, entry_edge);
       inserted = true;
 #endif
@@ -5423,6 +5452,15 @@ thread_prologue_and_epilogue_insns (void)
                 with a simple return instruction.  */
              if (simplejump_p (jump))
                {
+                 /* The use of the return register might be present in the exit
+                    fallthru block.  Either:
+                    - removing the use is safe, and we should remove the use in
+                      the exit fallthru block, or
+                    - removing the use is not safe, and we should add it here.
+                    For now, we conservatively choose the latter.  Either of the
+                    2 helps in crossjumping.  */
+                 emit_use_return_register_into_block (bb);
+
                  emit_return_into_block (bb);
                  delete_insn (jump);
                }
@@ -5437,6 +5475,9 @@ thread_prologue_and_epilogue_insns (void)
                      continue;
                    }
 
+                 /* See comment in simple_jump_p case above.  */
+                 emit_use_return_register_into_block (bb);
+
                  /* If this block has only one successor, it both jumps
                     and falls through to the fallthru block, so we can't
                     delete the edge.  */
@@ -5548,13 +5589,23 @@ thread_prologue_and_epilogue_insns (void)
          cur_bb->aux = cur_bb->next_bb;
       cfg_layout_finalize ();
     }
+
 epilogue_done:
   default_rtl_profile ();
 
   if (inserted)
     {
+      sbitmap blocks;
+
       commit_edge_insertions ();
 
+      /* Look for basic blocks within the prologue insns.  */
+      blocks = sbitmap_alloc (last_basic_block);
+      sbitmap_zero (blocks);
+      SET_BIT (blocks, entry_edge->dest->index);
+      find_many_sub_basic_blocks (blocks);
+      sbitmap_free (blocks);
+
       /* The epilogue insns we inserted may cause the exit edge to no longer
         be fallthru.  */
       FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
@@ -5888,7 +5939,7 @@ rest_of_handle_thread_prologue_and_epilogue (void)
   thread_prologue_and_epilogue_insns ();
 
   /* The stack usage info is finalized during prologue expansion.  */
-  if (flag_stack_usage)
+  if (flag_stack_usage_info)
     output_stack_usage ();
 
   return 0;