Project

General

Profile

Feature #12172 » 0003-introduce-opt_newarray_max-min-for-Array-max-min.patch

mame (Yusuke Endoh), 03/14/2016 01:28 PM

View differences:

compile.c
}
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 */
defs/id.def
# -*- mode: ruby; coding: us-ascii -*-
firstline, predefined = __LINE__+1, %[\
max
min
freeze
inspect
intern
insns.def
}
}
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
vm.c
OP(Succ, SUCC), (C(Fixnum), C(String), C(Time));
OP(EqTilde, MATCH), (C(Regexp), C(String));
OP(Freeze, FREEZE), (C(String));
OP(Max, MAX), (C(Array));
OP(Min, MIN), (C(Array));
#undef C
#undef OP
}
vm_core.h
BOP_NEQ,
BOP_MATCH,
BOP_FREEZE,
BOP_MAX,
BOP_MIN,
BOP_LAST_
};
(3-3/3)