diff options
author | John Wehle <john@feith.com> | 2001-07-26 18:06:45 +0000 |
---|---|---|
committer | John Wehle <wehle@gcc.gnu.org> | 2001-07-26 18:06:45 +0000 |
commit | 11f68165164dc7cc245fd991c98eb87967852520 (patch) | |
tree | 32515011bfca44af926d53cd7f3eacfbe9d182ec | |
parent | 62c62a4fde6dc009d30adcea0bc36aaa655c9f6b (diff) | |
download | gcc-11f68165164dc7cc245fd991c98eb87967852520.zip gcc-11f68165164dc7cc245fd991c98eb87967852520.tar.gz gcc-11f68165164dc7cc245fd991c98eb87967852520.tar.bz2 |
basic-block.h (PROP_ALLOW_CFG_CHANGES): Define.
* basic-block.h (PROP_ALLOW_CFG_CHANGES): Define.
(PROP_FINAL): Include PROP_ALLOW_CFG_CHANGES.
(propagate_block): Update prototype.
* flow.c (update_life_info): Simplify the CFG and
recalculate the global regs which are alive when
removing dead code during a global update.
(propagate_block): Return non-zero if an INSN is
deleted.
From-SVN: r44403
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/basic-block.h | 8 | ||||
-rw-r--r-- | gcc/flow.c | 49 |
3 files changed, 61 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7d5ee37..fdb554a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +Thu Jul 26 14:04:03 EDT 2001 John Wehle (john@feith.com) + + * basic-block.h (PROP_ALLOW_CFG_CHANGES): Define. + (PROP_FINAL): Include PROP_ALLOW_CFG_CHANGES. + (propagate_block): Update prototype. + * flow.c (update_life_info): Simplify the CFG and + recalculate the global regs which are alive when + removing dead code during a global update. + (propagate_block): Return non-zero if an INSN is + deleted. + 2001-07-26 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> * Makefile.in (LIBICONV): Define. diff --git a/gcc/basic-block.h b/gcc/basic-block.h index c069ad5..654e63a 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -533,8 +533,10 @@ enum update_life_extent #define PROP_REG_INFO 4 /* Update regs_ever_live et al. */ #define PROP_KILL_DEAD_CODE 8 /* Remove dead code. */ #define PROP_SCAN_DEAD_CODE 16 /* Scan for dead code. */ -#define PROP_AUTOINC 32 /* Create autoinc mem references. */ -#define PROP_FINAL 63 /* All of the above. */ +#define PROP_ALLOW_CFG_CHANGES 32 /* Allow the CFG to be changed + by dead code removal. */ +#define PROP_AUTOINC 64 /* Create autoinc mem references. */ +#define PROP_FINAL 127 /* All of the above. */ #define CLEANUP_EXPENSIVE 1 /* Do relativly expensive optimizations except for edge forwarding */ @@ -557,7 +559,7 @@ extern void life_analysis PARAMS ((rtx, FILE *, int)); extern void update_life_info PARAMS ((sbitmap, enum update_life_extent, int)); extern int count_or_remove_death_notes PARAMS ((sbitmap, int)); -extern void propagate_block PARAMS ((basic_block, regset, regset, regset, +extern int propagate_block PARAMS ((basic_block, regset, regset, regset, int)); struct propagate_block_info; @@ -4209,11 +4209,45 @@ update_life_info (blocks, extent, prop_flags) tmp = INITIALIZE_REG_SET (tmp_head); + /* Changes to the CFG are only allowed when + doing a global update for the entire CFG. */ + if ((prop_flags & PROP_ALLOW_CFG_CHANGES) + && (extent == UPDATE_LIFE_LOCAL || blocks)) + abort (); + /* For a global update, we go through the relaxation process again. */ if (extent != UPDATE_LIFE_LOCAL) { - calculate_global_regs_live (blocks, blocks, - prop_flags & PROP_SCAN_DEAD_CODE); + for ( ; ; ) + { + int changed = 0; + + calculate_global_regs_live (blocks, blocks, + prop_flags & (PROP_SCAN_DEAD_CODE + | PROP_ALLOW_CFG_CHANGES)); + + if ((prop_flags & (PROP_KILL_DEAD_CODE | PROP_ALLOW_CFG_CHANGES)) + != (PROP_KILL_DEAD_CODE | PROP_ALLOW_CFG_CHANGES)) + break; + + /* Removing dead code may allow the CFG to be simplified which + in turn may allow for further dead code detection / removal. */ + for (i = n_basic_blocks - 1; i >= 0; --i) + { + basic_block bb = BASIC_BLOCK (i); + + COPY_REG_SET (tmp, bb->global_live_at_end); + changed |= propagate_block (bb, tmp, NULL, NULL, + prop_flags & (PROP_SCAN_DEAD_CODE + | PROP_KILL_DEAD_CODE)); + } + + if (! changed || ! try_optimize_cfg (CLEANUP_EXPENSIVE)) + break; + + delete_unreachable_blocks (); + mark_critical_edges (); + } /* If asked, remove notes from the blocks we'll update. */ if (extent == UPDATE_LIFE_GLOBAL_RM_NOTES) @@ -5365,9 +5399,11 @@ free_propagate_block_info (pbi) and cleared in COND_LOCAL_SET. It is valid for LOCAL_SET and COND_LOCAL_SET to be the same set. In this case, the resulting set will be equal to the union of the two sets that - would otherwise be computed. */ + would otherwise be computed. -void + Return non-zero if an INSN is deleted (i.e. by dead code removal). */ + +int propagate_block (bb, live, local_set, cond_local_set, flags) basic_block bb; regset live; @@ -5377,6 +5413,7 @@ propagate_block (bb, live, local_set, cond_local_set, flags) { struct propagate_block_info *pbi; rtx insn, prev; + int changed; pbi = init_propagate_block_info (bb, live, local_set, cond_local_set, flags); @@ -5392,6 +5429,7 @@ propagate_block (bb, live, local_set, cond_local_set, flags) /* Scan the block an insn at a time from end to beginning. */ + changed = 0; for (insn = bb->end;; insn = prev) { /* If this is a call to `setjmp' et al, warn if any @@ -5402,12 +5440,15 @@ propagate_block (bb, live, local_set, cond_local_set, flags) IOR_REG_SET (regs_live_at_setjmp, pbi->reg_live); prev = propagate_one_insn (pbi, insn); + changed |= NEXT_INSN (prev) != insn; if (insn == bb->head) break; } free_propagate_block_info (pbi); + + return changed; } /* Return 1 if X (the body of an insn, or part of it) is just dead stores |