Project

General

Profile

0003-introduce-opt_newarray_max-min-for-Array-max-min.patch

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

Download (4.03 KB)

View differences:

compile.c
4916 4916
	    }
4917 4917
	    break;
4918 4918
	}
4919
	/* optimization shortcut
4920
	*   [a, b, ...].max/min -> a, b, c, opt_newarray_max/min
4921
	*/
4922
	if (node->nd_recv && nd_type(node->nd_recv) == NODE_ARRAY &&
4923
	    (node->nd_mid == idMax || node->nd_mid == idMin) && node->nd_args == NULL &&
4924
	    ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
4925
	    ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
4926
	    COMPILE(ret, "recv", node->nd_recv);
4927
	    if (((INSN*)ret->last)->insn_id == BIN(newarray)) {
4928
		((INSN*)ret->last)->insn_id = node->nd_mid == idMax ? BIN(opt_newarray_max) :
4929
		BIN(opt_newarray_min);
4930
	    }
4931
	    else {
4932
		ADD_SEND(ret, line, node->nd_mid, INT2FIX(0));
4933
	    }
4934
	    if (poped) {
4935
		ADD_INSN(ret, line, pop);
4936
	    }
4937
	    break;
4938
	}
4919 4939
      case NODE_QCALL:
4920 4940
      case NODE_FCALL:
4921 4941
      case NODE_VCALL:{		/* VCALL: variable or call */
defs/id.def
1 1
# -*- mode: ruby; coding: us-ascii -*-
2 2
firstline, predefined = __LINE__+1, %[\
3
  max
4
  min
3 5
  freeze
4 6
  inspect
5 7
  intern
insns.def
986 986
    }
987 987
}
988 988

  
989
DEFINE_INSN
990
opt_newarray_max
991
(rb_num_t num)
992
(...)
993
(VALUE val) // inc += 1 - num;
994
{
995
#define id_cmp  idCmp
996
    if (BASIC_OP_UNREDEFINED_P(BOP_MAX, ARRAY_REDEFINED_OP_FLAG)) {
997
	if (num == 0) {
998
	    val = Qnil;
999
	}
1000
	else {
1001
	    struct cmp_opt_data cmp_opt = { 0, 0 };
1002
	    VALUE result = Qundef;
1003
	    rb_num_t i = num - 1;
1004
	    result = TOPN(i);
1005
	    while (i-- > 0) {
1006
		const VALUE v = TOPN(i);
1007
		if (result == Qundef || OPTIMIZED_CMP(v, result, cmp_opt) > 0) {
1008
		    result = v;
1009
		}
1010
	    }
1011
	    val = result == Qundef ? Qnil : result;
1012
	}
1013
	POPN(num);
1014
    }
1015
    else {
1016
	VALUE ary = rb_ary_new4((long)num, STACK_ADDR_FROM_TOP(num));
1017
	val = rb_funcall(ary, idMax, 0);
1018
	POPN(num);
1019
    }
1020
#undef id_cmp
1021
}
1022

  
1023
DEFINE_INSN
1024
opt_newarray_min
1025
(rb_num_t num)
1026
(...)
1027
(VALUE val) // inc += 1 - num;
1028
{
1029
#define id_cmp  idCmp
1030
    if (BASIC_OP_UNREDEFINED_P(BOP_MIN, ARRAY_REDEFINED_OP_FLAG)) {
1031
	if (num == 0) {
1032
	    val = Qnil;
1033
	}
1034
	else {
1035
	    struct cmp_opt_data cmp_opt = { 0, 0 };
1036
	    VALUE result = Qundef;
1037
	    rb_num_t i = num - 1;
1038
	    result = TOPN(i);
1039
	    while (i-- > 0) {
1040
		const VALUE v = TOPN(i);
1041
		if (result == Qundef || OPTIMIZED_CMP(v, result, cmp_opt) < 0) {
1042
		    result = v;
1043
		}
1044
	    }
1045
	    val = result == Qundef ? Qnil : result;
1046
	}
1047
	POPN(num);
1048
    }
1049
    else {
1050
	VALUE ary = rb_ary_new4((long)num, STACK_ADDR_FROM_TOP(num));
1051
	val = rb_funcall(ary, idMin, 0);
1052
	POPN(num);
1053
    }
1054
#undef id_cmp
1055
}
1056

  
989 1057
/**
990 1058
  @c optimize
991 1059
  @e Invoke method without block
vm.c
1475 1475
    OP(Succ, SUCC), (C(Fixnum), C(String), C(Time));
1476 1476
    OP(EqTilde, MATCH), (C(Regexp), C(String));
1477 1477
    OP(Freeze, FREEZE), (C(String));
1478
    OP(Max, MAX), (C(Array));
1479
    OP(Min, MIN), (C(Array));
1478 1480
#undef C
1479 1481
#undef OP
1480 1482
}
vm_core.h
453 453
    BOP_NEQ,
454 454
    BOP_MATCH,
455 455
    BOP_FREEZE,
456
    BOP_MAX,
457
    BOP_MIN,
456 458

  
457 459
    BOP_LAST_
458 460
};
459
-