diff options
author | mame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-03-17 12:47:31 +0000 |
---|---|---|
committer | mame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-03-17 12:47:31 +0000 |
commit | 3c7c983300670b29e6c7feb3b8c23421c53af01b (patch) | |
tree | 728707319212fd344ab8b2723cd7c5b3f22a88a7 /compile.c | |
parent | 4ca0483a2879d6db9174d26f62ea98de33058650 (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.c | 20 |
1 files changed, 20 insertions, 0 deletions
@@ -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 */ |