aboutsummaryrefslogtreecommitdiffstats
path: root/compile.c
diff options
context:
space:
mode:
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 */