do \
{ \
unsigned int node_; \
- EXECUTE_IF_SET_IN_BITMAP (BITMAP, MIN, node_, \
- {(BB) = BASIC_BLOCK (node_); CODE;}); \
+ bitmap_iterator bi; \
+ EXECUTE_IF_SET_IN_BITMAP (BITMAP, MIN, node_, bi) \
+ { \
+ (BB) = BASIC_BLOCK (node_); \
+ CODE; \
+ } \
} \
while (0)
static void df_du_chain_create (struct df *, bitmap);
static void df_bb_ud_chain_create (struct df *, basic_block);
static void df_ud_chain_create (struct df *, bitmap);
-static void df_bb_rd_local_compute (struct df *, basic_block);
+static void df_bb_rd_local_compute (struct df *, basic_block, bitmap);
static void df_rd_local_compute (struct df *, bitmap);
static void df_bb_ru_local_compute (struct df *, basic_block);
static void df_ru_local_compute (struct df *, bitmap);
use = gen_rtx_USE (GET_MODE (reg), reg);
return use;
}
-
-
-/* Return a CLOBBER for register REGNO. */
-static rtx df_reg_clobber_gen (unsigned int regno)
-{
- rtx reg;
- rtx use;
-
- reg = regno_reg_rtx[regno];
-
- use = gen_rtx_CLOBBER (GET_MODE (reg), reg);
- return use;
-}
\f
/* Local chain manipulation routines. */
/* Only a single ref. It must be the one we want.
If not, the def-use and use-def chains are likely to
be inconsistent. */
- if (link->ref != ref)
- abort ();
+ gcc_assert (link->ref == ref);
+
/* Now have an empty chain. */
*phead = NULL;
}
{
unsigned int regno;
- if (GET_CODE (reg) != REG && GET_CODE (reg) != SUBREG)
- abort ();
+ gcc_assert (REG_P (reg) || GET_CODE (reg) == SUBREG);
/* For the reg allocator we are interested in some SUBREG rtx's, but not
all. Notably only those representing a word extraction from a multi-word
flags |= DF_REF_READ_WRITE;
}
- if (GET_CODE (dst) == REG
- || (GET_CODE (dst) == SUBREG && GET_CODE (SUBREG_REG (dst)) == REG))
+ if (REG_P (dst)
+ || (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst))))
df_ref_record (df, dst, loc, insn, DF_REF_REG_DEF, flags);
}
case CLOBBER:
/* If we are clobbering a MEM, mark any registers inside the address
as being used. */
- if (GET_CODE (XEXP (x, 0)) == MEM)
+ if (MEM_P (XEXP (x, 0)))
df_uses_record (df, &XEXP (XEXP (x, 0), 0),
DF_REF_REG_MEM_STORE, bb, insn, flags);
/* While we're here, optimize this case. */
/* In case the SUBREG is not of a REG, do not optimize. */
- if (GET_CODE (SUBREG_REG (x)) != REG)
+ if (!REG_P (SUBREG_REG (x)))
{
loc = &SUBREG_REG (x);
df_uses_record (df, loc, ref_type, bb, insn, flags);
bb, insn, 0);
break;
case STRICT_LOW_PART:
- /* A strict_low_part uses the whole REG and not just the SUBREG. */
+ /* A strict_low_part uses the whole REG and not just the
+ SUBREG. */
dst = XEXP (dst, 0);
- if (GET_CODE (dst) != SUBREG)
- abort ();
+ gcc_assert (GET_CODE (dst) == SUBREG);
df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb,
insn, DF_REF_READ_WRITE);
break;
dst = XEXP (dst, 0);
break;
default:
- abort ();
+ gcc_unreachable ();
}
return;
}
}
}
- if (GET_CODE (insn) == CALL_INSN)
+ if (CALL_P (insn))
{
rtx note;
rtx x;
df_uses_record (df, &PATTERN (insn),
DF_REF_REG_USE, bb, insn, 0);
- if (GET_CODE (insn) == CALL_INSN)
+ if (CALL_P (insn))
{
rtx note;
- if (df->flags & DF_HARD_REGS)
- {
- /* Kill all registers invalidated by a call. */
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
- {
- rtx reg_clob = df_reg_clobber_gen (i);
- df_defs_record (df, reg_clob, bb, insn);
- }
- }
+ /* We do not record hard registers clobbered by the call,
+ since there are awfully many of them and "defs" created
+ through them are not interesting (since no use can be legally
+ reached by them). So we must just make sure we include them when
+ computing kill bitmaps. */
/* There may be extra registers to be clobbered. */
for (note = CALL_INSN_FUNCTION_USAGE (insn);
{
#ifdef ENABLE_CHECKING
for (regno = 0; regno < df->n_regs; regno++)
- if (df->regs[regno].defs)
- abort ();
+ gcc_assert (!df->regs[regno].defs);
#endif
/* Pretend that all defs are new. */
{
#ifdef ENABLE_CHECKING
for (regno = 0; regno < df->n_regs; regno++)
- if (df->regs[regno].uses)
- abort ();
+ gcc_assert (!df->regs[regno].uses);
#endif
/* Pretend that all uses are new. */
/* Compute local reaching def info for basic block BB. */
static void
-df_bb_rd_local_compute (struct df *df, basic_block bb)
+df_bb_rd_local_compute (struct df *df, basic_block bb, bitmap call_killed_defs)
{
struct bb_info *bb_info = DF_BB_INFO (df, bb);
rtx insn;
+ bitmap seen = BITMAP_XMALLOC ();
+ bool call_seen = false;
- for (insn = BB_HEAD (bb); insn && insn != NEXT_INSN (BB_END (bb));
- insn = NEXT_INSN (insn))
+ FOR_BB_INSNS_REVERSE (bb, insn)
{
unsigned int uid = INSN_UID (insn);
struct df_link *def_link;
unsigned int regno = DF_REF_REGNO (def);
struct df_link *def2_link;
+ if (bitmap_bit_p (seen, regno)
+ || (call_seen
+ && regno < FIRST_PSEUDO_REGISTER
+ && TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)))
+ continue;
+
for (def2_link = df->regs[regno].defs; def2_link;
def2_link = def2_link->next)
{
be killed by this BB but it keeps things a lot
simpler. */
bitmap_set_bit (bb_info->rd_kill, DF_REF_ID (def2));
-
- /* Zap from the set of gens for this BB. */
- bitmap_clear_bit (bb_info->rd_gen, DF_REF_ID (def2));
}
bitmap_set_bit (bb_info->rd_gen, DF_REF_ID (def));
+ bitmap_set_bit (seen, regno);
+ }
+
+ if (CALL_P (insn) && (df->flags & DF_HARD_REGS))
+ {
+ bitmap_operation (bb_info->rd_kill, bb_info->rd_kill,
+ call_killed_defs, BITMAP_IOR);
+ call_seen = 1;
}
}
- bb_info->rd_valid = 1;
+ BITMAP_XFREE (seen);
}
df_rd_local_compute (struct df *df, bitmap blocks)
{
basic_block bb;
+ bitmap killed_by_call = NULL;
+ unsigned regno;
+ struct df_link *def_link;
+
+ if (df->flags & DF_HARD_REGS)
+ {
+ killed_by_call = BITMAP_XMALLOC ();
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ {
+ if (!TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
+ continue;
+
+ for (def_link = df->regs[regno].defs;
+ def_link;
+ def_link = def_link->next)
+ bitmap_set_bit (killed_by_call, DF_REF_ID (def_link->ref));
+ }
+ }
FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
{
- df_bb_rd_local_compute (df, bb);
+ df_bb_rd_local_compute (df, bb, killed_by_call);
});
+
+ if (df->flags & DF_HARD_REGS)
+ BITMAP_XFREE (killed_by_call);
}
unsigned int uid = INSN_UID (insn);
unsigned int regno;
struct df_link *link;
+ bitmap_iterator bi;
if (! INSN_P (insn))
continue;
}
/* Increment lifetimes of all live registers. */
- EXECUTE_IF_SET_IN_BITMAP (live, 0, regno,
- {
- reg_info[regno].lifetime++;
- });
+ EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
+ {
+ reg_info[regno].lifetime++;
+ }
}
}
}
else
{
- EXECUTE_IF_AND_IN_BITMAP (df->bbs_modified, blocks, 0, bbno,
+ bitmap_iterator bi;
+
+ EXECUTE_IF_AND_IN_BITMAP (df->bbs_modified, blocks, 0, bbno, bi)
{
count += df_bb_refs_update (df, BASIC_BLOCK (bbno));
- });
+ }
}
df_refs_process (df);
/* We could deal with additional basic blocks being created by
rescanning everything again. */
- if (df->n_bbs && df->n_bbs != (unsigned int) last_basic_block)
- abort ();
+ gcc_assert (!df->n_bbs || df->n_bbs == (unsigned int) last_basic_block);
update = df_modified_p (df, blocks);
if (update || (flags != df->flags))
if (blocks == (bitmap) -1)
blocks = df->bbs_modified;
- if (! df->n_bbs)
- abort ();
+ gcc_assert (df->n_bbs);
df_analyze_1 (df, blocks, flags, 1);
bitmap_zero (df->bbs_modified);
return last;
}
-/* Alternative entry point to the analysis. Analyse just the part of the cfg
+/* Alternative entry point to the analysis. Analyze just the part of the cfg
graph induced by BLOCKS.
TODO I am not quite sure how to avoid code duplication with df_analyze_1
handle the JUMP_LABEL? */
/* We should not be deleting the NOTE_INSN_BASIC_BLOCK or label. */
- if (insn == BB_HEAD (bb))
- abort ();
+ gcc_assert (insn != BB_HEAD (bb));
/* Delete the insn. */
delete_insn (insn);
if (! INSN_P (insn))
continue;
- if (bitmap_bit_p (blocks, DF_REF_BBNO (ref)))
- {
- df_ref_reg_replace (df, ref, oldreg, newreg);
+ gcc_assert (bitmap_bit_p (blocks, DF_REF_BBNO (ref)));
+
+ df_ref_reg_replace (df, ref, oldreg, newreg);
- /* Replace occurrences of the reg within the REG_NOTES. */
- if ((! link->next || DF_REF_INSN (ref)
- != DF_REF_INSN (link->next->ref))
- && REG_NOTES (insn))
- {
- args.insn = insn;
- for_each_rtx (®_NOTES (insn), df_rtx_reg_replace, &args);
- }
- }
- else
+ /* Replace occurrences of the reg within the REG_NOTES. */
+ if ((! link->next || DF_REF_INSN (ref)
+ != DF_REF_INSN (link->next->ref))
+ && REG_NOTES (insn))
{
- /* Temporary check to ensure that we have a grip on which
- regs should be replaced. */
- abort ();
+ args.insn = insn;
+ for_each_rtx (®_NOTES (insn), df_rtx_reg_replace, &args);
}
}
}
if (! INSN_P (DF_REF_INSN (ref)))
return 0;
- if (oldreg && oldreg != DF_REF_REG (ref))
- abort ();
+ gcc_assert (!oldreg || oldreg == DF_REF_REG (ref));
if (! validate_change (DF_REF_INSN (ref), DF_REF_LOC (ref), newreg, 1))
return 0;
/* A non-const call should not have slipped through the net. If
it does, we need to create a new basic block. Ouch. The
same applies for a label. */
- if ((GET_CODE (insn) == CALL_INSN
- && ! CONST_OR_PURE_CALL_P (insn))
- || GET_CODE (insn) == CODE_LABEL)
- abort ();
+ gcc_assert ((!CALL_P (insn) || CONST_OR_PURE_CALL_P (insn))
+ && !LABEL_P (insn));
uid = INSN_UID (insn);
rtx prev_insn = PREV_INSN (insn);
/* We should not be inserting before the start of the block. */
- if (insn == BB_HEAD (bb))
- abort ();
+ gcc_assert (insn != BB_HEAD (bb));
ret_insn = emit_insn_before (pattern, insn);
if (ret_insn == insn)
return ret_insn;
{
struct bb_info *bb_info = DF_BB_INFO (df, bb);
-#ifdef ENABLE_CHECKING
- if (! bb_info->lr_in)
- abort ();
-#endif
+ gcc_assert (bb_info->lr_in);
return bitmap_bit_p (bb_info->lr_in, REGNO (reg));
}
{
struct bb_info *bb_info = DF_BB_INFO (df, bb);
-#ifdef ENABLE_CHECKING
- if (! bb_info->lr_in)
- abort ();
-#endif
+ gcc_assert (bb_info->lr_in);
return bitmap_bit_p (bb_info->lr_out, REGNO (reg));
}
/* The regs must be local to BB. */
- if (df_regno_bb (df, regno1) != bb
- || df_regno_bb (df, regno2) != bb)
- abort ();
+ gcc_assert (df_regno_bb (df, regno1) == bb
+ && df_regno_bb (df, regno2) == bb);
def2 = df_bb_regno_first_def_find (df, bb, regno2);
use1 = df_bb_regno_last_use_find (df, bb, regno1);
def = df_bb_insn_regno_first_def_find (df, bb, insn, REGNO (reg));
- if (! def)
- abort ();
+ gcc_assert (def);
du_link = DF_REF_CHAIN (def);
break;
default:
- abort ();
+ gcc_unreachable ();
}
break;
break;
default:
- abort ();
+ gcc_unreachable ();
}
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
int changed;
int i = bb->index;
edge e;
+ edge_iterator ei;
SET_BIT (visited, bb->index);
- if (!TEST_BIT (pending, bb->index))
- abort ();
+ gcc_assert (TEST_BIT (pending, bb->index));
RESET_BIT (pending, i);
-#define HS(E_ANTI, E_ANTI_NEXT, E_ANTI_BB, E_ANTI_START_BB, IN_SET, \
- E, E_NEXT, E_BB, E_START_BB, OUT_SET) \
+#define HS(E_ANTI, E_ANTI_BB, E_ANTI_START_BB, IN_SET, \
+ E, E_BB, E_START_BB, OUT_SET) \
do \
{ \
/* Calculate <conf_op> of predecessor_outs. */ \
bitmap_zero (IN_SET[i]); \
- for (e = bb->E_ANTI; e; e = e->E_ANTI_NEXT) \
+ FOR_EACH_EDGE (e, ei, bb->E_ANTI) \
{ \
if (e->E_ANTI_BB == E_ANTI_START_BB) \
continue; \
if (!changed) \
break; \
\
- for (e = bb->E; e; e = e->E_NEXT) \
+ FOR_EACH_EDGE (e, ei, bb->E) \
{ \
if (e->E_BB == E_START_BB || e->E_BB->index == i) \
continue; \
SET_BIT (pending, e->E_BB->index); \
} \
\
- for (e = bb->E; e; e = e->E_NEXT) \
+ FOR_EACH_EDGE (e, ei, bb->E) \
{ \
if (e->E_BB == E_START_BB || e->E_BB->index == i) \
continue; \
} while (0)
if (dataflow->dir == DF_FORWARD)
- HS (pred, pred_next, src, ENTRY_BLOCK_PTR, dataflow->in,
- succ, succ_next, dest, EXIT_BLOCK_PTR, dataflow->out);
+ HS (preds, src, ENTRY_BLOCK_PTR, dataflow->in,
+ succs, dest, EXIT_BLOCK_PTR, dataflow->out);
else
- HS (succ, succ_next, dest, EXIT_BLOCK_PTR, dataflow->out,
- pred, pred_next, src, ENTRY_BLOCK_PTR, dataflow->in);
+ HS (succs, dest, EXIT_BLOCK_PTR, dataflow->out,
+ preds, src, ENTRY_BLOCK_PTR, dataflow->in);
}
/* This function will perform iterative bitvector dataflow described by