diff options
author | Jan Hubicka <jh@suse.cz> | 2003-03-25 20:20:34 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2003-03-25 19:20:34 +0000 |
commit | cb9a1d9bb63b68d604dde99a916e48eb5171dd7e (patch) | |
tree | 0e69de262d22541befef3a9f7c91b5a102b2a66c /gcc/cfglayout.c | |
parent | dcb0eee2a208c8283d8ae7dc59747664b33efcce (diff) | |
download | gcc-cb9a1d9bb63b68d604dde99a916e48eb5171dd7e.zip gcc-cb9a1d9bb63b68d604dde99a916e48eb5171dd7e.tar.gz gcc-cb9a1d9bb63b68d604dde99a916e48eb5171dd7e.tar.bz2 |
re PR rtl-optimization/10056 ([HP-PA] ICE at -O2 when building c++ code from doxygen)
PR opt/10056
* cfglayout.c (fixup_reorder_chain): Fix dealing with the conditional
jump jumping to the next instruction.
* cfgrtl.c (force_nonfallthru_and_redirect): Likewise.
From-SVN: r64854
Diffstat (limited to 'gcc/cfglayout.c')
-rw-r--r-- | gcc/cfglayout.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c index 1f4f8fc..c95ac38 100644 --- a/gcc/cfglayout.c +++ b/gcc/cfglayout.c @@ -465,11 +465,43 @@ fixup_reorder_chain () && e_fall->dest == EXIT_BLOCK_PTR)) continue; + /* The degenerated case of conditional jump jumping to the next + instruction can happen on target having jumps with side + effects. + + Create temporarily the duplicated edge representing branch. + It will get unidentified by force_nonfallthru_and_redirect + that would otherwise get confused by fallthru edge not pointing + to the next basic block. */ + if (!e_taken) + { + rtx note; + edge e_fake; + + e_fake = unchecked_make_edge (bb, e_fall->dest, 0); + + if (!redirect_jump (bb->end, block_label (bb), 0)) + abort (); + note = find_reg_note (bb->end, REG_BR_PROB, NULL_RTX); + if (note) + { + int prob = INTVAL (XEXP (note, 0)); + + e_fake->probability = prob; + e_fake->count = e_fall->count * prob / REG_BR_PROB_BASE; + e_fall->probability -= e_fall->probability; + e_fall->count -= e_fake->count; + if (e_fall->probability < 0) + e_fall->probability = 0; + if (e_fall->count < 0) + e_fall->count = 0; + } + } /* There is one special case: if *neither* block is next, such as happens at the very end of a function, then we'll need to add a new unconditional jump. Choose the taken edge based on known or assumed probability. */ - if (RBI (bb)->next != e_taken->dest) + else if (RBI (bb)->next != e_taken->dest) { rtx note = find_reg_note (bb_end_insn, REG_BR_PROB, 0); |