From 715e7fbc831af02e80acc60be2fa19208ab62dfc Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 10 Oct 1999 16:34:17 -0700 Subject: [PATCH] combine.c (refresh_blocks, [...]): New. * 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. From-SVN: r29893 --- gcc/ChangeLog | 12 ++++++++++++ gcc/Makefile.in | 2 +- gcc/basic-block.h | 5 +++-- gcc/combine.c | 37 ++++++++++++++++++------------------- gcc/flow.c | 16 +++++++++++----- 5 files changed, 45 insertions(+), 27 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5d61baf..32b6b35 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +Sun Oct 10 16:14:16 1999 Richard Henderson + + * 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 * genrecog.c (add_to_sequence): Thinko last change: delete diff --git a/gcc/Makefile.in b/gcc/Makefile.in index d9d5e1f..fcfa047 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1593,7 +1593,7 @@ final.o : final.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h intl.h \ 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 diff --git a/gcc/basic-block.h b/gcc/basic-block.h index ca63f73..e7c5dfc 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -301,8 +301,9 @@ extern void compute_immediate_dominators PROTO ((int *, sbitmap *)); 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)); diff --git a/gcc/combine.c b/gcc/combine.c index 0e634ae..c63bf39 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -196,6 +196,12 @@ static rtx added_links_insn; /* 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; /* 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 @@ -551,6 +557,10 @@ combine_instructions (f, nregs) 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; @@ -685,6 +695,10 @@ combine_instructions (f, nregs) } } + 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; @@ -11858,30 +11872,15 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) /* 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; } } } diff --git a/gcc/flow.c b/gcc/flow.c index 9418b8b..3619e28 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -2554,9 +2554,9 @@ verify_local_live_at_start (new_live_at_start, bb) 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; @@ -2565,8 +2565,14 @@ update_life_info (blocks, local_only) 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, { @@ -2576,7 +2582,7 @@ update_life_info (blocks, local_only) 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; -- 2.7.4