[Bug #20572] Abandon if replacing destination is the same
This commit is contained in:
parent
278a7cb057
commit
32a555ea53
18
compile.c
18
compile.c
@ -2972,16 +2972,18 @@ unref_destination(INSN *iobj, int pos)
|
||||
if (!lobj->refcnt) ELEM_REMOVE(&lobj->link);
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
replace_destination(INSN *dobj, INSN *nobj)
|
||||
{
|
||||
VALUE n = OPERAND_AT(nobj, 0);
|
||||
LABEL *dl = (LABEL *)OPERAND_AT(dobj, 0);
|
||||
LABEL *nl = (LABEL *)n;
|
||||
if (dl == nl) return false;
|
||||
--dl->refcnt;
|
||||
++nl->refcnt;
|
||||
OPERAND_AT(dobj, 0) = n;
|
||||
if (!dl->refcnt) ELEM_REMOVE(&dl->link);
|
||||
return true;
|
||||
}
|
||||
|
||||
static LABEL*
|
||||
@ -3263,9 +3265,10 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
|
||||
* => in this case, first jump instruction should jump to
|
||||
* LABEL2 directly
|
||||
*/
|
||||
replace_destination(iobj, diobj);
|
||||
remove_unreachable_chunk(iseq, iobj->link.next);
|
||||
goto again;
|
||||
if (replace_destination(iobj, diobj)) {
|
||||
remove_unreachable_chunk(iseq, iobj->link.next);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
else if (IS_INSN_ID(diobj, leave)) {
|
||||
/*
|
||||
@ -3310,8 +3313,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
|
||||
*/
|
||||
piobj->insn_id = (IS_INSN_ID(piobj, branchif))
|
||||
? BIN(branchunless) : BIN(branchif);
|
||||
replace_destination(piobj, iobj);
|
||||
if (refcnt <= 1) {
|
||||
if (replace_destination(piobj, iobj) && refcnt <= 1) {
|
||||
ELEM_REMOVE(&iobj->link);
|
||||
}
|
||||
else {
|
||||
@ -3440,7 +3442,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
|
||||
|
||||
for (;;) {
|
||||
if (IS_INSN(&nobj->link) && IS_INSN_ID(nobj, jump)) {
|
||||
replace_destination(iobj, nobj);
|
||||
if (!replace_destination(iobj, nobj)) break;
|
||||
}
|
||||
else if (prev_dup && IS_INSN_ID(nobj, dup) &&
|
||||
!!(nobj = (INSN *)nobj->link.next) &&
|
||||
@ -3461,7 +3463,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
|
||||
* dup
|
||||
* if L2
|
||||
*/
|
||||
replace_destination(iobj, nobj);
|
||||
if (!replace_destination(iobj, nobj)) break;
|
||||
}
|
||||
else if (pobj) {
|
||||
/*
|
||||
|
@ -871,4 +871,12 @@ class TestISeq < Test::Unit::TestCase
|
||||
RubyVM::InstructionSequence.load_from_binary(var_0)
|
||||
end
|
||||
end
|
||||
|
||||
def test_while_in_until_condition
|
||||
assert_in_out_err(["--dump=i", "-e", "until while 1; end; end"]) do |stdout, stderr, status|
|
||||
assert_include(stdout.shift, "== disasm:")
|
||||
assert_include(stdout.pop, "leave")
|
||||
assert_predicate(status, :success?)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user