aboutsummaryrefslogtreecommitdiffstats
path: root/insns.def
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 /insns.def
parent4ca0483a2879d6db9174d26f62ea98de33058650 (diff)
downloadruby-3c7c983300670b29e6c7feb3b8c23421c53af01b.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.def68
1 files changed, 68 insertions, 0 deletions
diff --git a/insns.def b/insns.def
index 98871bf9a6..5b08d0625a 100644
--- a/insns.def
+++ b/insns.def
@@ -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