#include "alloc-pool.h"
#include "flags.h"
#include "tree-pass.h"
+#include "vecprim.h"
/* Holds the interesting trailing notes for the function. */
-rtx cfg_layout_function_footer, cfg_layout_function_header;
+rtx cfg_layout_function_footer;
+rtx cfg_layout_function_header;
static rtx skip_insns_after_block (basic_block);
static void record_effective_endpoints (void);
case NOTE:
switch (NOTE_LINE_NUMBER (insn))
{
- case NOTE_INSN_LOOP_END:
case NOTE_INSN_BLOCK_END:
last_insn = insn;
continue;
if (NEXT_INSN (insn)
&& JUMP_P (NEXT_INSN (insn))
&& (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
- || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
+ || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
{
insn = NEXT_INSN (insn);
last_insn = insn;
/* It is possible to hit contradictory sequence. For instance:
jump_insn
- NOTE_INSN_LOOP_BEG
+ NOTE_INSN_BLOCK_BEG
barrier
Where barrier belongs to jump_insn, but the note does not. This can be
created by removing the basic block originally following
- NOTE_INSN_LOOP_BEG. In such case reorder the notes. */
+ NOTE_INSN_BLOCK_BEG. In such case reorder the notes. */
for (insn = last_insn; insn != BB_END (bb); insn = prev)
{
if (NOTE_P (insn))
switch (NOTE_LINE_NUMBER (insn))
{
- case NOTE_INSN_LOOP_END:
case NOTE_INSN_BLOCK_END:
case NOTE_INSN_DELETED:
case NOTE_INSN_DELETED_LABEL:
continue;
/* No basic blocks at all? */
gcc_assert (insn);
-
+
if (PREV_INSN (insn))
cfg_layout_function_header =
unlink_insn_chain (get_insns (), PREV_INSN (insn));
cfg_layout_function_footer = unlink_insn_chain (cfg_layout_function_footer, get_last_insn ());
}
\f
-DEF_VEC_I(int);
-DEF_VEC_ALLOC_I(int,heap);
-
/* Data structures representing mapping of INSN_LOCATOR into scope blocks, line
numbers and files. In order to be GGC friendly we need to use separate
varrays. This also slightly improve the memory locality in binary search.
represented via INSN_NOTEs. Replace them by representation using
INSN_LOCATORs. */
-void
+unsigned int
insn_locators_initialize (void)
{
tree block = NULL;
for (insn = get_insns (); insn; insn = next)
{
int active = 0;
-
+
next = NEXT_INSN (insn);
if (NOTE_P (insn))
NOTE_EXPANDED_LOCATION (xloc, insn);
line_number = xloc.line;
file_name = xloc.file;
+ delete_insn (insn);
}
}
else
active = (active_insn_p (insn)
&& GET_CODE (PATTERN (insn)) != ADDR_VEC
&& GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC);
-
+
check_block_change (insn, &block);
if (active
set_block_levels (DECL_INITIAL (cfun->decl), 0);
free_block_changes ();
+ return 0;
}
struct tree_opt_pass pass_insn_locators_initialize =
{
"locators", /* name */
- NULL, /* gate */
- insn_locators_initialize, /* execute */
+ NULL, /* gate */
+ insn_locators_initialize, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
0 /* letter */
};
+static unsigned int
+into_cfg_layout_mode (void)
+{
+ cfg_layout_initialize (0);
+ return 0;
+}
+
+static unsigned int
+outof_cfg_layout_mode (void)
+{
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
+ if (bb->next_bb != EXIT_BLOCK_PTR)
+ bb->aux = bb->next_bb;
+
+ cfg_layout_finalize ();
+
+ return 0;
+}
+
+struct tree_opt_pass pass_into_cfg_layout_mode =
+{
+ "into_cfglayout", /* name */
+ NULL, /* gate */
+ into_cfg_layout_mode, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func, /* todo_flags_finish */
+ 0 /* letter */
+};
+
+struct tree_opt_pass pass_outof_cfg_layout_mode =
+{
+ "outof_cfglayout", /* name */
+ NULL, /* gate */
+ outof_cfg_layout_mode, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func, /* todo_flags_finish */
+ 0 /* letter */
+};
/* For each lexical block, set BLOCK_NUMBER to the depth at which it is
found in the block tree. */
this_block = insn_scope (insn);
/* For sequences compute scope resulting from merging all scopes
- of instructions nested inside. */
+ of instructions nested inside. */
if (GET_CODE (PATTERN (insn)) == SEQUENCE)
{
int i;
{
/* If the old fallthru is still next, nothing to do. */
if (bb->aux == e_fall->dest
- || e_fall->dest == EXIT_BLOCK_PTR)
+ || e_fall->dest == EXIT_BLOCK_PTR)
continue;
/* The degenerated case of conditional jump jumping to the next
bb->aux = nb;
/* Don't process this new block. */
bb = nb;
-
+
/* Make sure new bb is tagged for correct section (same as
fall-thru source, since you cannot fall-throu across
section boundaries). */
for (; bb; prev_bb = bb, bb = bb->aux, index ++)
{
bb->index = index;
- BASIC_BLOCK (index) = bb;
+ SET_BASIC_BLOCK (index, bb);
bb->prev_bb = prev_bb;
prev_bb->next_bb = bb;
switch (NOTE_LINE_NUMBER (insn))
{
/* In case prologue is empty and function contain label
- in first BB, we may want to copy the block. */
+ in first BB, we may want to copy the block. */
case NOTE_INSN_PROLOGUE_END:
- case NOTE_INSN_LOOP_BEG:
- case NOTE_INSN_LOOP_END:
- /* Strip down the loop notes - we don't really want to keep
- them consistent in loop copies. */
case NOTE_INSN_DELETED:
case NOTE_INSN_DELETED_LABEL:
/* No problem to strip these. */
case NOTE_INSN_EPILOGUE_BEG:
- case NOTE_INSN_FUNCTION_END:
/* Debug code expect these notes to exist just once.
- Keep them in the master copy.
- ??? It probably makes more sense to duplicate them for each
- epilogue copy. */
+ Keep them in the master copy.
+ ??? It probably makes more sense to duplicate them for each
+ epilogue copy. */
case NOTE_INSN_FUNCTION_BEG:
/* There is always just single entry to function. */
case NOTE_INSN_BASIC_BLOCK:
break;
- case NOTE_INSN_REPEATED_LINE_NUMBER:
case NOTE_INSN_SWITCH_TEXT_SECTIONS:
emit_note_copy (insn);
break;
/* All other notes should have already been eliminated.
*/
gcc_assert (NOTE_LINE_NUMBER (insn) >= 0);
-
+
/* It is possible that no_line_number is set and the note
- won't be emitted. */
+ won't be emitted. */
emit_note_copy (insn);
}
break;
bb->il.rtl->visited = 0;
}
- break_superblocks ();
-
#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif
Created copies of N_EDGES edges in array EDGES are stored in array NEW_EDGES,
also in the same order.
-
+
Newly created basic blocks are put after the basic block AFTER in the
instruction stream, and the order of the blocks in BBS array is preserved. */
new_bb = new_bbs[i] = duplicate_block (bb, NULL, after);
after = new_bb;
bb->flags |= BB_DUPLICATED;
- /* Add to loop. */
- add_bb_to_loop (new_bb, bb->loop_father->copy);
- /* Possibly set header. */
+ /* Possibly set loop header. */
if (bb->loop_father->header == bb && bb->loop_father != base)
new_bb->loop_father->header = new_bb;
/* Or latch. */