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 »