From 6c2888937aea5f12333762dbefa8efd76ac9640a Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Sat, 4 Apr 2015 18:47:49 -0300 Subject: [PATCH] Make (make-vector ) 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. --- .../tests/racket/optimize.rktl | 20 +++++++++--- racket/src/racket/src/optimize.c | 32 +++++++++++++++++++ racket/src/racket/src/validate.c | 18 ++++++++++- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index ed55e36b5c..0b3794dbb9 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -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) diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index a1379c36a6..d7d8ff02fd 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -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 ) => */ + 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 ) => */ + 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: diff --git a/racket/src/racket/src/validate.c b/racket/src/racket/src/validate.c index f039b50570..8959163593 100644 --- a/racket/src/racket/src/validate.c +++ b/racket/src/racket/src/validate.c @@ -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;