+Sun Oct 10 16:14:16 1999 Richard Henderson <rth@cygnus.com>
+
+ * combine.c (refresh_blocks, need_refresh): New.
+ (combine_instructions): Allocate refresh_blocks. Invoke
+ update_life_info if needed.
+ (distribute_notes): Mark refresh_blocks instead of installing
+ USE insns.
+ * flow.c (update_life_info): Remove notes if GLOBAL_RM_NOTES.
+ * basic_block.h (enum update_life_extent): Add GLOBAL_RM_NOTES.
+
+ * Makefile.in (recog.o): Depend on basic-block.h.
+
Sun Oct 10 12:03:21 1999 Richard Henderson <rth@cygnus.com>
* genrecog.c (add_to_sequence): Thinko last change: delete
dbxout.h
recog.o : recog.c $(CONFIG_H) system.h $(RTL_H) function.h \
$(REGS_H) $(RECOG_H) hard-reg-set.h flags.h insn-config.h insn-attr.h \
- insn-flags.h insn-codes.h real.h toplev.h output.h resource.h
+ insn-flags.h insn-codes.h real.h toplev.h output.h resource.h basic-block.h
reg-stack.o : reg-stack.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) recog.h \
$(REGS_H) hard-reg-set.h flags.h insn-config.h insn-flags.h toplev.h \
varray.h function.h
enum update_life_extent
{
- UPDATE_LIFE_GLOBAL = 0,
- UPDATE_LIFE_LOCAL = 1
+ UPDATE_LIFE_LOCAL = 0,
+ UPDATE_LIFE_GLOBAL = 1,
+ UPDATE_LIFE_GLOBAL_RM_NOTES = 2,
};
extern void update_life_info PROTO ((sbitmap, enum update_life_extent));
/* Basic block number of the block in which we are performing combines. */
static int this_basic_block;
+
+/* A bitmap indicating which blocks had registers go dead at entry.
+ After combine, we'll need to re-do global life analysis with
+ those blocks as starting points. */
+static sbitmap refresh_blocks;
+static int need_refresh;
\f
/* The next group of arrays allows the recording of the last value assigned
to (hard or pseudo) register n. We use this information to see if a
setup_incoming_promotions ();
+ refresh_blocks = sbitmap_alloc (n_basic_blocks);
+ sbitmap_zero (refresh_blocks);
+ need_refresh = 0;
+
for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
{
uid_cuid[INSN_UID (insn)] = ++i;
}
}
+ if (need_refresh)
+ update_life_info (refresh_blocks, UPDATE_LIFE_GLOBAL_RM_NOTES);
+ sbitmap_free (refresh_blocks);
+
total_attempts += combine_attempts;
total_merges += combine_merges;
total_extras += combine_extras;
/* We haven't found an insn for the death note and it
is still a REG_DEAD note, but we have hit the beginning
of the block. If the existing life info says the reg
- was dead, there's nothing left to do.
-
- ??? If the register was live, we ought to mark for later
- global life update. Cop out like the previous code and
- just add a hook for the death note to live on. */
+ 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)
{
int regno = REGNO (XEXP (note, 0));
-
if (REGNO_REG_SET_P (bb->global_live_at_start, regno))
{
- rtx die = gen_rtx_USE (VOIDmode, XEXP (note, 0));
-
- place = bb->head;
- if (GET_CODE (place) != CODE_LABEL
- && GET_CODE (place) != NOTE)
- {
- place = emit_insn_before (die, place);
- bb->head = place;
- }
- else
- {
- place = emit_insn_after (die, place);
- }
+ SET_BIT (refresh_blocks, this_basic_block);
+ need_refresh = 1;
}
}
}
lose the kill. So we _can_ have a pseudo go live. How irritating. */
void
-update_life_info (blocks, local_only)
+update_life_info (blocks, extent)
sbitmap blocks;
- enum update_life_extent local_only;
+ enum update_life_extent extent;
{
regset tmp;
int i;
tmp = ALLOCA_REG_SET ();
/* For a global update, we go through the relaxation process again. */
- if (! local_only)
- calculate_global_regs_live (blocks, blocks, 0);
+ if (extent != UPDATE_LIFE_LOCAL)
+ {
+ calculate_global_regs_live (blocks, blocks, 0);
+
+ /* If asked, remove notes from the blocks we'll update. */
+ if (extent == UPDATE_LIFE_GLOBAL_RM_NOTES)
+ count_or_remove_death_notes (blocks, 1);
+ }
EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
{
propagate_block (tmp, bb->head, bb->end, (regset) NULL, i,
PROP_DEATH_NOTES);
- if (local_only)
+ if (extent == UPDATE_LIFE_LOCAL)
verify_local_live_at_start (tmp, bb);
CLEAN_ALLOCA;