diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-11-18 02:32:17 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-11-18 02:32:17 +0000 |
commit | 4a23f0695a40e735a2215ea9fbf7e388e384f051 (patch) | |
tree | 59cef8c39af71bf62fea6bbc91d6c604d1506127 /compile.c | |
parent | e4fc85dfcf3b089ce8522f8dc694d7ed338603ee (diff) | |
download | ruby-4a23f0695a40e735a2215ea9fbf7e388e384f051.tar.gz |
compile.c: optimize useless branches
* compile.c (iseq_peephole_optimize): eliminate always/never
branches after a literal object. this sequence typically
appears by defined? operator for a method call on a local
variable.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52633 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r-- | compile.c | 27 |
1 files changed, 27 insertions, 0 deletions
@@ -2031,6 +2031,33 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal */ replace_destination(iobj, nobj); } + else if (pobj) { + int cond; + if (pobj->insn_id == BIN(putobject)) { + cond = (iobj->insn_id == BIN(branchif) ? + OPERAND_AT(pobj, 0) != Qfalse : + iobj->insn_id == BIN(branchunless) ? + OPERAND_AT(pobj, 0) == Qfalse : + FALSE); + } + else if (pobj->insn_id == BIN(putstring)) { + cond = iobj->insn_id == BIN(branchif); + } + else if (pobj->insn_id == BIN(putnil)) { + cond = iobj->insn_id != BIN(branchif); + } + else break; + REMOVE_ELEM(&pobj->link); + if (cond) { + iobj->insn_id = BIN(jump); + goto again; + } + else { + unref_destination(iobj); + REMOVE_ELEM(&iobj->link); + } + break; + } else break; nobj = (INSN *)get_destination_insn(nobj); } |