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 | 4c63cb161ab62d08ceaefb029aa3fe1ca4da92be (patch) | |
tree | 728707319212fd344ab8b2723cd7c5b3f22a88a7 /insns.def | |
parent | 380cabf8224c5623af4e686240404097da01f17d (diff) | |
download | ruby-4c63cb161ab62d08ceaefb029aa3fe1ca4da92be.tar.gz |
* 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 'insns.def')
-rw-r--r-- | insns.def | 68 |
1 files changed, 68 insertions, 0 deletions
@@ -986,6 +986,74 @@ opt_str_freeze } } +DEFINE_INSN +opt_newarray_max +(rb_num_t num) +(...) +(VALUE val) // inc += 1 - num; +{ +#define id_cmp idCmp + if (BASIC_OP_UNREDEFINED_P(BOP_MAX, ARRAY_REDEFINED_OP_FLAG)) { + if (num == 0) { + val = Qnil; + } + else { + struct cmp_opt_data cmp_opt = { 0, 0 }; + VALUE result = Qundef; + rb_num_t i = num - 1; + result = TOPN(i); + while (i-- > 0) { + const VALUE v = TOPN(i); + if (result == Qundef || OPTIMIZED_CMP(v, result, cmp_opt) > 0) { + result = v; + } + } + val = result == Qundef ? Qnil : result; + } + POPN(num); + } + else { + VALUE ary = rb_ary_new4((long)num, STACK_ADDR_FROM_TOP(num)); + val = rb_funcall(ary, idMax, 0); + POPN(num); + } +#undef id_cmp +} + +DEFINE_INSN +opt_newarray_min +(rb_num_t num) +(...) +(VALUE val) // inc += 1 - num; +{ +#define id_cmp idCmp + if (BASIC_OP_UNREDEFINED_P(BOP_MIN, ARRAY_REDEFINED_OP_FLAG)) { + if (num == 0) { + val = Qnil; + } + else { + struct cmp_opt_data cmp_opt = { 0, 0 }; + VALUE result = Qundef; + rb_num_t i = num - 1; + result = TOPN(i); + while (i-- > 0) { + const VALUE v = TOPN(i); + if (result == Qundef || OPTIMIZED_CMP(v, result, cmp_opt) < 0) { + result = v; + } + } + val = result == Qundef ? Qnil : result; + } + POPN(num); + } + else { + VALUE ary = rb_ary_new4((long)num, STACK_ADDR_FROM_TOP(num)); + val = rb_funcall(ary, idMin, 0); + POPN(num); + } +#undef id_cmp +} + /** @c optimize @e Invoke method without block |