/* Control flow graph analysis code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
|| !bb->succ || bb->succ->succ_next)
return false;
- for (insn = bb->head; insn != bb->end; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
if (INSN_P (insn) && flow_active_insn_p (insn))
return false;
bool
can_fallthru (basic_block src, basic_block target)
{
- rtx insn = src->end;
- rtx insn2 = target->head;
+ rtx insn = BB_END (src);
+ rtx insn2 = target == EXIT_BLOCK_PTR ? NULL : BB_HEAD (target);
if (src->next_bb != target)
return 0;
- if (!active_insn_p (insn2))
+ if (insn2 && !active_insn_p (insn2))
insn2 = next_active_insn (insn2);
/* ??? Later we may add code to move jump tables offline. */
bool found = false;
/* Allocate the preorder and postorder number arrays. */
- pre = (int *) xcalloc (last_basic_block, sizeof (int));
- post = (int *) xcalloc (last_basic_block, sizeof (int));
+ pre = xcalloc (last_basic_block, sizeof (int));
+ post = xcalloc (last_basic_block, sizeof (int));
/* Allocate stack for back-tracking up CFG. */
- stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
+ stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
CAN_FALLTHRU edges. */
if (!bb->succ || !bb->succ->succ_next || bb->succ->succ_next->succ_next)
continue;
- if (!any_condjump_p (bb->end))
+ if (!any_condjump_p (BB_END (bb)))
continue;
- if (!invert_jump (bb->end, JUMP_LABEL (bb->end), 0))
+ if (!invert_jump (BB_END (bb), JUMP_LABEL (BB_END (bb)), 0))
continue;
- invert_jump (bb->end, JUMP_LABEL (bb->end), 0);
+ invert_jump (BB_END (bb), JUMP_LABEL (BB_END (bb)), 0);
bb->succ->flags |= EDGE_CAN_FALLTHRU;
bb->succ->succ_next->flags |= EDGE_CAN_FALLTHRU;
}
if (check_last_block)
{
basic_block bb = EXIT_BLOCK_PTR->prev_bb;
- rtx insn = bb->end;
+ rtx insn = BB_END (bb);
/* Back up past insns that must be kept in the same block as a call. */
- while (insn != bb->head
+ while (insn != BB_HEAD (bb)
&& keep_with_call_p (insn))
insn = PREV_INSN (insn);
for (i = 0; i < last_bb; i++)
{
basic_block bb = BASIC_BLOCK (i);
+ rtx libcall_end = NULL_RTX;
rtx insn;
rtx prev_insn;
if (blocks && !TEST_BIT (blocks, i))
continue;
- for (insn = bb->end; ; insn = prev_insn)
+ for (insn = BB_END (bb); ; insn = prev_insn)
{
prev_insn = PREV_INSN (insn);
if (need_fake_edge_p (insn))
edge e;
rtx split_at_insn = insn;
+ /* Don't split libcalls. */
+ if (libcall_end)
+ split_at_insn = libcall_end;
+
/* Don't split the block between a call and an insn that should
remain in the same block as the call. */
- if (GET_CODE (insn) == CALL_INSN)
- while (split_at_insn != bb->end
+ else if (GET_CODE (insn) == CALL_INSN)
+ while (split_at_insn != BB_END (bb)
&& keep_with_call_p (NEXT_INSN (split_at_insn)))
split_at_insn = NEXT_INSN (split_at_insn);
cause us to mark that edge as fake and remove it later. */
#ifdef ENABLE_CHECKING
- if (split_at_insn == bb->end)
+ if (split_at_insn == BB_END (bb))
for (e = bb->succ; e; e = e->succ_next)
if (e->dest == EXIT_BLOCK_PTR)
abort ();
/* Note that the following may create a new basic block
and renumber the existing basic blocks. */
- if (split_at_insn != bb->end)
+ if (split_at_insn != BB_END (bb))
{
e = split_block (bb, split_at_insn);
if (e)
make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
}
- if (insn == bb->head)
+ /* Watch out for REG_LIBCALL/REG_RETVAL notes so that we know
+ whether we are currently in a libcall or not. Remember that
+ we are scanning backwards! */
+ if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
+ libcall_end = insn;
+ if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
+ libcall_end = NULL_RTX;
+
+ if (insn == BB_HEAD (bb))
break;
}
}
edge e;
basic_block *tos, *worklist, bb;
- tos = worklist =
- (basic_block *) xmalloc (sizeof (basic_block) * n_basic_blocks);
+ tos = worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
/* Clear all the reachability flags. */
num_edges++;
}
- elist = (struct edge_list *) xmalloc (sizeof (struct edge_list));
+ elist = xmalloc (sizeof (struct edge_list));
elist->num_blocks = block_count;
elist->num_edges = num_edges;
- elist->index_to_edge = (edge *) xmalloc (sizeof (edge) * num_edges);
+ elist->index_to_edge = xmalloc (sizeof (edge) * num_edges);
num_edges = 0;
sbitmap visited;
/* Allocate stack for back-tracking up CFG. */
- stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
+ stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
sbitmap visited;
/* Allocate stack for back-tracking up CFG. */
- stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
+ stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
basic_block bb;
/* Allocate stack for back-tracking up CFG. */
- stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
+ stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
sp = 0;
/* Allocate the tree. */
- dfst = (struct dfst_node *) xcalloc (last_basic_block,
- sizeof (struct dfst_node));
+ dfst = xcalloc (last_basic_block, sizeof (struct dfst_node));
FOR_EACH_BB (bb)
{
dfst[bb->index].node
= (max_successors
- ? (struct dfst_node **) xcalloc (max_successors,
- sizeof (struct dfst_node *))
- : NULL);
+ ? xcalloc (max_successors, sizeof (struct dfst_node *)) : NULL);
}
/* Allocate bitmap to track nodes that have been visited. */
flow_dfs_compute_reverse_init (depth_first_search_ds data)
{
/* Allocate stack for back-tracking up CFG. */
- data->stack = (basic_block *) xmalloc ((n_basic_blocks - (INVALID_BLOCK + 1))
- * sizeof (basic_block));
+ data->stack = xmalloc ((n_basic_blocks - (INVALID_BLOCK + 1))
+ * sizeof (basic_block));
data->sp = 0;
/* Allocate bitmap to track nodes that have been visited. */