OSDN Git Service

2006-11-22 Antony King <anthony.king@st.com>
[pf3gnuchains/gcc-fork.git] / gcc / function.c
index e912d6a..a27d8cb 100644 (file)
@@ -195,7 +195,6 @@ static struct temp_slot *find_temp_slot_from_address (rtx);
 static void pad_to_arg_alignment (struct args_size *, int, struct args_size *);
 static void pad_below (struct args_size *, enum machine_mode, tree);
 static void reorder_blocks_1 (rtx, tree, VEC(tree,heap) **);
-static void reorder_fix_fragments (tree);
 static int all_blocks (tree, tree *);
 static tree *get_block_vector (tree, int *);
 extern tree debug_find_var_in_block_tree (tree, tree);
@@ -204,7 +203,7 @@ extern tree debug_find_var_in_block_tree (tree, tree);
 static void record_insns (rtx, VEC(int,heap) **) ATTRIBUTE_UNUSED;
 static int contains (rtx, VEC(int,heap) **);
 #ifdef HAVE_return
-static void emit_return_into_block (basic_block, rtx);
+static void emit_return_into_block (basic_block);
 #endif
 #if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)
 static rtx keep_stack_depressed (rtx);
@@ -1541,7 +1540,7 @@ instantiate_virtual_regs_in_insn (rtx insn)
       /* Propagate operand changes into the duplicates.  */
       for (i = 0; i < recog_data.n_dups; ++i)
        *recog_data.dup_loc[i]
-         = recog_data.operand[(unsigned)recog_data.dup_num[i]];
+         = copy_rtx (recog_data.operand[(unsigned)recog_data.dup_num[i]]);
 
       /* Force re-recognition of the instruction for validation.  */
       INSN_CODE (insn) = -1;
@@ -3584,9 +3583,6 @@ reorder_blocks (void)
   reorder_blocks_1 (get_insns (), block, &block_stack);
   BLOCK_SUBBLOCKS (block) = blocks_nreverse (BLOCK_SUBBLOCKS (block));
 
-  /* Remove deleted blocks from the block fragment chains.  */
-  reorder_fix_fragments (block);
-
   VEC_free (tree, heap, block_stack);
 }
 
@@ -3615,17 +3611,18 @@ reorder_blocks_1 (rtx insns, tree current_block, VEC(tree,heap) **p_block_stack)
          if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
            {
              tree block = NOTE_BLOCK (insn);
+             tree origin;
+
+             origin = (BLOCK_FRAGMENT_ORIGIN (block)
+                       ? BLOCK_FRAGMENT_ORIGIN (block)
+                       : block);
 
              /* If we have seen this block before, that means it now
                 spans multiple address regions.  Create a new fragment.  */
              if (TREE_ASM_WRITTEN (block))
                {
                  tree new_block = copy_node (block);
-                 tree origin;
 
-                 origin = (BLOCK_FRAGMENT_ORIGIN (block)
-                           ? BLOCK_FRAGMENT_ORIGIN (block)
-                           : block);
                  BLOCK_FRAGMENT_ORIGIN (new_block) = origin;
                  BLOCK_FRAGMENT_CHAIN (new_block)
                    = BLOCK_FRAGMENT_CHAIN (origin);
@@ -3642,10 +3639,13 @@ reorder_blocks_1 (rtx insns, tree current_block, VEC(tree,heap) **p_block_stack)
                 will cause infinite recursion.  */
              if (block != current_block)
                {
+                 if (block != origin)
+                   gcc_assert (BLOCK_SUPERCONTEXT (origin) == current_block);
+
                  BLOCK_SUPERCONTEXT (block) = current_block;
                  BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (current_block);
                  BLOCK_SUBBLOCKS (current_block) = block;
-                 current_block = block;
+                 current_block = origin;
                }
              VEC_safe_push (tree, heap, *p_block_stack, block);
            }
@@ -3660,61 +3660,6 @@ reorder_blocks_1 (rtx insns, tree current_block, VEC(tree,heap) **p_block_stack)
     }
 }
 
-/* Rationalize BLOCK_FRAGMENT_ORIGIN.  If an origin block no longer
-   appears in the block tree, select one of the fragments to become
-   the new origin block.  */
-
-static void
-reorder_fix_fragments (tree block)
-{
-  while (block)
-    {
-      tree dup_origin = BLOCK_FRAGMENT_ORIGIN (block);
-      tree new_origin = NULL_TREE;
-
-      if (dup_origin)
-       {
-         if (! TREE_ASM_WRITTEN (dup_origin))
-           {
-             new_origin = BLOCK_FRAGMENT_CHAIN (dup_origin);
-
-             /* Find the first of the remaining fragments.  There must
-                be at least one -- the current block.  */
-             while (! TREE_ASM_WRITTEN (new_origin))
-               new_origin = BLOCK_FRAGMENT_CHAIN (new_origin);
-             BLOCK_FRAGMENT_ORIGIN (new_origin) = NULL_TREE;
-           }
-       }
-      else if (! dup_origin)
-       new_origin = block;
-
-      /* Re-root the rest of the fragments to the new origin.  In the
-        case that DUP_ORIGIN was null, that means BLOCK was the origin
-        of a chain of fragments and we want to remove those fragments
-        that didn't make it to the output.  */
-      if (new_origin)
-       {
-         tree *pp = &BLOCK_FRAGMENT_CHAIN (new_origin);
-         tree chain = *pp;
-
-         while (chain)
-           {
-             if (TREE_ASM_WRITTEN (chain))
-               {
-                 BLOCK_FRAGMENT_ORIGIN (chain) = new_origin;
-                 *pp = chain;
-                 pp = &BLOCK_FRAGMENT_CHAIN (chain);
-               }
-             chain = BLOCK_FRAGMENT_CHAIN (chain);
-           }
-         *pp = NULL_TREE;
-       }
-
-      reorder_fix_fragments (BLOCK_SUBBLOCKS (block));
-      block = BLOCK_CHAIN (block);
-    }
-}
-
 /* Reverse the order of elements in the chain T of blocks,
    and return the new head of the chain (old last element).  */
 
@@ -4395,14 +4340,6 @@ expand_function_end (void)
      without returning a value.  */
   emit_note (NOTE_INSN_FUNCTION_END);
 
-  /* Must mark the last line number note in the function, so that the test
-     coverage code can avoid counting the last line twice.  This just tells
-     the code to ignore the immediately following line note, since there
-     already exists a copy of this note somewhere above.  This line number
-     note is still needed for debugging though, so we can't delete it.  */
-  if (flag_test_coverage)
-    emit_note (NOTE_INSN_REPEATED_LINE_NUMBER);
-
   /* Output a linenumber for the end of the function.
      SDB depends on this.  */
   force_next_line_note ();
@@ -4708,11 +4645,9 @@ sibcall_epilogue_contains (rtx insn)
    block_for_insn appropriately.  */
 
 static void
-emit_return_into_block (basic_block bb, rtx line_note)
+emit_return_into_block (basic_block bb)
 {
   emit_jump_insn_after (gen_return (), BB_END (bb));
-  if (line_note)
-    emit_note_copy_after (line_note, PREV_INSN (BB_END (bb)));
 }
 #endif /* HAVE_return */
 
@@ -5178,18 +5113,6 @@ 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,
-            if we can find one.  */
-         for (seq = get_last_insn ();
-              seq && ! active_insn_p (seq);
-              seq = PREV_INSN (seq))
-           if (NOTE_P (seq) && NOTE_LINE_NUMBER (seq) > 0)
-             {
-               epilogue_line_note = seq;
-               break;
-             }
 
          for (ei2 = ei_start (last->preds); (e = ei_safe_edge (ei2)); )
            {
@@ -5213,7 +5136,7 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED)
                 with a simple return instruction.  */
              if (simplejump_p (jump))
                {
-                 emit_return_into_block (bb, epilogue_line_note);
+                 emit_return_into_block (bb);
                  delete_insn (jump);
                }
 
@@ -5250,7 +5173,7 @@ thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED)
             this is still reachable will be determined later.  */
 
          emit_barrier_after (BB_END (last));
-         emit_return_into_block (last, epilogue_line_note);
+         emit_return_into_block (last);
          epilogue_end = BB_END (last);
          single_succ_edge (last)->flags &= ~EDGE_FALLTHRU;
          goto epilogue_done;
@@ -5352,61 +5275,6 @@ epilogue_done:
     }
 #endif
 
-#ifdef HAVE_prologue
-  /* This is probably all useless now that we use locators.  */
-  if (prologue_end)
-    {
-      rtx insn, prev;
-
-      /* GDB handles `break f' by setting a breakpoint on the first
-        line note after the prologue.  Which means (1) that if
-        there are line number notes before where we inserted the
-        prologue we should move them, and (2) we should generate a
-        note before the end of the first basic block, if there isn't
-        one already there.
-
-        ??? This behavior is completely broken when dealing with
-        multiple entry functions.  We simply place the note always
-        into first basic block and let alternate entry points
-        to be missed.
-       */
-
-      for (insn = prologue_end; insn; insn = prev)
-       {
-         prev = PREV_INSN (insn);
-         if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0)
-           {
-             /* Note that we cannot reorder the first insn in the
-                chain, since rest_of_compilation relies on that
-                remaining constant.  */
-             if (prev == NULL)
-               break;
-             reorder_insns (insn, insn, prologue_end);
-           }
-       }
-
-      /* Find the last line number note in the first block.  */
-      for (insn = BB_END (ENTRY_BLOCK_PTR->next_bb);
-          insn != prologue_end && insn;
-          insn = PREV_INSN (insn))
-       if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0)
-         break;
-
-      /* If we didn't find one, make a copy of the first line number
-        we run across.  */
-      if (! insn)
-       {
-         for (insn = next_active_insn (prologue_end);
-              insn;
-              insn = PREV_INSN (insn))
-           if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0)
-             {
-               emit_note_copy_after (insn, prologue_end);
-               break;
-             }
-       }
-    }
-#endif
 #ifdef HAVE_epilogue
   if (epilogue_end)
     {
@@ -5421,8 +5289,7 @@ epilogue_done:
        {
          next = NEXT_INSN (insn);
          if (NOTE_P (insn) 
-             && (NOTE_LINE_NUMBER (insn) > 0
-                 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG
+             && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG
                  || NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END))
            reorder_insns (insn, insn, PREV_INSN (epilogue_end));
        }