Make (make-vector <number>) omittable

In many use cases the length of the vector is fixed and know,
so we are sure that make-vector will not raise an error and
we can recognize these expressions as omittable and drop
them when the result is ignored.
This commit is contained in:
Gustavo Massaccesi 2015-04-04 18:47:49 -03:00
parent 2be6eb9570
commit 6c2888937a
3 changed files with 65 additions and 5 deletions

View File

@ -1280,6 +1280,18 @@
'(lambda (w z) (make-vector (w) (z)) #t))
(test-comp '(lambda (w z) (vector? (make-vector (w))))
'(lambda (w z) (make-vector (w)) #t))
(test-comp '(lambda (w z) (vector? (make-vector 5 (z))))
'(lambda (w z) (values (z)) #t))
#;(test-comp '(lambda (w z) (vector? (make-vector 5 w)))
'(lambda (w z) #t))
(test-comp '(lambda (w z) (vector? (make-vector 5)))
'(lambda (w z) #t))
(test-comp '(lambda (w z) (vector? (make-vector -1)))
'(lambda (w z) #t)
#f)
(test-comp '(lambda (w z) (vector? (make-vector #f)))
'(lambda (w z) #t)
#f)
(test-comp '(lambda (w z)
(let ([x (list* w z)]
@ -1450,14 +1462,14 @@
(car (cons (list 7) (values (f)))))
#f)
;don't exchange if it may be not safe for space
(test-comp '(lambda (f)
(test-comp '(lambda (f n)
(let ([big (cons (f) (make-vector 10))])
(display big)
(begin (make-vector 20) (car big))))
'(lambda (f)
(begin (make-vector n) (car big))))
'(lambda (f n)
(let ([big (cons (f) (make-vector 10))])
(display big)
(car (cons (car big) (make-vector 20)))))
(car (cons (car big) (make-vector n)))))
#f)
(test-comp '(lambda (w)

View File

@ -449,6 +449,12 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved,
if (scheme_omittable_expr(app->rand, 1, fuel - 1, resolved, opt_info, warn_info,
min_id_depth, id_offset + (resolved ? 1 : 0), no_id))
return 1;
} else if (SAME_OBJ(app->rator, scheme_make_vector_proc)
&& (vals == 1 || vals == -1)
&& (SCHEME_INTP(app->rand)
&& (SCHEME_INT_VAL(app->rand) >= 0))
&& IN_FIXNUM_RANGE_ON_ALL_PLATFORMS(SCHEME_INT_VAL(app->rand))) {
return 1;
} else if (SCHEME_PRIMP(app->rator)) {
if (!(SCHEME_PRIM_PROC_FLAGS(app->rator) & SCHEME_PRIM_IS_MULTI_RESULT)
|| SAME_OBJ(scheme_values_func, app->rator)) {
@ -467,6 +473,14 @@ int scheme_omittable_expr(Scheme_Object *o, int vals, int fuel, int resolved,
&& scheme_omittable_expr(app->rand2, 1, fuel - 1, resolved, opt_info, warn_info,
min_id_depth, id_offset + (resolved ? 2 : 0), no_id))
return 1;
} else if (SAME_OBJ(app->rator, scheme_make_vector_proc)
&& (vals == 1 || vals == -1)
&& (SCHEME_INTP(app->rand1)
&& (SCHEME_INT_VAL(app->rand1) >= 0)
&& IN_FIXNUM_RANGE_ON_ALL_PLATFORMS(SCHEME_INT_VAL(app->rand1)))
&& scheme_omittable_expr(app->rand2, 1, fuel - 1, resolved, opt_info, warn_info,
min_id_depth, id_offset + (resolved ? 2 : 0), no_id)) {
return 1;
} else if (SCHEME_PRIMP(app->rator)) {
if (!(SCHEME_PRIM_PROC_FLAGS(app->rator) & SCHEME_PRIM_IS_MULTI_RESULT)) {
note_match(1, vals, warn_info);
@ -636,6 +650,13 @@ static Scheme_Object *optimize_ignored(Scheme_Object *e, Optimize_Info *info, in
if (!SAME_OBJ(app->rator, scheme_values_func)) /* `values` is probably here to ensure a single result */
if (scheme_is_functional_nonfailing_primitive(app->rator, 1, expected_vals))
return do_make_discarding_sequence(app->rand, scheme_void, info, id_offset, 1, 0);
/* (make-vector <num>) => <void> */
if (SAME_OBJ(app->rator, scheme_make_vector_proc)
&& (SCHEME_INTP(app->rand)
&& (SCHEME_INT_VAL(app->rand) >= 0))
&& IN_FIXNUM_RANGE_ON_ALL_PLATFORMS(SCHEME_INT_VAL(app->rand)))
return (maybe_omittable ? NULL : scheme_void);
}
break;
case scheme_application3_type:
@ -650,6 +671,17 @@ static Scheme_Object *optimize_ignored(Scheme_Object *e, Optimize_Info *info, in
1, 0),
info, id_offset,
1, 0);
/* (make-vector <num> <expr>) => <expr> */
if (SAME_OBJ(app->rator, scheme_make_vector_proc)
&& (SCHEME_INTP(app->rand1)
&& (SCHEME_INT_VAL(app->rand1) >= 0))
&& IN_FIXNUM_RANGE_ON_ALL_PLATFORMS(SCHEME_INT_VAL(app->rand1))) {
if (single_valued_noncm_expression(app->rand2, 5))
return optimize_ignored(app->rand2, info, id_offset, 1, maybe_omittable, 5);
else
return ensure_single_value(optimize_ignored(app->rand2, info, id_offset, 1, 0, 5));
}
}
break;
case scheme_application_type:

View File

@ -1574,6 +1574,14 @@ static int validate_expr(Mz_CPort *port, Scheme_Object *expr,
if (result) {
r = is_functional_nonfailing_rator(app->rator, 1, expected_results, _st_ht);
if (!r
&& SAME_OBJ(app->rator, scheme_make_vector_proc)
&& (expected_results == 1 || expected_results == -1)
&& (SCHEME_INTP(app->rand)
&& (SCHEME_INT_VAL(app->rand) >= 0)
&& IN_FIXNUM_RANGE_ON_ALL_PLATFORMS(SCHEME_INT_VAL(app->rand)))) {
r = 1;
}
result = validate_join(result, r);
}
}
@ -1612,7 +1620,15 @@ static int validate_expr(Mz_CPort *port, Scheme_Object *expr,
if (result) {
r = is_functional_nonfailing_rator(app->rator, 2, expected_results, _st_ht);
result = validate_join(r, result);
if (!r
&& SAME_OBJ(app->rator, scheme_make_vector_proc)
&& (expected_results == 1 || expected_results == -1)
&& (SCHEME_INTP(app->rand1)
&& (SCHEME_INT_VAL(app->rand1) >= 0)
&& IN_FIXNUM_RANGE_ON_ALL_PLATFORMS(SCHEME_INT_VAL(app->rand1)))) {
r = 1;
}
result = validate_join(r, result);
}
}
break;