From: John Wehle Date: Thu, 26 Jul 2001 18:06:45 +0000 (+0000) Subject: basic-block.h (PROP_ALLOW_CFG_CHANGES): Define. X-Git-Tag: prereleases/libstdc++-3.0.95~3023 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=11f68165164dc7cc245fd991c98eb87967852520;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7d5ee3741a3b..fdb554afb870 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 * Makefile.in (LIBICONV): Define. diff --git a/gcc/basic-block.h b/gcc/basic-block.h index c069ad57edd5..654e63a94789 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; diff --git a/gcc/flow.c b/gcc/flow.c index 529eb00ddf03..cd33decb7cfc 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -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