[INTERPRETER]

* OPT: Many optimizations. One is big (gcc is not really clever sometimes!), 
  and now Gambas is about 30% faster than interpreted Python when running 
  stupid benchmarks.


git-svn-id: svn://localhost/gambas/trunk@3005 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2010-06-13 20:25:34 +00:00
parent 390a19785c
commit aaf1044366
5 changed files with 287 additions and 24 deletions

View File

@ -76,7 +76,7 @@ static void *SubrTable[] =
/* 28 */ _SUBR_comp, _SUBR_compn, SUBR_compi, SUBR_compi,
/* 2C */ SUBR_compi, SUBR_compi, SUBR_near, SUBR_case,
/* 30 */ _SUBR_add, _SUBR_sub, _SUBR_mul, _SUBR_div,
/* 34 */ SUBR_neg_, SUBR_quo, SUBR_rem, SUBR_pow,
/* 34 */ SUBR_neg, SUBR_quo, SUBR_rem, SUBR_pow,
/* 38 */ SUBR_and_, SUBR_and_, SUBR_and_, SUBR_not,
/* 3C */ SUBR_cat, SUBR_like, SUBR_file, SUBR_is,
@ -100,9 +100,9 @@ static void *SubrTable[] =
SUBR_strcomp, /* 17 51 */
SUBR_iconv, /* 18 52 */
SUBR_sconv, /* 19 53 */
SUBR_neg_, /* 20 54 */
SUBR_neg_, /* 21 55 */
SUBR_neg_, /* 22 56 */
SUBR_abs, /* 20 54 */
SUBR_int, /* 21 55 */
SUBR_fix, /* 22 56 */
SUBR_sgn, /* 23 57 */
SUBR_math, /* 24 58 */
SUBR_pi, /* 25 59 */
@ -469,7 +469,9 @@ _SUBR_CODE:
_NEXT:
PC++;
PC++;
code = *PC;
goto *jump_table[code >> 8];
/*-----------------------------------------------*/

View File

@ -110,16 +110,6 @@ int fsgn(double x)
return ((x > 0) ? 1 : ((x < 0) ? (-1) : 0));
}
double deg(double x)
{
return x * 180 / M_PI;
}
double rad(double x)
{
return x * M_PI / 180;
}
double fix(double x)
{
if (x >= 0)

View File

@ -33,8 +33,6 @@ int llsgn(int64_t x);
double frac(double x);
int fsgn(double x);
double deg(double x);
double rad(double x);
double fix(double x);
double frexp10(double x, int *exp);
double ang(double x, double y);
@ -42,6 +40,9 @@ double ang(double x, double y);
void randomize(bool set, uint seed);
double rnd(void);
#define deg(_x) ((_x) * 180 / M_PI)
#define rad(_x) ((_x) * M_PI / 180)
#if defined(OS_FREEBSD) || defined(OS_OPENBSD) || defined(OS_CYGWIN)
double exp10(double x);
#ifdef log2

View File

@ -104,7 +104,10 @@ void SUBR_pow(void);
void SUBR_and_(ushort code);
void SUBR_not(ushort code);
void SUBR_neg_(ushort code);
void SUBR_neg(ushort code);
void SUBR_int(ushort code);
void SUBR_abs(ushort code);
void SUBR_fix(ushort code);
void SUBR_sgn(ushort code);
void SUBR_pi(ushort code);
void SUBR_math(ushort code);

View File

@ -37,11 +37,11 @@
#define ABS(x) ((x) < 0 ? (-x) : (x))
static MATH_FUNC MathFunc[] = {
/*static MATH_FUNC MathFunc[] = {
NULL, frac, log, exp, sqrt, sin, cos, tan, atan, asin, acos,
deg, rad, log10, sinh, cosh, tanh, asinh, acosh, atanh,
exp2, exp10, log2, cbrt, expm1, log1p
};
};*/
static MATH_FUNC_2 MathFunc2[] = {
NULL, atan2, ang, hypot
@ -145,11 +145,45 @@ void SUBR_round(ushort code)
void SUBR_math(ushort code)
{
static void *jump[] = {
NULL, &&__FRAC, &&__LOG, &&__EXP, &&__SQRT, &&__SIN, &&__COS, &&__TAN, &&__ATAN, &&__ASIN, &&__ACOS,
&&__DEG, &&__RAD, &&__LOG10, &&__SINH, &&__COSH, &&__TANH, &&__ASINH, &&__ACOSH, &&__ATANH,
&&__EXP2, &&__EXP10, &&__LOG2, &&__CBRT, &&__EXPM1, &&__LOG1P
};
SUBR_ENTER_PARAM(1);
VALUE_conv_float(PARAM);
goto *jump[code & 0x1F];
PARAM->_float.value = (*MathFunc[code & 0x1F])(PARAM->_float.value);
__FRAC: PARAM->_float.value = frac(PARAM->_float.value); goto __END;
__LOG: PARAM->_float.value = log(PARAM->_float.value); goto __END;
__EXP: PARAM->_float.value = exp(PARAM->_float.value); goto __END;
__SQRT: PARAM->_float.value = sqrt(PARAM->_float.value); goto __END;
__SIN: PARAM->_float.value = sin(PARAM->_float.value); goto __END;
__COS: PARAM->_float.value = cos(PARAM->_float.value); goto __END;
__TAN: PARAM->_float.value = tan(PARAM->_float.value); goto __END;
__ATAN: PARAM->_float.value = atan(PARAM->_float.value); goto __END;
__ASIN: PARAM->_float.value = asin(PARAM->_float.value); goto __END;
__ACOS: PARAM->_float.value = acos(PARAM->_float.value); goto __END;
__DEG: PARAM->_float.value = deg(PARAM->_float.value); goto __END;
__RAD: PARAM->_float.value = rad(PARAM->_float.value); goto __END;
__LOG10: PARAM->_float.value = log10(PARAM->_float.value); goto __END;
__SINH: PARAM->_float.value = sinh(PARAM->_float.value); goto __END;
__COSH: PARAM->_float.value = cosh(PARAM->_float.value); goto __END;
__TANH: PARAM->_float.value = tanh(PARAM->_float.value); goto __END;
__ASINH: PARAM->_float.value = asinh(PARAM->_float.value); goto __END;
__ACOSH: PARAM->_float.value = acosh(PARAM->_float.value); goto __END;
__ATANH: PARAM->_float.value = atanh(PARAM->_float.value); goto __END;
__EXP2: PARAM->_float.value = exp2(PARAM->_float.value); goto __END;
__EXP10: PARAM->_float.value = exp10(PARAM->_float.value); goto __END;
__LOG2: PARAM->_float.value = log2(PARAM->_float.value); goto __END;
__CBRT: PARAM->_float.value = cbrt(PARAM->_float.value); goto __END;
__EXPM1: PARAM->_float.value = expm1(PARAM->_float.value); goto __END;
__LOG1P: PARAM->_float.value = log1p(PARAM->_float.value); goto __END;
__END:
if (!finite(PARAM->_float.value))
THROW(E_MATH);
@ -177,10 +211,34 @@ void SUBR_pow(void)
SUBR_ENTER_PARAM(2);
VALUE_conv_float(&PARAM[0]);
VALUE_conv_float(&PARAM[1]);
if (TYPE_is_integer(PARAM[1].type))
{
static void *jump[] = { &&__M4, &&__M3, &&__M2, &&__M1, &&__P0, &&__END, &&__P2, &&__P3, &&__P4 };
int val = PARAM[1]._integer.value;
if (val >= -4 && val <= 4)
goto *jump[val + 4];
else
goto __FLOAT;
__P0: PARAM->_float.value = 1.0; goto __END;
__P2: PARAM->_float.value *= PARAM->_float.value; goto __END;
__P3: PARAM->_float.value *= PARAM->_float.value * PARAM->_float.value; goto __END;
__P4: PARAM->_float.value *= PARAM->_float.value;PARAM->_float.value *= PARAM->_float.value; goto __END;
__M1: PARAM->_float.value = 1.0 / PARAM->_float.value; goto __END;
__M2: PARAM->_float.value = 1.0 / PARAM->_float.value / PARAM->_float.value; goto __END;
__M3: PARAM->_float.value = 1.0 / PARAM->_float.value / PARAM->_float.value / PARAM->_float.value; goto __END;
__M4: PARAM->_float.value = 1.0 / PARAM->_float.value / PARAM->_float.value / PARAM->_float.value / PARAM->_float.value; goto __END;
}
__FLOAT:
VALUE_conv_float(&PARAM[1]);
PARAM->_float.value = pow(PARAM[0]._float.value, PARAM[1]._float.value);
__END:
if (!finite(PARAM->_float.value))
THROW(E_MATH);
@ -407,6 +465,28 @@ __END:
SP--;
}
#define MANAGE_VARIANT(_func) \
({ \
type = P1->type; \
\
if (TYPE_is_number_date(type)) \
{ \
*PC |= type; \
goto *jump[type]; \
} \
\
if (TYPE_is_variant(type)) \
{ \
type = P1->_variant.vtype; \
if (TYPE_is_number_date(type)) \
{ \
VARIANT_undo(P1); \
(_func)(code | type); \
VALUE_conv_variant(P1); \
return; \
} \
} \
})
void SUBR_sgn(ushort code)
@ -460,6 +540,195 @@ __END:
}
void SUBR_neg(ushort code)
{
static void *jump[] = {
&&__VARIANT, &&__BOOLEAN, &&__BYTE, &&__SHORT, &&__INTEGER, &&__LONG, &&__SINGLE, &&__FLOAT, &&__ERROR
};
VALUE *P1;
TYPE type;
P1 = SP - 1;
type = code & 0x0F;
goto *jump[type];
__BOOLEAN:
return;
__BYTE:
P1->_integer.value = (unsigned char)(-P1->_integer.value); return;
__SHORT:
P1->_integer.value = (short)(-P1->_integer.value); return;
__INTEGER:
P1->_integer.value = (-P1->_integer.value); return;
__LONG:
P1->_long.value = (-P1->_long.value); return;
__SINGLE:
VALUE_conv_float(P1);
__FLOAT:
P1->_float.value = (-P1->_float.value); return;
__VARIANT:
MANAGE_VARIANT(SUBR_neg);
__ERROR:
THROW(E_TYPE, "Number", TYPE_get_name(type));
}
void SUBR_abs(ushort code)
{
static void *jump[] = {
&&__VARIANT, &&__BOOLEAN, &&__BYTE, &&__SHORT, &&__INTEGER, &&__LONG, &&__SINGLE, &&__FLOAT, &&__ERROR
};
VALUE *P1;
TYPE type;
P1 = SP - 1;
type = code & 0x0F;
goto *jump[type];
__BOOLEAN:
return;
__BYTE:
P1->_integer.value = (unsigned char)ABS(-P1->_integer.value); return;
__SHORT:
P1->_integer.value = (short)ABS(P1->_integer.value); return;
__INTEGER:
P1->_integer.value = ABS(P1->_integer.value); return;
__LONG:
P1->_long.value = ABS(P1->_long.value); return;
__SINGLE:
VALUE_conv_float(P1);
__FLOAT:
P1->_float.value = fabs(P1->_float.value); return;
__VARIANT:
MANAGE_VARIANT(SUBR_abs);
__ERROR:
THROW(E_TYPE, "Number", TYPE_get_name(type));
}
void SUBR_int(ushort code)
{
static void *jump[] = {
&&__VARIANT, &&__BOOLEAN, &&__BYTE, &&__SHORT, &&__INTEGER, &&__LONG, &&__SINGLE, &&__FLOAT, &&__ERROR
};
VALUE *P1;
TYPE type;
P1 = SP - 1;
type = code & 0x0F;
goto *jump[type];
__BOOLEAN:
__BYTE:
__SHORT:
__INTEGER:
__LONG:
return;
__SINGLE:
VALUE_conv_float(P1);
__FLOAT:
P1->_float.value = floor(P1->_float.value); return;
__VARIANT:
MANAGE_VARIANT(SUBR_int);
__ERROR:
THROW(E_TYPE, "Number", TYPE_get_name(type));
}
void SUBR_fix(ushort code)
{
static void *jump[] = {
&&__VARIANT, &&__BOOLEAN, &&__BYTE, &&__SHORT, &&__INTEGER, &&__LONG, &&__SINGLE, &&__FLOAT, &&__ERROR
};
VALUE *P1;
TYPE type;
P1 = SP - 1;
type = code & 0x0F;
goto *jump[type];
__BOOLEAN:
__BYTE:
__SHORT:
__INTEGER:
__LONG:
return;
__SINGLE:
VALUE_conv_float(P1);
__FLOAT:
P1->_float.value = fix(P1->_float.value); return;
__VARIANT:
MANAGE_VARIANT(SUBR_fix);
__ERROR:
THROW(E_TYPE, "Number", TYPE_get_name(type));
}
#if 0
void SUBR_neg_(ushort code)
{
static void *jump[] = {
@ -585,8 +854,6 @@ __END:
return;
}
#if 0
void SUBR_add_(ushort code)
{
static void *jump[] = {