#include "toplev.h"
#include "recog.h"
#include "expr.h"
-#include "ssa.h"
#include "timevar.h"
#include "obstack.h"
static void notice_stack_pointer_modification (rtx);
static void mark_reg (rtx, void *);
static void mark_regs_live_at_end (regset);
-static int set_phi_alternative_reg (rtx, int, int, void *);
static void calculate_global_regs_live (sbitmap, sbitmap, int);
static void propagate_block_delete_insn (rtx);
static rtx propagate_block_delete_libcall (rtx, rtx);
generates subregs of a multi-word pseudo, current life analysis will
lose the kill. So we _can_ have a pseudo go live. How irritating.
+ It is also not true when a peephole decides that it doesn't need one
+ or more of the inputs.
+
Including PROP_REG_INFO does not properly refresh regs_ever_live
unless the caller resets it to zero. */
diddle_return_value (mark_reg, set);
}
-/* Callback function for for_each_successor_phi. DATA is a regset.
- Sets the SRC_REGNO, the regno of the phi alternative for phi node
- INSN, in the regset. */
-
-static int
-set_phi_alternative_reg (rtx insn ATTRIBUTE_UNUSED,
- int dest_regno ATTRIBUTE_UNUSED, int src_regno,
- void *data)
-{
- regset live = (regset) data;
- SET_REGNO_REG_SET (live, src_regno);
- return 0;
-}
-
/* Propagate global life info around the graph of basic blocks. Begin
considering blocks with their corresponding bit set in BLOCKS_IN.
If BLOCKS_IN is null, consider it the universal set.
SET_REGNO_REG_SET (new_live_at_end, PIC_OFFSET_TABLE_REGNUM);
}
- /* Regs used in phi nodes are not included in
- global_live_at_start, since they are live only along a
- particular edge. Set those regs that are live because of a
- phi node alternative corresponding to this particular block. */
- if (in_ssa_form)
- for_each_successor_phi (bb, &set_phi_alternative_reg,
- new_live_at_end);
-
if (bb == ENTRY_BLOCK_PTR)
{
COPY_REG_SET (bb->global_live_at_end, new_live_at_end);
free_reg_cond_life_info);
pbi->reg_cond_reg = BITMAP_XMALLOC ();
- /* If this block ends in a conditional branch, for each register live
- from one side of the branch and not the other, record the register
- as conditionally dead. */
+ /* If this block ends in a conditional branch, for each register
+ live from one side of the branch and not the other, record the
+ register as conditionally dead. */
if (GET_CODE (bb->end) == JUMP_INSN
&& any_condjump_p (bb->end))
{
regset_head diff_head;
regset diff = INITIALIZE_REG_SET (diff_head);
basic_block bb_true, bb_false;
- rtx cond_true, cond_false, set_src;
int i;
/* Identify the successor blocks. */
bb_false = bb_true;
}
- /* Extract the condition from the branch. */
- set_src = SET_SRC (pc_set (bb->end));
- cond_true = XEXP (set_src, 0);
- cond_false = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond_true)),
- GET_MODE (cond_true), XEXP (cond_true, 0),
- XEXP (cond_true, 1));
- if (GET_CODE (XEXP (set_src, 1)) == PC)
- {
- rtx t = cond_false;
- cond_false = cond_true;
- cond_true = t;
- }
-
/* Compute which register lead different lives in the successors. */
if (bitmap_operation (diff, bb_true->global_live_at_start,
bb_false->global_live_at_start, BITMAP_XOR))
{
+ /* Extract the condition from the branch. */
+ rtx set_src = SET_SRC (pc_set (bb->end));
+ rtx cond_true = XEXP (set_src, 0);
rtx reg = XEXP (cond_true, 0);
if (GET_CODE (reg) == SUBREG)
reg = SUBREG_REG (reg);
- if (GET_CODE (reg) != REG)
- abort ();
+ /* We can only track conditional lifetimes if the condition is
+ in the form of a comparison of a register against zero.
+ If the condition is more complex than that, then it is safe
+ not to record any information. */
+ if (GET_CODE (reg) == REG
+ && XEXP (cond_true, 1) == const0_rtx)
+ {
+ rtx cond_false
+ = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond_true)),
+ GET_MODE (cond_true), XEXP (cond_true, 0),
+ XEXP (cond_true, 1));
+ if (GET_CODE (XEXP (set_src, 1)) == PC)
+ {
+ rtx t = cond_false;
+ cond_false = cond_true;
+ cond_true = t;
+ }
- SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (reg));
+ SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (reg));
- /* For each such register, mark it conditionally dead. */
- EXECUTE_IF_SET_IN_REG_SET
- (diff, 0, i,
- {
- struct reg_cond_life_info *rcli;
- rtx cond;
+ /* For each such register, mark it conditionally dead. */
+ EXECUTE_IF_SET_IN_REG_SET
+ (diff, 0, i,
+ {
+ struct reg_cond_life_info *rcli;
+ rtx cond;
- rcli = xmalloc (sizeof (*rcli));
+ rcli = xmalloc (sizeof (*rcli));
- if (REGNO_REG_SET_P (bb_true->global_live_at_start, i))
- cond = cond_false;
- else
- cond = cond_true;
- rcli->condition = cond;
- rcli->stores = const0_rtx;
- rcli->orig_condition = cond;
+ if (REGNO_REG_SET_P (bb_true->global_live_at_start, i))
+ cond = cond_false;
+ else
+ cond = cond_true;
+ rcli->condition = cond;
+ rcli->stores = const0_rtx;
+ rcli->orig_condition = cond;
- splay_tree_insert (pbi->reg_cond_dead, i,
- (splay_tree_value) rcli);
- });
+ splay_tree_insert (pbi->reg_cond_dead, i,
+ (splay_tree_value) rcli);
+ });
+ }
}
FREE_REG_SET (diff);
x = COND_EXEC_CODE (x);
goto retry;
- case PHI:
- /* We _do_not_ want to scan operands of phi nodes. Operands of
- a phi function are evaluated only when control reaches this
- block along a particular edge. Therefore, regs that appear
- as arguments to phi should not be added to the global live at
- start. */
- return;
-
default:
break;
}