diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-07-06 08:01:58 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-07-06 08:01:58 +0000 |
commit | 5e7167f8fb954ec46eb12a4a0a1191a8f7d9543d (patch) | |
tree | ee282abc39fd8e887ebc4ee19aaa85ecfc57c000 | |
parent | 79f01d3972811e4388a257decea3e47445b42b59 (diff) | |
download | ruby-5e7167f8fb954ec46eb12a4a0a1191a8f7d9543d.tar.gz |
compile.c: remove unreachable jump only
* compile.c (iseq_peephole_optimize): remove unreachable jump
instruction only. if it is labeled and referred from other
instructions, it is reachable and must not be removed.
[ruby-core:87830] [Bug #14897]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63870 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | compile.c | 12 | ||||
-rw-r--r-- | test/ruby/test_optimization.rb | 13 |
2 files changed, 22 insertions, 3 deletions
@@ -2730,12 +2730,13 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal ELEM_INSERT_NEXT(&dniobj->link, &pop->link); goto again; } - else if (IS_INSN(iobj->link.prev) && - (piobj = (INSN *)iobj->link.prev) && + else if ((piobj = (INSN *)get_prev_insn(iobj)) != 0 && (IS_INSN_ID(piobj, branchif) || IS_INSN_ID(piobj, branchunless))) { INSN *pdiobj = (INSN *)get_destination_insn(piobj); if (niobj == pdiobj) { + int refcnt = IS_LABEL(piobj->link.next) ? + ((LABEL *)piobj->link.next)->refcnt : 0; /* * useless jump elimination (if/unless destination): * if L1 @@ -2753,7 +2754,12 @@ 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); - ELEM_REMOVE(&iobj->link); + if (refcnt <= 1) { + ELEM_REMOVE(&iobj->link); + } + else { + /* TODO: replace other branch destinations too */ + } return COMPILE_OK; } else if (diobj == pdiobj) { diff --git a/test/ruby/test_optimization.rb b/test/ruby/test_optimization.rb index 32bdcef13d..d4a1fdbcea 100644 --- a/test/ruby/test_optimization.rb +++ b/test/ruby/test_optimization.rb @@ -771,4 +771,17 @@ class TestRubyOptimization < Test::Unit::TestCase tap {true || tap {}} end; end + + def test_jump_elimination_with_optimized_out_block + x = Object.new + def x.bug(obj) + if obj || obj + obj = obj + else + raise "[ruby-core:87830] [Bug #14897]" + end + obj + end + assert_equal(:ok, x.bug(:ok)) + end end |