summaryrefslogtreecommitdiff
path: root/gcc/cfgrtl.c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-13 07:23:51 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-13 07:23:51 +0000
commitca632883aaea123589bc8f37e574a19aa2d452e2 (patch)
treeeda1ced99836a0df02e841aa54853a4b335cfb58 /gcc/cfgrtl.c
parent6336f7380bcbfbf60b6aeb13a982e63f584a8a73 (diff)
downloadgcc-ca632883aaea123589bc8f37e574a19aa2d452e2.tar.gz
PR rtl-optimization/54127
* cfgrtl.c (force_nonfallthru_and_redirect): When redirecting asm goto labels from BB_HEAD (e->dest) to target bb, decrement LABEL_NUSES of BB_HEAD (e->dest) and increment LABEL_NUSES of BB_HEAD (target) appropriately and adjust JUMP_LABEL and/or REG_LABEL_TARGET and REG_LABEL_OPERAND. * gcc.dg/torture/pr54127.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193470 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgrtl.c')
-rw-r--r--gcc/cfgrtl.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 1f601e51d03..8855bdf9861 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -1424,14 +1424,46 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
&& (note = extract_asm_operands (PATTERN (BB_END (e->src)))))
{
int i, n = ASM_OPERANDS_LABEL_LENGTH (note);
+ bool adjust_jump_target = false;
for (i = 0; i < n; ++i)
{
if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (e->dest))
- XEXP (ASM_OPERANDS_LABEL (note, i), 0) = block_label (target);
+ {
+ LABEL_NUSES (XEXP (ASM_OPERANDS_LABEL (note, i), 0))--;
+ XEXP (ASM_OPERANDS_LABEL (note, i), 0) = block_label (target);
+ LABEL_NUSES (XEXP (ASM_OPERANDS_LABEL (note, i), 0))++;
+ adjust_jump_target = true;
+ }
if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (target))
asm_goto_edge = true;
}
+ if (adjust_jump_target)
+ {
+ rtx insn = BB_END (e->src), note;
+ rtx old_label = BB_HEAD (e->dest);
+ rtx new_label = BB_HEAD (target);
+
+ if (JUMP_LABEL (insn) == old_label)
+ {
+ JUMP_LABEL (insn) = new_label;
+ note = find_reg_note (insn, REG_LABEL_TARGET, new_label);
+ if (note)
+ remove_note (insn, note);
+ }
+ else
+ {
+ note = find_reg_note (insn, REG_LABEL_TARGET, old_label);
+ if (note)
+ remove_note (insn, note);
+ if (JUMP_LABEL (insn) != new_label
+ && !find_reg_note (insn, REG_LABEL_TARGET, new_label))
+ add_reg_note (insn, REG_LABEL_TARGET, new_label);
+ }
+ while ((note = find_reg_note (insn, REG_LABEL_OPERAND, old_label))
+ != NULL_RTX)
+ XEXP (note, 0) = new_label;
+ }
}
if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags || asm_goto_edge)