optimizer: certain bitwise-operation patterns always produce fixnums

This commit is contained in:
Matthew Flatt 2013-08-13 12:57:10 -06:00
parent de322740a6
commit 3f8475d6a9

View File

@ -1924,9 +1924,11 @@ static int produces_local_type(Scheme_Object *rator, int argc)
return 0; return 0;
} }
int scheme_expr_produces_local_type(Scheme_Object *expr) static int expr_produces_local_type(Scheme_Object *expr, int fuel)
/* can be called by the JIT */ /* can be called by the JIT */
{ {
if (fuel <= 0) return 0;
while (1) { while (1) {
switch (SCHEME_TYPE(expr)) { switch (SCHEME_TYPE(expr)) {
case scheme_application_type: case scheme_application_type:
@ -1944,6 +1946,27 @@ int scheme_expr_produces_local_type(Scheme_Object *expr)
case scheme_application3_type: case scheme_application3_type:
{ {
Scheme_App3_Rec *app = (Scheme_App3_Rec *)expr; Scheme_App3_Rec *app = (Scheme_App3_Rec *)expr;
if (SCHEME_PRIMP(app->rator)
&& (SCHEME_PRIM_PROC_OPT_FLAGS(app->rator) & SCHEME_PRIM_IS_BINARY_INLINED)) {
/* Recognize combinations of bitwise operations as generating fixnums */
if (IS_NAMED_PRIM(app->rator, "bitwise-and")) {
if ((expr_produces_local_type(app->rand1, fuel-1) == SCHEME_LOCAL_TYPE_FIXNUM)
|| (expr_produces_local_type(app->rand2, fuel-1) == SCHEME_LOCAL_TYPE_FIXNUM))
return SCHEME_LOCAL_TYPE_FIXNUM;
} else if (IS_NAMED_PRIM(app->rator, "bitwise-ior")
|| IS_NAMED_PRIM(app->rator, "bitwise-xor")) {
if ((expr_produces_local_type(app->rand1, fuel-1) == SCHEME_LOCAL_TYPE_FIXNUM)
&& (expr_produces_local_type(app->rand2, fuel-1) == SCHEME_LOCAL_TYPE_FIXNUM))
return SCHEME_LOCAL_TYPE_FIXNUM;
} else if (IS_NAMED_PRIM(app->rator, "arithmetic-shift")) {
if (SCHEME_INTP(app->rand2) && (SCHEME_INT_VAL(app->rand2) <= 0)
&& (expr_produces_local_type(app->rand1, fuel-1) == SCHEME_LOCAL_TYPE_FIXNUM))
return SCHEME_LOCAL_TYPE_FIXNUM;
}
}
return produces_local_type(app->rator, 2); return produces_local_type(app->rator, 2);
} }
break; break;
@ -1973,6 +1996,11 @@ int scheme_expr_produces_local_type(Scheme_Object *expr)
} }
} }
int scheme_expr_produces_local_type(Scheme_Object *expr)
{
return expr_produces_local_type(expr, 10);
}
static Scheme_Object *finish_optimize_app(Scheme_Object *o, Optimize_Info *info, int context, int rator_flags) static Scheme_Object *finish_optimize_app(Scheme_Object *o, Optimize_Info *info, int context, int rator_flags)
{ {
switch(SCHEME_TYPE(o)) { switch(SCHEME_TYPE(o)) {