summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authormame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-03-17 12:47:31 +0000
committermame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-03-17 12:47:31 +0000
commit3c7c983300670b29e6c7feb3b8c23421c53af01b (patch)
tree728707319212fd344ab8b2723cd7c5b3f22a88a7 /compile.c
parent4ca0483a2879d6db9174d26f62ea98de33058650 (diff)
* compile.c (NODE_CALL): add optimization shortcut for Array#max/min.
Now `[x, y].max` is optimized so that a temporal array object is not created in some condition. * insns.def (opt_newarray_max, opt_newarray_min): added. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54153 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/compile.c b/compile.c
index 76024dfe53..767e2b1772 100644
--- a/compile.c
+++ b/compile.c
@@ -4916,6 +4916,26 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
break;
}
+ /* optimization shortcut
+ * [a, b, ...].max/min -> a, b, c, opt_newarray_max/min
+ */
+ if (node->nd_recv && nd_type(node->nd_recv) == NODE_ARRAY &&
+ (node->nd_mid == idMax || node->nd_mid == idMin) && node->nd_args == NULL &&
+ ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
+ ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
+ COMPILE(ret, "recv", node->nd_recv);
+ if (((INSN*)ret->last)->insn_id == BIN(newarray)) {
+ ((INSN*)ret->last)->insn_id =
+ node->nd_mid == idMax ? BIN(opt_newarray_max) : BIN(opt_newarray_min);
+ }
+ else {
+ ADD_SEND(ret, line, node->nd_mid, INT2FIX(0));
+ }
+ if (poped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
case NODE_QCALL:
case NODE_FCALL:
case NODE_VCALL:{ /* VCALL: variable or call */