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