summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-11-18 02:32:17 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-11-18 02:32:17 +0000
commit4a23f0695a40e735a2215ea9fbf7e388e384f051 (patch)
tree59cef8c39af71bf62fea6bbc91d6c604d1506127
parente4fc85dfcf3b089ce8522f8dc694d7ed338603ee (diff)
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
-rw-r--r--ChangeLog7
-rw-r--r--compile.c27
2 files changed, 34 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index b5a13556d9..2075e954e1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Wed Nov 18 11:32:15 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * 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.
+
Wed Nov 18 10:33:06 2015 NAKAMURA Usaku <usa@ruby-lang.org>
* ext/socket/ancdata.c (bsock_recvmsg_internal): stretch the buffer size
diff --git a/compile.c b/compile.c
index f66f12e94b..ae900fbf31 100644
--- a/compile.c
+++ b/compile.c
@@ -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);
}