static int label_tick;
-/* Reset to label_tick for each label. */
+/* Reset to label_tick for each extended basic block in scanning order. */
static int label_tick_ebb_start;
if (INSN_P (insn))
free_INSN_LIST_list (&LOG_LINKS (insn));
}
-
-
-
\f
/* Main entry point for combiner. F is the first insn of the function.
NREGS is the first unused pseudo-reg number.
#endif
rtx links, nextlinks;
rtx first;
+ basic_block last_bb;
int new_direct_jump_p = 0;
problems when, for example, we have j <<= 1 in a loop. */
nonzero_sign_valid = 0;
+ label_tick = label_tick_ebb_start = 1;
/* Scan all SETs and see if we can deduce anything about what
bits are known to be zero for some registers and how many copies
for what bits are known to be set. */
setup_incoming_promotions (first);
+ /* Allow the entry block and the first block to fall into the same EBB.
+ Conceptually the incoming promotions are assigned to the entry block. */
+ last_bb = ENTRY_BLOCK_PTR;
create_log_links ();
- label_tick_ebb_start = ENTRY_BLOCK_PTR->index;
FOR_EACH_BB (this_basic_block)
{
optimize_this_for_speed_p = optimize_bb_for_speed_p (this_basic_block);
last_call_luid = 0;
mem_last_set = -1;
- label_tick = this_basic_block->index;
+
+ label_tick++;
if (!single_pred_p (this_basic_block)
- || single_pred (this_basic_block)->index != label_tick - 1)
+ || single_pred (this_basic_block) != last_bb)
label_tick_ebb_start = label_tick;
+ last_bb = this_basic_block;
+
FOR_BB_INSNS (this_basic_block, insn)
if (INSN_P (insn) && BLOCK_FOR_INSN (insn))
{
nonzero_sign_valid = 1;
/* Now scan all the insns in forward order. */
-
- label_tick_ebb_start = ENTRY_BLOCK_PTR->index;
+ label_tick = label_tick_ebb_start = 1;
init_reg_last ();
setup_incoming_promotions (first);
+ last_bb = ENTRY_BLOCK_PTR;
FOR_EACH_BB (this_basic_block)
{
optimize_this_for_speed_p = optimize_bb_for_speed_p (this_basic_block);
last_call_luid = 0;
mem_last_set = -1;
- label_tick = this_basic_block->index;
+
+ label_tick++;
if (!single_pred_p (this_basic_block)
- || single_pred (this_basic_block)->index != label_tick - 1)
+ || single_pred (this_basic_block) != last_bb)
label_tick_ebb_start = label_tick;
+ last_bb = this_basic_block;
+
rtl_profile_for_bb (this_basic_block);
for (insn = BB_HEAD (this_basic_block);
insn != NEXT_INSN (BB_END (this_basic_block));
return x;
}
-#endif
/* Auxiliary data structure for propagate_for_debug_stmt. */
struct rtx_subst_pair
{
- rtx from, to;
- bool changed;
-#ifdef AUTO_INC_DEC
+ rtx to;
bool adjusted;
bool after;
-#endif
};
-/* Clean up any auto-updates in PAIR->to the first time it is called
- for a PAIR. PAIR->adjusted is used to tell whether we've cleaned
- up before. */
+/* DATA points to an rtx_subst_pair. Return the value that should be
+ substituted. */
-static void
-auto_adjust_pair (struct rtx_subst_pair *pair ATTRIBUTE_UNUSED)
+static rtx
+propagate_for_debug_subst (rtx from ATTRIBUTE_UNUSED, void *data)
{
-#ifdef AUTO_INC_DEC
+ struct rtx_subst_pair *pair = (struct rtx_subst_pair *)data;
+
if (!pair->adjusted)
{
pair->adjusted = true;
pair->to = cleanup_auto_inc_dec (pair->to, pair->after, VOIDmode);
+ return pair->to;
}
-#endif
-}
-
-/* If *LOC is the same as FROM in the struct rtx_subst_pair passed as
- DATA, replace it with a copy of TO. Handle SUBREGs of *LOC as
- well. */
-
-static int
-propagate_for_debug_subst (rtx *loc, void *data)
-{
- struct rtx_subst_pair *pair = (struct rtx_subst_pair *)data;
- rtx from = pair->from, to = pair->to;
- rtx x = *loc, s = x;
-
- if (rtx_equal_p (x, from)
- || (GET_CODE (x) == SUBREG && rtx_equal_p ((s = SUBREG_REG (x)), from)))
- {
- auto_adjust_pair (pair);
- if (pair->to != to)
- to = pair->to;
- else
- to = copy_rtx (to);
- if (s != x)
- {
- gcc_assert (GET_CODE (x) == SUBREG && SUBREG_REG (x) == s);
- to = simplify_gen_subreg (GET_MODE (x), to,
- GET_MODE (from), SUBREG_BYTE (x));
- }
- *loc = wrap_constant (GET_MODE (x), to);
- pair->changed = true;
- return -1;
- }
-
- return 0;
+ return copy_rtx (pair->to);
}
+#endif
/* Replace occurrences of DEST with SRC in DEBUG_INSNs between INSN
and LAST. If MOVE holds, debug insns must also be moved past
static void
propagate_for_debug (rtx insn, rtx last, rtx dest, rtx src, bool move)
{
- struct rtx_subst_pair p;
- rtx next, move_pos = move ? last : NULL_RTX;
-
- p.from = dest;
- p.to = src;
- p.changed = false;
+ rtx next, move_pos = move ? last : NULL_RTX, loc;
#ifdef AUTO_INC_DEC
+ struct rtx_subst_pair p;
+ p.to = src;
p.adjusted = false;
p.after = move;
#endif
next = NEXT_INSN (insn);
if (DEBUG_INSN_P (insn))
{
- for_each_rtx (&INSN_VAR_LOCATION_LOC (insn),
- propagate_for_debug_subst, &p);
- if (!p.changed)
+#ifdef AUTO_INC_DEC
+ loc = simplify_replace_fn_rtx (INSN_VAR_LOCATION_LOC (insn),
+ dest, propagate_for_debug_subst, &p);
+#else
+ loc = simplify_replace_rtx (INSN_VAR_LOCATION_LOC (insn), dest, src);
+#endif
+ if (loc == INSN_VAR_LOCATION_LOC (insn))
continue;
- p.changed = false;
+ INSN_VAR_LOCATION_LOC (insn) = loc;
if (move_pos)
{
remove_insn (insn);
if (GET_CODE (XEXP (x, 0)) == CONST
|| GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
{
+ enum machine_mode address_mode
+ = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x));
+
SUBST (XEXP (x, 0),
- gen_rtx_LO_SUM (Pmode,
- gen_rtx_HIGH (Pmode, XEXP (x, 0)),
+ gen_rtx_LO_SUM (address_mode,
+ gen_rtx_HIGH (address_mode, XEXP (x, 0)),
XEXP (x, 0)));
return &XEXP (XEXP (x, 0), 0);
}
it will not remain in the result. */
if (GET_CODE (XEXP (x, 0)) == PLUS
&& CONST_INT_P (XEXP (XEXP (x, 0), 1))
- && ! memory_address_p (GET_MODE (x), XEXP (x, 0)))
+ && ! memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
+ MEM_ADDR_SPACE (x)))
{
rtx reg = regno_reg_rtx[FIRST_PSEUDO_REGISTER];
rtx seq = combine_split_insns (gen_rtx_SET (VOIDmode, reg,
&& NONJUMP_INSN_P (NEXT_INSN (seq))
&& GET_CODE (PATTERN (NEXT_INSN (seq))) == SET
&& SET_DEST (PATTERN (NEXT_INSN (seq))) == reg
- && memory_address_p (GET_MODE (x),
- SET_SRC (PATTERN (NEXT_INSN (seq)))))
+ && memory_address_addr_space_p
+ (GET_MODE (x), SET_SRC (PATTERN (NEXT_INSN (seq))),
+ MEM_ADDR_SPACE (x)))
{
rtx src1 = SET_SRC (PATTERN (seq));
rtx src2 = SET_SRC (PATTERN (NEXT_INSN (seq)));
/* If we have a PLUS whose first operand is complex, try computing it
separately by making a split there. */
if (GET_CODE (XEXP (x, 0)) == PLUS
- && ! memory_address_p (GET_MODE (x), XEXP (x, 0))
+ && ! memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
+ MEM_ADDR_SPACE (x))
&& ! OBJECT_P (XEXP (XEXP (x, 0), 0))
&& ! (GET_CODE (XEXP (XEXP (x, 0), 0)) == SUBREG
&& OBJECT_P (SUBREG_REG (XEXP (XEXP (x, 0), 0)))))