From e68e310815a8ef2fa1e9ac966aeabbe0fd9c81cf Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Fri, 8 Jun 2001 21:54:11 +0000 Subject: [PATCH] basic-block.h: Improve comments. * basic-block.h: Improve comments. * except.c (expand_eh_region_end_allowed): Remove redundant call to do_pending_stack_adjust. * flow.c (life_analysis): Fix typo in comment. (calculate_global_regs_live): Add documentation. (mark_set_1): Likewise. (debug_regset): Likewise. * doc/rtl.texi (cond_exec): Document it. From-SVN: r43049 --- gcc/ChangeLog | 11 +++++++++++ gcc/basic-block.h | 32 +++++++++++++++++++++++++++----- gcc/doc/rtl.texi | 9 ++++++++- gcc/except.c | 4 ---- gcc/flow.c | 32 +++++++++++++++++++++++++++++--- 5 files changed, 75 insertions(+), 13 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9c9c387781a..e6f8e986f64 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2001-06-08 Mark Mitchell + + * basic-block.h: Improve comments. + * except.c (expand_eh_region_end_allowed): Remove redundant call + to do_pending_stack_adjust. + * flow.c (life_analysis): Fix typo in comment. + (calculate_global_regs_live): Add documentation. + (mark_set_1): Likewise. + (debug_regset): Likewise. + * doc/rtl.texi (cond_exec): Document it. + Fri Jun 8 21:52:51 CEST 2001 Jan Hubicka * i386.h (CONST_COSTS): set cost of constants representable in diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 8ffcbce368b..c5e30d96805 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -1,5 +1,5 @@ /* Define control and data flow tables, and regsets. - Copyright (C) 1987, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of GNU CC. @@ -141,7 +141,20 @@ typedef struct edge_def { #define EDGE_COMPLEX (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH) -/* Basic blocks need not start with a label nor end with a jump insn. +/* A basic block is a sequence of instructions with only entry and + only one exit. If any one of the instructions are executed, they + will all be executed, and in sequence from first to last. + + There may be COND_EXEC instructions in the basic block. The + COND_EXEC *instructions* will be executed -- but if the condition + is false the conditionally executed *expressions* will of course + not be executed. We don't consider the conditionally executed + expression (which might have side-effects) to be in a separate + basic block because the program counter will always be at the same + location after the COND_EXEC instruction, regardless of whether the + condition is true or not. + + Basic blocks need not start with a label nor end with a jump insn. For example, a previous basic block may just "conditionally fall" into the succeeding basic block, and the last basic block need not end with a jump insn. Block 0 is a descendant of the entry block. @@ -161,12 +174,21 @@ typedef struct basic_block_def { /* The edges into and out of the block. */ edge pred, succ; - /* Liveness info. Note that in SSA form, global_live_at_start does - not reflect the use of regs in phi functions, since the liveness - of these regs may depend on which edge was taken into the block. */ + /* Liveness info. */ + + /* The registers that are modified within this in block. */ regset local_set; + /* The registers that are conditionally modified within this block. + In other words, registers that are set only as part of a + COND_EXEC. */ regset cond_local_set; + /* The registers that are live on entry to this block. + + Note that in SSA form, global_live_at_start does not reflect the + use of regs in phi functions, since the liveness of these regs + may depend on which edge was taken into the block. */ regset global_live_at_start; + /* The registers that are live on exit from this block. */ regset global_live_at_end; /* Auxiliary info specific to a pass. */ diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi index 2b393589d9d..e3dd607717e 100644 --- a/gcc/doc/rtl.texi +++ b/gcc/doc/rtl.texi @@ -2201,6 +2201,13 @@ but it is ok then because no further optimization remains to be done. However, the definition of the macro @code{NOTICE_UPDATE_CC}, if any, must deal with such insns if you define any peephole optimizations. +@findex cond_exec +@item (cond_exec [@var{cond} @var{expr}]) +Represents a conditionally executed expression. The @var{expr} is +executed only if the @var{cond} is non-zero. The @var{cond} expression +must not have side-effects, but the @var{expr} may very well have +side-effects. + @findex sequence @item (sequence [@var{insns} @dots{}]) Represents a sequence of insns. Each of the @var{insns} that appears @@ -2685,7 +2692,7 @@ An expression for the side effect performed by this insn. This must be one of the following codes: @code{set}, @code{call}, @code{use}, @code{clobber}, @code{return}, @code{asm_input}, @code{asm_output}, @code{addr_vec}, @code{addr_diff_vec}, @code{trap_if}, @code{unspec}, -@code{unspec_volatile}, @code{parallel}, or @code{sequence}. If it is a @code{parallel}, +@code{unspec_volatile}, @code{parallel}, @code{cond_exec}, or @code{sequence}. If it is a @code{parallel}, each element of the @code{parallel} must be one these codes, except that @code{parallel} expressions cannot be nested and @code{addr_vec} and @code{addr_diff_vec} are not permitted inside a @code{parallel} expression. diff --git a/gcc/except.c b/gcc/except.c index 5ad9071ec59..24e70799de7 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -857,10 +857,6 @@ expand_eh_region_end_allowed (allowed, failure) throws a different exception, that it will be processed by the correct region. */ - /* If there are any pending stack adjustments, we must emit them - before we branch -- otherwise, we won't know how much adjustment - is required later. */ - do_pending_stack_adjust (); around_label = gen_label_rtx (); emit_jump (around_label); diff --git a/gcc/flow.c b/gcc/flow.c index 2567926f257..77783aa9696 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -2859,7 +2859,7 @@ life_analysis (f, file, flags) { rtx insn; - /* Search for any REG_LABEL notes whih reference deleted labels. */ + /* Search for any REG_LABEL notes which reference deleted labels. */ for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) { rtx inote = find_reg_note (insn, REG_LABEL, NULL_RTX); @@ -3385,6 +3385,24 @@ calculate_global_regs_live (blocks_in, blocks_out, flags) if (blocks_out) sbitmap_zero (blocks_out); + /* We work through the queue until there are no more blocks. What + is live at the end of this block is precisely the union of what + is live at the beginning of all its successors. So, we set its + GLOBAL_LIVE_AT_END field based on the GLOBAL_LIVE_AT_START field + for its successors. Then, we compute GLOBAL_LIVE_AT_START for + this block by walking through the instructions in this block in + reverse order and updating as we go. If that changed + GLOBAL_LIVE_AT_START, we add the predecessors of the block to the + queue; they will now need to recalculate GLOBAL_LIVE_AT_END. + + We are guaranteed to terminate, because GLOBAL_LIVE_AT_START + never shrinks. If a register appears in GLOBAL_LIVE_AT_START, it + must either be live at the end of the block, or used within the + block. In the latter case, it will certainly never disappear + from GLOBAL_LIVE_AT_START. In the former case, the register + could go away only if it disappeared from GLOBAL_LIVE_AT_START + for one of the successor blocks. By induction, that cannot + occur. */ while (qhead != qtail) { int rescan, changed; @@ -3396,7 +3414,7 @@ calculate_global_regs_live (blocks_in, blocks_out, flags) qhead = queue; bb->aux = NULL; - /* Begin by propogating live_at_start from the successor blocks. */ + /* Begin by propagating live_at_start from the successor blocks. */ CLEAR_REG_SET (new_live_at_end); for (e = bb->succ; e; e = e->succ_next) { @@ -4609,7 +4627,11 @@ mark_set_regs (pbi, x, insn) } } -/* Process a single SET rtx, X. */ +/* Process a single set, which appears in INSN. REG (which may not + actually be a REG, it may also be a SUBREG, PARALLEL, etc.) is + being set using the CODE (which may be SET, CLOBBER, or COND_EXEC). + If the set is conditional (because it appear in a COND_EXEC), COND + will be the condition. */ static void mark_set_1 (pbi, code, reg, cond, insn, flags) @@ -6258,6 +6280,10 @@ dump_regset (r, outf) }); } +/* Print a human-reaable representation of R on the standard error + stream. This function is designed to be used from within the + debugger. */ + void debug_regset (r) regset r; -- 2.30.2