2005-06-16 Jan Hubicka <jh@suse.cz>
+ * basic-block.h (rtl_bb_info): Break out head_, end_,
+ global_live_at_start, global_live_at_end from ...
+ (basic_block_def): ... here; update all references
+ (BB_RTL): New flag.
+ (init_rtl_bb_info): Declare.
+ * cfgexpand.c (expand_gimple_basic_block): Init bb info, set BB_RTL
+ flag.
+ * cfgrtl.c: Include ggc.h
+ (create_basic_block_structure): Init bb info.
+ (rtl_verify_flow_info_1): Check BB_RTL flag and rtl_bb_info pointer.
+ (init_rtl_bb_info): New function.
+ (rtl_merge_block, cfglayout_merge_block): Copy global_live_at_end here.
+ * cfghooks.c (merge_block): Do not copy global_live_at_end here.
+ * cfg.c (clear_bb_flags): Skip BB_RTL flag.
+ (dump_flow_info): Gueard global_live_* dumping.
+
* Makefile.in (cfg.o): Add new dependencies.
* basic-block.h (reorder_block_def): Kill
original/copy/duplicated/copy_number fields.
/* Declared in tree-flow.h. */
struct edge_prediction;
+struct rtl_bb_info;
/* A basic block is a sequence of instructions with only entry and
only one exit. If any one of the instructions are executed, they
/* Basic block information indexed by block number. */
struct basic_block_def GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb")))
{
- /* The first and last insns of the block. */
- rtx head_;
- rtx end_;
-
/* Pointers to the first and last trees of the block. */
tree stmt_list;
VEC(edge,gc) *preds;
VEC(edge,gc) *succs;
- /* The registers that are live on entry to this block. */
- bitmap GTY ((skip (""))) global_live_at_start;
-
- /* The registers that are live on exit from this block. */
- bitmap GTY ((skip (""))) global_live_at_end;
-
/* Auxiliary info specific to a pass. */
PTR GTY ((skip (""))) aux;
/* The data used by basic block copying and reordering functions. */
struct reorder_block_def * rbi;
+ union basic_block_il_dependent {
+ struct rtl_bb_info * GTY ((tag ("1"))) rtl;
+ } GTY ((desc ("((%1.flags & BB_RTL) != 0)"))) il;
+
/* Chain of PHI nodes for this block. */
tree phi_nodes;
int flags;
};
+struct rtl_bb_info GTY(())
+{
+ /* The first and last insns of the block. */
+ rtx head_;
+ rtx end_;
+
+ /* The registers that are live on entry to this block. */
+ bitmap GTY ((skip (""))) global_live_at_start;
+
+ /* The registers that are live on exit from this block. */
+ bitmap GTY ((skip (""))) global_live_at_end;
+};
+
typedef struct basic_block_def *basic_block;
/* Structure to hold information about the blocks during reordering and
BB_COLD_PARTITION = 128,
/* Set on block that was duplicated. */
- BB_DUPLICATED = 256
+ BB_DUPLICATED = 256,
+
+ /* Set on blocks that are in RTL format. */
+ BB_RTL = 1024
};
/* Dummy flag for convenience in the hot/cold partitioning code. */
\f
/* Stuff for recording basic block info. */
-#define BB_HEAD(B) (B)->head_
-#define BB_END(B) (B)->end_
+#define BB_HEAD(B) (B)->il.rtl->head_
+#define BB_END(B) (B)->il.rtl->end_
/* Special block numbers [markers] for entry and exit. */
#define ENTRY_BLOCK (-1)
extern void break_superblocks (void);
extern void check_bb_profile (basic_block, FILE *);
extern void update_bb_profile_for_threading (basic_block, int, gcov_type, edge);
+extern void init_rtl_bb_info (basic_block);
extern void initialize_original_copy_tables (void);
extern void free_original_copy_tables (void);
/* Update register liveness information. */
- new_bb->global_live_at_start = ALLOC_REG_SET (®_obstack);
- new_bb->global_live_at_end = ALLOC_REG_SET (®_obstack);
- COPY_REG_SET (new_bb->global_live_at_end,
- prev_bb->global_live_at_end);
- COPY_REG_SET (new_bb->global_live_at_start,
- prev_bb->global_live_at_end);
+ new_bb->il.rtl->global_live_at_start = ALLOC_REG_SET (®_obstack);
+ new_bb->il.rtl->global_live_at_end = ALLOC_REG_SET (®_obstack);
+ COPY_REG_SET (new_bb->il.rtl->global_live_at_end,
+ prev_bb->il.rtl->global_live_at_end);
+ COPY_REG_SET (new_bb->il.rtl->global_live_at_start,
+ prev_bb->il.rtl->global_live_at_end);
/* Put appropriate instructions in new bb. */
CLEAR_HARD_REG_SET (info.btrs_written_in_block);
for (reg = first_btr; reg <= last_btr; reg++)
if (TEST_HARD_REG_BIT (all_btrs, reg)
- && REGNO_REG_SET_P (bb->global_live_at_start, reg))
+ && REGNO_REG_SET_P (bb->il.rtl->global_live_at_start, reg))
SET_HARD_REG_BIT (info.btrs_live_in_block, reg);
for (insn = BB_HEAD (bb), last = NEXT_INSN (BB_END (bb));
COPY_HARD_REG_SET (btrs_live[i], info.btrs_live_in_block);
COPY_HARD_REG_SET (btrs_written[i], info.btrs_written_in_block);
- REG_SET_TO_HARD_REG_SET (btrs_live_at_end[i], bb->global_live_at_end);
+ REG_SET_TO_HARD_REG_SET (btrs_live_at_end[i], bb->il.rtl->global_live_at_end);
/* If this block ends in a jump insn, add any uses or even clobbers
of branch target registers that it might have. */
for (insn = BB_END (bb); insn != BB_HEAD (bb) && ! INSN_P (insn); )
basic_block bb;
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
- bb->flags = BB_PARTITION (bb) | (bb->flags & BB_DISABLE_SCHEDULE);
+ bb->flags = (BB_PARTITION (bb) | (bb->flags & BB_DISABLE_SCHEDULE)
+ | (bb->flags & BB_RTL));
}
\f
/* Check the consistency of profile information. We can't do that
FOR_EACH_EDGE (e, ei, bb->succs)
dump_edge_info (file, e, 1);
- if (bb->global_live_at_start)
+ if (bb->flags & BB_RTL)
{
- fprintf (file, "\nRegisters live at start:");
- dump_regset (bb->global_live_at_start, file);
- }
-
- if (bb->global_live_at_end)
- {
- fprintf (file, "\nRegisters live at end:");
- dump_regset (bb->global_live_at_end, file);
+ if (bb->il.rtl->global_live_at_start)
+ {
+ fprintf (file, "\nRegisters live at start:");
+ dump_regset (bb->il.rtl->global_live_at_start, file);
+ }
+
+ if (bb->il.rtl->global_live_at_end)
+ {
+ fprintf (file, "\nRegisters live at end:");
+ dump_regset (bb->il.rtl->global_live_at_end, file);
+ }
}
putc ('\n', file);
/* In case liveness information is available, we need to prove equivalence
only of the live values. */
if (mode & CLEANUP_UPDATE_LIFE)
- AND_REG_SET (nonequal, b->global_live_at_end);
+ AND_REG_SET (nonequal, b->il.rtl->global_live_at_end);
EXECUTE_IF_SET_IN_REG_SET (nonequal, 0, i, rsi)
goto failed_exit;
bb->index);
}
+ init_rtl_bb_info (bb);
+ bb->flags |= BB_RTL;
+
if (!bsi_end_p (bsi))
stmt = bsi_stmt (bsi);
/* Multiple entry points not supported yet. */
gcc_assert (EDGE_COUNT (ENTRY_BLOCK_PTR->succs) == 1);
+ init_rtl_bb_info (ENTRY_BLOCK_PTR);
+ init_rtl_bb_info (EXIT_BLOCK_PTR);
+ ENTRY_BLOCK_PTR->flags |= BB_RTL;
+ EXIT_BLOCK_PTR->flags |= BB_RTL;
e = EDGE_SUCC (ENTRY_BLOCK_PTR, 0);
/* B hasn't quite yet ceased to exist. Attempt to prevent mishap. */
b->preds = b->succs = NULL;
- a->global_live_at_end = b->global_live_at_end;
if (dom_computed[CDI_DOMINATORS])
redirect_immediate_dominators (CDI_DOMINATORS, b, a);
new_bb->rbi->footer = unlink_insn_chain (insn, get_last_insn ());
}
- if (bb->global_live_at_start)
+ if (bb->il.rtl->global_live_at_start)
{
- new_bb->global_live_at_start = ALLOC_REG_SET (®_obstack);
- new_bb->global_live_at_end = ALLOC_REG_SET (®_obstack);
- COPY_REG_SET (new_bb->global_live_at_start, bb->global_live_at_start);
- COPY_REG_SET (new_bb->global_live_at_end, bb->global_live_at_end);
+ new_bb->il.rtl->global_live_at_start = ALLOC_REG_SET (®_obstack);
+ new_bb->il.rtl->global_live_at_end = ALLOC_REG_SET (®_obstack);
+ COPY_REG_SET (new_bb->il.rtl->global_live_at_start,
+ bb->il.rtl->global_live_at_start);
+ COPY_REG_SET (new_bb->il.rtl->global_live_at_end,
+ bb->il.rtl->global_live_at_end);
}
return new_bb;
#include "expr.h"
#include "target.h"
#include "cfgloop.h"
+#include "ggc.h"
static int can_delete_note_p (rtx);
static int can_delete_label_p (rtx);
bb = alloc_block ();
+ init_rtl_bb_info (bb);
if (!head && !end)
head = end = bb_note
= emit_note_after (NOTE_INSN_BASIC_BLOCK, get_last_insn ());
BB_HEAD (bb) = head;
BB_END (bb) = end;
bb->index = last_basic_block++;
- bb->flags = BB_NEW;
+ bb->flags = BB_NEW | BB_RTL;
link_block (bb, after);
BASIC_BLOCK (bb->index) = bb;
update_bb_for_insn (bb);
FOR_EACH_EDGE (e, ei, new_bb->succs)
e->src = new_bb;
- if (bb->global_live_at_start)
+ if (bb->il.rtl->global_live_at_start)
{
- new_bb->global_live_at_start = ALLOC_REG_SET (®_obstack);
- new_bb->global_live_at_end = ALLOC_REG_SET (®_obstack);
- COPY_REG_SET (new_bb->global_live_at_end, bb->global_live_at_end);
+ new_bb->il.rtl->global_live_at_start = ALLOC_REG_SET (®_obstack);
+ new_bb->il.rtl->global_live_at_end = ALLOC_REG_SET (®_obstack);
+ COPY_REG_SET (new_bb->il.rtl->global_live_at_end, bb->il.rtl->global_live_at_end);
/* We now have to calculate which registers are live at the end
of the split basic block and at the start of the new basic
block. Start with those registers that are known to be live
at the end of the original basic block and get
propagate_block to determine which registers are live. */
- COPY_REG_SET (new_bb->global_live_at_start, bb->global_live_at_end);
- propagate_block (new_bb, new_bb->global_live_at_start, NULL, NULL, 0);
- COPY_REG_SET (bb->global_live_at_end,
- new_bb->global_live_at_start);
+ COPY_REG_SET (new_bb->il.rtl->global_live_at_start, bb->il.rtl->global_live_at_end);
+ propagate_block (new_bb, new_bb->il.rtl->global_live_at_start, NULL, NULL, 0);
+ COPY_REG_SET (bb->il.rtl->global_live_at_end,
+ new_bb->il.rtl->global_live_at_start);
#ifdef HAVE_conditional_execution
/* In the presence of conditional execution we are not able to update
liveness precisely. */
}
BB_END (a) = a_end;
+ a->il.rtl->global_live_at_end = b->il.rtl->global_live_at_end;
}
/* Return true when block A and B can be merged. */
jump_block->frequency = EDGE_FREQUENCY (e);
jump_block->loop_depth = target->loop_depth;
- if (target->global_live_at_start)
+ if (target->il.rtl->global_live_at_start)
{
- jump_block->global_live_at_start = ALLOC_REG_SET (®_obstack);
- jump_block->global_live_at_end = ALLOC_REG_SET (®_obstack);
- COPY_REG_SET (jump_block->global_live_at_start,
- target->global_live_at_start);
- COPY_REG_SET (jump_block->global_live_at_end,
- target->global_live_at_start);
+ jump_block->il.rtl->global_live_at_start = ALLOC_REG_SET (®_obstack);
+ jump_block->il.rtl->global_live_at_end = ALLOC_REG_SET (®_obstack);
+ COPY_REG_SET (jump_block->il.rtl->global_live_at_start,
+ target->il.rtl->global_live_at_start);
+ COPY_REG_SET (jump_block->il.rtl->global_live_at_end,
+ target->il.rtl->global_live_at_start);
}
/* Make sure new block ends up in correct hot/cold section. */
}
/* ??? This info is likely going to be out of date very soon. */
- if (edge_in->dest->global_live_at_start)
+ if (edge_in->dest->il.rtl->global_live_at_start)
{
- bb->global_live_at_start = ALLOC_REG_SET (®_obstack);
- bb->global_live_at_end = ALLOC_REG_SET (®_obstack);
- COPY_REG_SET (bb->global_live_at_start,
- edge_in->dest->global_live_at_start);
- COPY_REG_SET (bb->global_live_at_end,
- edge_in->dest->global_live_at_start);
+ bb->il.rtl->global_live_at_start = ALLOC_REG_SET (®_obstack);
+ bb->il.rtl->global_live_at_end = ALLOC_REG_SET (®_obstack);
+ COPY_REG_SET (bb->il.rtl->global_live_at_start,
+ edge_in->dest->il.rtl->global_live_at_start);
+ COPY_REG_SET (bb->il.rtl->global_live_at_end,
+ edge_in->dest->il.rtl->global_live_at_start);
}
make_single_succ_edge (bb, edge_in->dest, EDGE_FALLTHRU);
&& !REGNO_PTR_FRAME_P (regno))
SET_REGNO_REG_SET (killed, regno);
- bitmap_and_into (killed, e->dest->global_live_at_start);
+ bitmap_and_into (killed, e->dest->il.rtl->global_live_at_start);
EXECUTE_IF_SET_IN_REG_SET (killed, 0, regno, rsi)
{
s_indent[indent] = '\0';
fprintf (outf, ";;%s Registers live at start: ", s_indent);
- dump_regset (bb->global_live_at_start, outf);
+ dump_regset (bb->il.rtl->global_live_at_start, outf);
putc ('\n', outf);
for (insn = BB_HEAD (bb), last = NEXT_INSN (BB_END (bb)); insn != last;
print_rtl_single (outf, insn);
fprintf (outf, ";;%s Registers live at end: ", s_indent);
- dump_regset (bb->global_live_at_end, outf);
+ dump_regset (bb->il.rtl->global_live_at_end, outf);
putc ('\n', outf);
}
\f
{
fprintf (outf, ";; Start of basic block %d, registers live:",
bb->index);
- dump_regset (bb->global_live_at_start, outf);
+ dump_regset (bb->il.rtl->global_live_at_start, outf);
putc ('\n', outf);
}
{
fprintf (outf, ";; End of basic block %d, registers live:\n",
bb->index);
- dump_regset (bb->global_live_at_end, outf);
+ dump_regset (bb->il.rtl->global_live_at_end, outf);
putc ('\n', outf);
}
if (x == end)
break;
+ if (!(bb->flags & BB_RTL))
+ {
+ error ("BB_RTL flag not set for block %d", bb->index);
+ err = 1;
+ }
+
if (!x)
{
error ("end insn %d for block %d not found in the insn stream",
}
b->rbi->footer = NULL;
}
+ a->il.rtl->global_live_at_end = b->il.rtl->global_live_at_end;
if (dump_file)
fprintf (dump_file, "Merged blocks %d and %d.\n",
/* ??? This info is likely going to be out of date very soon, but we must
create it to avoid getting an ICE later. */
- if (e->dest->global_live_at_start)
+ if (e->dest->il.rtl->global_live_at_start)
{
- new_bb->global_live_at_start = ALLOC_REG_SET (®_obstack);
- new_bb->global_live_at_end = ALLOC_REG_SET (®_obstack);
- COPY_REG_SET (new_bb->global_live_at_start,
- e->dest->global_live_at_start);
- COPY_REG_SET (new_bb->global_live_at_end,
- e->dest->global_live_at_start);
+ new_bb->il.rtl->global_live_at_start = ALLOC_REG_SET (®_obstack);
+ new_bb->il.rtl->global_live_at_end = ALLOC_REG_SET (®_obstack);
+ COPY_REG_SET (new_bb->il.rtl->global_live_at_start,
+ e->dest->il.rtl->global_live_at_start);
+ COPY_REG_SET (new_bb->il.rtl->global_live_at_end,
+ e->dest->il.rtl->global_live_at_start);
}
make_edge (new_bb, e->dest, EDGE_FALLTHRU);
}
}
+void
+init_rtl_bb_info (basic_block bb)
+{
+ gcc_assert (!bb->il.rtl);
+ bb->il.rtl = ggc_alloc_cleared (sizeof (struct rtl_bb_info));
+}
+
/* Implementation of CFG manipulation for linearized RTL. */
struct cfg_hooks rtl_cfg_hooks = {
&& REGNO (x) >= FIRST_PSEUDO_REGISTER
/* If this register is undefined at the start of the file, we can't
say what its contents were. */
- && ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, REGNO (x))
+ && ! REGNO_REG_SET_P
+ (ENTRY_BLOCK_PTR->next_bb->il.rtl->global_live_at_start, REGNO (x))
&& GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
{
if (set == 0 || GET_CODE (set) == CLOBBER)
&& (reg_stat[REGNO (x)].last_set_label == label_tick
|| (REGNO (x) >= FIRST_PSEUDO_REGISTER
&& REG_N_SETS (REGNO (x)) == 1
- && ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start,
- REGNO (x))))
+ && ! REGNO_REG_SET_P
+ (ENTRY_BLOCK_PTR->next_bb->il.rtl->global_live_at_start,
+ REGNO (x))))
&& INSN_CUID (reg_stat[REGNO (x)].last_set) < subst_low_cuid)
{
*nonzero &= reg_stat[REGNO (x)].last_set_nonzero_bits;
&& (reg_stat[REGNO (x)].last_set_label == label_tick
|| (REGNO (x) >= FIRST_PSEUDO_REGISTER
&& REG_N_SETS (REGNO (x)) == 1
- && ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start,
- REGNO (x))))
+ && ! REGNO_REG_SET_P
+ (ENTRY_BLOCK_PTR->next_bb->il.rtl->global_live_at_start,
+ REGNO (x))))
&& INSN_CUID (reg_stat[REGNO (x)].last_set) < subst_low_cuid)
{
*result = reg_stat[REGNO (x)].last_set_sign_bit_copies;
|| (! (regno >= FIRST_PSEUDO_REGISTER
&& REG_N_SETS (regno) == 1
&& (! REGNO_REG_SET_P
- (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno)))
+ (ENTRY_BLOCK_PTR->next_bb->il.rtl->global_live_at_start,
+ regno)))
&& reg_stat[j].last_set_label > tick))
{
if (replace)
&& (regno < FIRST_PSEUDO_REGISTER
|| REG_N_SETS (regno) != 1
|| (REGNO_REG_SET_P
- (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno)))))
+ (ENTRY_BLOCK_PTR->next_bb->il.rtl->global_live_at_start,
+ regno)))))
return 0;
/* If the value was set in a later insn than the ones we are processing,
}
for (i = reg_dead_regno; i < reg_dead_endregno; i++)
- if (REGNO_REG_SET_P (block->global_live_at_start, i))
+ if (REGNO_REG_SET_P (block->il.rtl->global_live_at_start, i))
return 0;
return 1;
was dead, there's nothing left to do. Otherwise, we'll
need to do a global life update after combine. */
if (REG_NOTE_KIND (note) == REG_DEAD && place == 0
- && REGNO_REG_SET_P (bb->global_live_at_start,
+ && REGNO_REG_SET_P (bb->il.rtl->global_live_at_start,
REGNO (XEXP (note, 0))))
SET_BIT (refresh_blocks, this_basic_block->index);
}
for (j = CC_FIRST; j <= CC_LAST; j++)
if (TEST_HARD_REG_BIT (tmp_reg->regs, j))
{
- if (REGNO_REG_SET_P (then_bb->global_live_at_start, j))
+ if (REGNO_REG_SET_P (then_bb->il.rtl->global_live_at_start, j))
continue;
- if (else_bb && REGNO_REG_SET_P (else_bb->global_live_at_start, j))
+ if (else_bb
+ && REGNO_REG_SET_P (else_bb->il.rtl->global_live_at_start, j))
continue;
- if (join_bb && REGNO_REG_SET_P (join_bb->global_live_at_start, j))
+ if (join_bb
+ && REGNO_REG_SET_P (join_bb->il.rtl->global_live_at_start, j))
continue;
SET_HARD_REG_BIT (frv_ifcvt.nested_cc_ok_rewrite, j);
/* Remove anything live at the beginning of the join block from being
available for allocation. */
- EXECUTE_IF_SET_IN_REG_SET (join_bb->global_live_at_start, 0, regno, rsi)
+ EXECUTE_IF_SET_IN_REG_SET (join_bb->il.rtl->global_live_at_start, 0, regno, rsi)
{
if (regno < FIRST_PSEUDO_REGISTER)
CLEAR_HARD_REG_BIT (tmp_reg->regs, regno);
/* Anything live at the beginning of the block is obviously unavailable
for allocation. */
- EXECUTE_IF_SET_IN_REG_SET (bb[j]->global_live_at_start, 0, regno, rsi)
+ EXECUTE_IF_SET_IN_REG_SET (bb[j]->il.rtl->global_live_at_start, 0, regno, rsi)
{
if (regno < FIRST_PSEUDO_REGISTER)
CLEAR_HARD_REG_BIT (tmp_reg->regs, regno);
severely. */
&& ce_info->join_bb
&& ! (REGNO_REG_SET_P
- (ce_info->join_bb->global_live_at_start,
+ (ce_info->join_bb->il.rtl->global_live_at_start,
REGNO (SET_DEST (set))))
/* Similarly, we must not unconditionally set a reg
used as scratch in the THEN branch if the same reg
&& (! ce_info->else_bb
|| BLOCK_FOR_INSN (insn) == ce_info->else_bb
|| ! (REGNO_REG_SET_P
- (ce_info->else_bb->global_live_at_start,
+ (ce_info->else_bb->il.rtl->global_live_at_start,
REGNO (SET_DEST (set))))))
pattern = set;
to correct at this point. This gives false positives for broken
functions that might use uninitialized data that happens to be
allocated in eax, but who cares? */
- return REGNO_REG_SET_P (ENTRY_BLOCK_PTR->global_live_at_end, 0);
+ return REGNO_REG_SET_P (ENTRY_BLOCK_PTR->il.rtl->global_live_at_end, 0);
}
/* Value is the number of bytes of arguments automatically
/* Skip p0, which may be thought to be live due to (reg:DI p0)
grabbing the entire block of predicate registers. */
for (r = PR_REG (2); r < PR_REG (64); r += 2)
- if (REGNO_REG_SET_P (bb->global_live_at_start, r))
+ if (REGNO_REG_SET_P (bb->il.rtl->global_live_at_start, r))
{
rtx p = gen_rtx_REG (BImode, r);
rtx n = emit_insn_after (gen_pred_rel_mutex (p), head);
allocate_bb_life_data ();
/* Find the set of registers live on function exit. */
- mark_regs_live_at_end (EXIT_BLOCK_PTR->global_live_at_start);
+ mark_regs_live_at_end (EXIT_BLOCK_PTR->il.rtl->global_live_at_start);
/* "Update" life info from zero. It'd be nice to begin the
relaxation with just the exit and noreturn blocks, but that set
{
/* After reload, there are no pseudos, nor subregs of multi-word
registers. The regsets should exactly match. */
- if (! REG_SET_EQUAL_P (new_live_at_start, bb->global_live_at_start))
+ if (! REG_SET_EQUAL_P (new_live_at_start,
+ bb->il.rtl->global_live_at_start))
{
if (dump_file)
{
reg_set_iterator rsi;
/* Find the set of changed registers. */
- XOR_REG_SET (new_live_at_start, bb->global_live_at_start);
+ XOR_REG_SET (new_live_at_start, bb->il.rtl->global_live_at_start);
EXECUTE_IF_SET_IN_REG_SET (new_live_at_start, 0, i, rsi)
{
/* No registers should die. */
- if (REGNO_REG_SET_P (bb->global_live_at_start, i))
+ if (REGNO_REG_SET_P (bb->il.rtl->global_live_at_start, i))
{
if (dump_file)
{
in turn may allow for further dead code detection / removal. */
FOR_EACH_BB_REVERSE (bb)
{
- COPY_REG_SET (tmp, bb->global_live_at_end);
+ COPY_REG_SET (tmp, bb->il.rtl->global_live_at_end);
changed |= propagate_block (bb, tmp, NULL, NULL,
prop_flags & (PROP_SCAN_DEAD_CODE
| PROP_SCAN_DEAD_STORES
in the code being marked live at entry. */
FOR_EACH_BB (bb)
{
- CLEAR_REG_SET (bb->global_live_at_start);
- CLEAR_REG_SET (bb->global_live_at_end);
+ CLEAR_REG_SET (bb->il.rtl->global_live_at_start);
+ CLEAR_REG_SET (bb->il.rtl->global_live_at_end);
}
}
{
bb = BASIC_BLOCK (i);
- COPY_REG_SET (tmp, bb->global_live_at_end);
+ COPY_REG_SET (tmp, bb->il.rtl->global_live_at_end);
propagate_block (bb, tmp, NULL, NULL, stabilized_prop_flags);
if (extent == UPDATE_LIFE_LOCAL)
{
FOR_EACH_BB_REVERSE (bb)
{
- COPY_REG_SET (tmp, bb->global_live_at_end);
+ COPY_REG_SET (tmp, bb->il.rtl->global_live_at_end);
propagate_block (bb, tmp, NULL, NULL, stabilized_prop_flags);
are those that were not set anywhere in the function. local-alloc
doesn't know how to handle these correctly, so mark them as not
local to any one basic block. */
- EXECUTE_IF_SET_IN_REG_SET (ENTRY_BLOCK_PTR->global_live_at_end,
+ EXECUTE_IF_SET_IN_REG_SET (ENTRY_BLOCK_PTR->il.rtl->global_live_at_end,
FIRST_PSEUDO_REGISTER, i, rsi)
REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL;
label_to_block_map = NULL;
ENTRY_BLOCK_PTR->aux = NULL;
- ENTRY_BLOCK_PTR->global_live_at_end = NULL;
+ ENTRY_BLOCK_PTR->il.rtl->global_live_at_end = NULL;
EXIT_BLOCK_PTR->aux = NULL;
- EXIT_BLOCK_PTR->global_live_at_start = NULL;
+ EXIT_BLOCK_PTR->il.rtl->global_live_at_start = NULL;
}
/* Delete any insns that copy a register to itself. */
confused by sibling call edges, which crashes reg-stack. */
if (e->flags & EDGE_EH)
bitmap_ior_and_compl_into (new_live_at_end,
- sb->global_live_at_start,
+ sb->il.rtl->global_live_at_start,
invalidated_by_call);
else
- IOR_REG_SET (new_live_at_end, sb->global_live_at_start);
+ IOR_REG_SET (new_live_at_end, sb->il.rtl->global_live_at_start);
/* If a target saves one register in another (instead of on
the stack) the save register will need to be live for EH. */
if (bb == ENTRY_BLOCK_PTR)
{
- COPY_REG_SET (bb->global_live_at_end, new_live_at_end);
+ COPY_REG_SET (bb->il.rtl->global_live_at_end, new_live_at_end);
continue;
}
rescan the block. This wouldn't be necessary if we had
precalculated local_live, however with PROP_SCAN_DEAD_CODE
local_live is really dependent on live_at_end. */
- rescan = bitmap_intersect_compl_p (bb->global_live_at_end,
+ rescan = bitmap_intersect_compl_p (bb->il.rtl->global_live_at_end,
new_live_at_end);
if (!rescan)
/* Find the set of changed bits. Take this opportunity
to notice that this set is empty and early out. */
- bitmap_xor (tmp, bb->global_live_at_end, new_live_at_end);
+ bitmap_xor (tmp, bb->il.rtl->global_live_at_end, new_live_at_end);
if (bitmap_empty_p (tmp))
continue;
/* Add to live_at_start the set of all registers in
new_live_at_end that aren't in the old live_at_end. */
- changed = bitmap_ior_and_compl_into (bb->global_live_at_start,
+ changed = bitmap_ior_and_compl_into (bb->il.rtl->global_live_at_start,
new_live_at_end,
- bb->global_live_at_end);
- COPY_REG_SET (bb->global_live_at_end, new_live_at_end);
+ bb->il.rtl->global_live_at_end);
+ COPY_REG_SET (bb->il.rtl->global_live_at_end, new_live_at_end);
if (! changed)
continue;
}
else
{
- COPY_REG_SET (bb->global_live_at_end, new_live_at_end);
+ COPY_REG_SET (bb->il.rtl->global_live_at_end, new_live_at_end);
/* Rescan the block insn by insn to turn (a copy of) live_at_end
into live_at_start. */
flags);
/* If live_at start didn't change, no need to go farther. */
- if (REG_SET_EQUAL_P (bb->global_live_at_start, new_live_at_end))
+ if (REG_SET_EQUAL_P (bb->il.rtl->global_live_at_start,
+ new_live_at_end))
continue;
if (failure_strategy_required)
{
/* Get the list of registers that were removed from the
bb->global_live_at_start set. */
- bitmap_and_compl (tmp, bb->global_live_at_start,
+ bitmap_and_compl (tmp, bb->il.rtl->global_live_at_start,
new_live_at_end);
if (!bitmap_empty_p (tmp))
{
pbb_changed = false;
pbb_changed
- |= bitmap_and_compl_into (pbb->global_live_at_start,
- registers_made_dead);
+ |= bitmap_and_compl_into
+ (pbb->il.rtl->global_live_at_start,
+ registers_made_dead);
pbb_changed
- |= bitmap_and_compl_into (pbb->global_live_at_end,
- registers_made_dead);
+ |= bitmap_and_compl_into
+ (pbb->il.rtl->global_live_at_end,
+ registers_made_dead);
if (!pbb_changed)
continue;
}
} /* end of failure_strategy_required */
- COPY_REG_SET (bb->global_live_at_start, new_live_at_end);
+ COPY_REG_SET (bb->il.rtl->global_live_at_start, new_live_at_end);
}
/* Queue all predecessors of BB so that we may re-examine
FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
{
basic_block bb = e->dest;
- regset map = bb->global_live_at_start;
+ regset map = bb->il.rtl->global_live_at_start;
reg_set_iterator rsi;
EXECUTE_IF_SET_IN_REG_SET (map, FIRST_PSEUDO_REGISTER, reg, rsi)
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
{
- bb->global_live_at_start = ALLOC_REG_SET (®_obstack);
- bb->global_live_at_end = ALLOC_REG_SET (®_obstack);
+ bb->il.rtl->global_live_at_start = ALLOC_REG_SET (®_obstack);
+ bb->il.rtl->global_live_at_end = ALLOC_REG_SET (®_obstack);
}
regs_live_at_setjmp = ALLOC_REG_SET (®_obstack);
except for return values. */
sibcall_p = SIBLING_CALL_P (insn);
- live_at_end = EXIT_BLOCK_PTR->global_live_at_start;
+ live_at_end = EXIT_BLOCK_PTR->il.rtl->global_live_at_start;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)
&& ! (sibcall_p
}
/* Compute which register lead different lives in the successors. */
- bitmap_xor (diff, bb_true->global_live_at_start,
- bb_false->global_live_at_start);
+ bitmap_xor (diff, bb_true->il.rtl->global_live_at_start,
+ bb_false->il.rtl->global_live_at_start);
if (!bitmap_empty_p (diff))
{
rcli = xmalloc (sizeof (*rcli));
- if (REGNO_REG_SET_P (bb_true->global_live_at_start, i))
+ if (REGNO_REG_SET_P (bb_true->il.rtl->global_live_at_start,
+ i))
cond = cond_false;
else
cond = cond_true;
return 0;
return ((REG_N_SETS (regno) > 1
- || REGNO_REG_SET_P (ENTRY_BLOCK_PTR->global_live_at_end, regno))
+ || REGNO_REG_SET_P (ENTRY_BLOCK_PTR->il.rtl->global_live_at_end,
+ regno))
&& REGNO_REG_SET_P (regs_live_at_setjmp, regno));
}
\f
if (HARD_REGNO_MODE_OK (regno, Pmode)
&& !fixed_regs[regno]
&& TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)
- && !REGNO_REG_SET_P (EXIT_BLOCK_PTR->global_live_at_start,
- regno)
+ && !REGNO_REG_SET_P
+ (EXIT_BLOCK_PTR->il.rtl->global_live_at_start, regno)
&& !refers_to_regno_p (regno,
regno + hard_regno_nregs[regno]
[Pmode],
be explicitly marked in basic_block_live_at_start. */
{
- regset old = b->global_live_at_start;
+ regset old = b->il.rtl->global_live_at_start;
int ax = 0;
reg_set_iterator rsi;
FOR_EACH_BB (bb)
{
- regset r = bb->global_live_at_start;
+ regset r = bb->il.rtl->global_live_at_start;
if (REGNO_REG_SET_P (r, from))
{
CLEAR_REGNO_REG_SET (r, from);
CLEAR_REG_SET (live_relevant_regs);
- EXECUTE_IF_SET_IN_BITMAP (b->global_live_at_start, 0, i, bi)
+ EXECUTE_IF_SET_IN_BITMAP (b->il.rtl->global_live_at_start, 0, i, bi)
{
if (i < FIRST_PSEUDO_REGISTER
? ! TEST_HARD_REG_BIT (eliminable_regset, i)
if (pred->index != ENTRY_BLOCK)
bitmap_ior_into (bb_live_pavin, BB_INFO (pred)->live_pavout);
}
- bitmap_and_into (bb_live_pavin, bb->global_live_at_start);
+ bitmap_and_into (bb_live_pavin, bb->il.rtl->global_live_at_start);
bitmap_ior_and_compl (temp_bitmap, bb_info->avloc,
bb_live_pavin, bb_info->killed);
- bitmap_and_into (temp_bitmap, bb->global_live_at_end);
+ bitmap_and_into (temp_bitmap, bb->il.rtl->global_live_at_end);
if (! bitmap_equal_p (temp_bitmap, bb_live_pavout))
{
bitmap_copy (bb_live_pavout, temp_bitmap);
{
bb_info = BB_INFO (bb);
- bitmap_and_into (bb->global_live_at_start, bb_info->live_pavin);
- bitmap_and_into (bb->global_live_at_end, bb_info->live_pavout);
+ bitmap_and_into (bb->il.rtl->global_live_at_start, bb_info->live_pavin);
+ bitmap_and_into (bb->il.rtl->global_live_at_end, bb_info->live_pavout);
}
free_bb_info ();
}
if (then_bb)
{
- if (combo_bb->global_live_at_end)
- COPY_REG_SET (combo_bb->global_live_at_end,
- then_bb->global_live_at_end);
+ if (combo_bb->il.rtl->global_live_at_end)
+ COPY_REG_SET (combo_bb->il.rtl->global_live_at_end,
+ then_bb->il.rtl->global_live_at_end);
merge_blocks (combo_bb, then_bb);
num_true_changes++;
}
&& join_bb != EXIT_BLOCK_PTR)
{
/* We can merge the JOIN. */
- if (combo_bb->global_live_at_end)
- COPY_REG_SET (combo_bb->global_live_at_end,
- join_bb->global_live_at_end);
+ if (combo_bb->il.rtl->global_live_at_end)
+ COPY_REG_SET (combo_bb->il.rtl->global_live_at_end,
+ join_bb->il.rtl->global_live_at_end);
merge_blocks (combo_bb, join_bb);
num_true_changes++;
/* Conversion went ok, including moving the insns and fixing up the
jump. Adjust the CFG to match. */
- bitmap_ior (test_bb->global_live_at_end,
- else_bb->global_live_at_start,
- then_bb->global_live_at_end);
+ bitmap_ior (test_bb->il.rtl->global_live_at_end,
+ else_bb->il.rtl->global_live_at_start,
+ then_bb->il.rtl->global_live_at_end);
/* We can avoid creating a new basic block if then_bb is immediately
/* Conversion went ok, including moving the insns and fixing up the
jump. Adjust the CFG to match. */
- bitmap_ior (test_bb->global_live_at_end,
- then_bb->global_live_at_start,
- else_bb->global_live_at_end);
+ bitmap_ior (test_bb->il.rtl->global_live_at_end,
+ then_bb->il.rtl->global_live_at_start,
+ else_bb->il.rtl->global_live_at_end);
delete_basic_block (else_bb);
/* For TEST, we're interested in a range of insns, not a whole block.
Moreover, we're interested in the insns live from OTHER_BB. */
- COPY_REG_SET (test_live, other_bb->global_live_at_start);
+ COPY_REG_SET (test_live, other_bb->il.rtl->global_live_at_start);
pbi = init_propagate_block_info (test_bb, test_live, test_set, test_set,
0);
/* We can perform the transformation if
MERGE_SET & (TEST_SET | TEST_LIVE)
and
- TEST_SET & merge_bb->global_live_at_start
+ TEST_SET & merge_bb->il.rtl->global_live_at_start
are empty. */
if (bitmap_intersect_p (test_set, merge_set)
|| bitmap_intersect_p (test_live, merge_set)
- || bitmap_intersect_p (test_set, merge_bb->global_live_at_start))
+ || bitmap_intersect_p (test_set,
+ merge_bb->il.rtl->global_live_at_start))
fail = 1;
FREE_REG_SET (tmp);
{
FOR_EACH_BB (bb)
{
- AND_COMPL_REG_SET (bb->global_live_at_start, &cleared_regs);
- AND_COMPL_REG_SET (bb->global_live_at_end, &cleared_regs);
+ AND_COMPL_REG_SET (bb->il.rtl->global_live_at_start,
+ &cleared_regs);
+ AND_COMPL_REG_SET (bb->il.rtl->global_live_at_end,
+ &cleared_regs);
}
}
else
{
FOR_EACH_BB (bb)
{
- CLEAR_REGNO_REG_SET (bb->global_live_at_start, j);
- CLEAR_REGNO_REG_SET (bb->global_live_at_end, j);
+ CLEAR_REGNO_REG_SET (bb->il.rtl->global_live_at_start, j);
+ CLEAR_REGNO_REG_SET (bb->il.rtl->global_live_at_end, j);
}
}
}
/* Initialize table of hardware registers currently live. */
- REG_SET_TO_HARD_REG_SET (regs_live, BASIC_BLOCK (b)->global_live_at_start);
+ REG_SET_TO_HARD_REG_SET (regs_live,
+ BASIC_BLOCK (b)->il.rtl->global_live_at_start);
/* This loop scans the instructions of the basic block
and assigns quantities to registers.
if (eg->flags & EDGE_FALLTHRU)
{
basic_block src_bb = eg->src;
- regset live_at_end = src_bb->global_live_at_end;
+ regset live_at_end = src_bb->il.rtl->global_live_at_end;
rtx last_insn, ret_reg;
gcc_assert (!pre_exit);
else
{
pre_exit = split_edge (eg);
- COPY_REG_SET (pre_exit->global_live_at_start, live_at_end);
- COPY_REG_SET (pre_exit->global_live_at_end, live_at_end);
+ COPY_REG_SET (pre_exit->il.rtl->global_live_at_start, live_at_end);
+ COPY_REG_SET (pre_exit->il.rtl->global_live_at_end, live_at_end);
}
}
HARD_REG_SET live_now;
REG_SET_TO_HARD_REG_SET (live_now,
- bb->global_live_at_start);
+ bb->il.rtl->global_live_at_start);
for (insn = BB_HEAD (bb);
insn != NULL && insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
src_bb = eg->src;
REG_SET_TO_HARD_REG_SET (live_at_edge,
- src_bb->global_live_at_end);
+ src_bb->il.rtl->global_live_at_end);
start_sequence ();
EMIT_MODE_SET (entity_map[j], mode, live_at_edge);
HARD_REG_SET live;
REG_SET_TO_HARD_REG_SET (live,
- bb->global_live_at_start);
+ bb->il.rtl->global_live_at_start);
compute_use_by_pseudos (&live,
- bb->global_live_at_start);
+ bb->il.rtl->global_live_at_start);
COPY_HARD_REG_SET (LABEL_LIVE (insn), live);
IOR_HARD_REG_SET (ever_live_at_start, live);
}
peep2_current = MAX_INSNS_PER_PEEP2;
/* Start up propagation. */
- COPY_REG_SET (live, bb->global_live_at_end);
+ COPY_REG_SET (live, bb->il.rtl->global_live_at_end);
COPY_REG_SET (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);
#ifdef HAVE_conditional_execution
/* Some peepholes can decide the don't need one or more of their
inputs. If this happens, local life update is not enough. */
- EXECUTE_IF_AND_COMPL_IN_BITMAP (bb->global_live_at_start, live,
+ EXECUTE_IF_AND_COMPL_IN_BITMAP (bb->il.rtl->global_live_at_start, live,
0, j, rsi)
{
do_global_life_update = true;
/* Copy live_at_end and live_at_start into temporaries. */
for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
{
- if (REGNO_REG_SET_P (bb->global_live_at_end, reg))
+ if (REGNO_REG_SET_P (bb->il.rtl->global_live_at_end, reg))
SET_HARD_REG_BIT (bi->out_reg_set, reg);
- if (REGNO_REG_SET_P (bb->global_live_at_start, reg))
+ if (REGNO_REG_SET_P (bb->il.rtl->global_live_at_start, reg))
SET_HARD_REG_BIT (bi->stack_in.reg_set, reg);
}
}
{
int i;
for (i = 0; i < flags_nregs; ++i)
- live |= REGNO_REG_SET_P (block->global_live_at_start,
+ live |= REGNO_REG_SET_P (block->il.rtl->global_live_at_start,
flags_regno + i);
}
#endif
rtx insn;
HARD_REG_SET live;
- REG_SET_TO_HARD_REG_SET (live, b->global_live_at_start);
+ REG_SET_TO_HARD_REG_SET (live, b->il.rtl->global_live_at_start);
insn = BB_HEAD (b);
while (t)
{
/* Check that we don't use a hardreg for an uninitialized
pseudo. See also find_dummy_reload(). */
&& (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
- || ! bitmap_bit_p (ENTRY_BLOCK_PTR->global_live_at_end,
+ || ! bitmap_bit_p (ENTRY_BLOCK_PTR->il.rtl->global_live_at_end,
ORIGINAL_REGNO (XEXP (note, 0))))
&& ! refers_to_regno_for_reload_p (regno,
(regno
as they would clobber the other live pseudo using the same.
See also PR20973. */
&& (ORIGINAL_REGNO (in) < FIRST_PSEUDO_REGISTER
- || ! bitmap_bit_p (ENTRY_BLOCK_PTR->global_live_at_end,
+ || ! bitmap_bit_p (ENTRY_BLOCK_PTR->il.rtl->global_live_at_end,
ORIGINAL_REGNO (in))))
{
unsigned int regno = REGNO (in) + in_offset;
if (! frame_pointer_needed)
FOR_EACH_BB (bb)
- CLEAR_REGNO_REG_SET (bb->global_live_at_start,
+ CLEAR_REGNO_REG_SET (bb->il.rtl->global_live_at_start,
HARD_FRAME_POINTER_REGNUM);
/* Come here (with failure set nonzero) if we can't get enough spill
TARGET. Otherwise, we must assume everything is live. */
if (b != -1)
{
- regset regs_live = BASIC_BLOCK (b)->global_live_at_start;
+ regset regs_live = BASIC_BLOCK (b)->il.rtl->global_live_at_start;
unsigned int j;
unsigned int regno;
rtx start_insn, stop_insn;
it may guard the fallthrough block from using a value that has
conditionally overwritten that of the main codepath. So we
consider that it restores the value of the main codepath. */
- bitmap_and (set, e->dest->global_live_at_start, cond_set);
+ bitmap_and (set, e->dest->il.rtl->global_live_at_start, cond_set);
else
- bitmap_ior_into (used, e->dest->global_live_at_start);
+ bitmap_ior_into (used, e->dest->il.rtl->global_live_at_start);
}
/* Used in schedule_insns to initialize current_sched_info for scheduling
{
basic_block b = candidate_table[src].split_bbs.first_member[i];
- if (REGNO_REG_SET_P (b->global_live_at_start, regno + j))
+ if (REGNO_REG_SET_P (b->il.rtl->global_live_at_start,
+ regno + j))
{
return 0;
}
{
basic_block b = candidate_table[src].split_bbs.first_member[i];
- if (REGNO_REG_SET_P (b->global_live_at_start, regno))
+ if (REGNO_REG_SET_P (b->il.rtl->global_live_at_start, regno))
{
return 0;
}
{
basic_block b = candidate_table[src].update_bbs.first_member[i];
- SET_REGNO_REG_SET (b->global_live_at_start, regno + j);
+ SET_REGNO_REG_SET (b->il.rtl->global_live_at_start,
+ regno + j);
}
}
}
{
basic_block b = candidate_table[src].update_bbs.first_member[i];
- SET_REGNO_REG_SET (b->global_live_at_start, regno);
+ SET_REGNO_REG_SET (b->il.rtl->global_live_at_start, regno);
}
}
}