Feature #12172 » 0003-introduce-opt_newarray_max-min-for-Array-max-min.patch
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_
|
||
};
|
- « Previous
- 1
- 2
- 3
- Next »