~ chicken-core (chicken-5) e690a31507c1afebd93d4b056e79e6004b12594e
commit e690a31507c1afebd93d4b056e79e6004b12594e Merge: 7a3f416c cf5393cd Author: felix <felix@call-with-current-continuation.org> AuthorDate: Mon May 9 08:20:01 2011 +0200 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Mon May 9 08:20:01 2011 +0200 resolved conflicts diff --cc compiler.scm index 16c4f9fa,c02cecf6..c01cf532 --- a/compiler.scm +++ b/compiler.scm @@@ -71,8 -71,6 +71,7 @@@ ; (unsafe) ; (unused <symbol> ...) ; (uses {<unitname>}) - ; (unsafe-specialized-arithmetic) +; (specialize) ; ; <type> = fixnum | generic @@@ -332,12 -330,11 +331,11 @@@ (define standalone-executable #t) (define local-definitions #f) (define inline-locally #f) -(define inline-output-file #f) -(define do-scrutinize #f) (define enable-inline-files #f) (define compiler-syntax-enabled #t) - (define unchecked-specialized-arithmetic #f) (define bootstrap-mode #f) +(define struct-variable-types #f) +(define enable-specialization #f) ;;; These are here so that the backend can access them: @@@ -1514,21 -1488,12 +1512,19 @@@ (for-each (lambda (spec) (cond ((and (list? spec) (symbol? (car spec)) (= 2 (length spec))) - (##sys#put! (car spec) '##core#type (cadr spec)) - (##sys#put! (car spec) '##core#declared-type #t)) + (let ((name (##sys#globalize (car spec) se)) + (type (##sys#strip-syntax (cadr spec)))) + (cond ((validate-type type name) => + (lambda (type) + (##sys#put! name '##compiler#predicate type))) + (else + (warning "illegal `predicate' declaration" spec))))) (else - (warning "illegal `predicate' declaration" spec)))) - (cdr spec))) + (warning "illegal `type' declaration item" spec)))) + (globalize-all (cdr spec)))) - (else (warning "illegal declaration specifier" spec)) ) + ((specialize) + (set! enable-specialization #t)) - ((unsafe-specialized-arithmetic) - (set! unchecked-specialized-arithmetic #t)) + (else (warning "unknown declaration specifier" spec)) ) '(##core#undefined) ) ) ) diff --cc manual/Declarations index 0bec4e45,a693046e..c6af35d4 --- a/manual/Declarations +++ b/manual/Declarations @@@ -356,18 -384,7 +356,7 @@@ are registered as features during compi knows about them. - === unsafe-specialized-arithmetic - - [declaration specifier] (unsafe-specialized-arithmetic) - - Assume specialized arithmetic operations like {{fp+}}, {{fpsin}}, etc. - are always called with arguments of correct type and perform - unboxing of intermediate results if possible and if the {{-unboxing}} - compiler-option has been enabled (done by default on optimization - levels 2 and higher). - - --- -Previous: [[Modules]] +Previous: [[Types]] Next: [[Parameters]] diff --cc optimizer.scm index 36a4b737,c3c94561..de01886f --- a/optimizer.scm +++ b/optimizer.scm @@@ -1076,12 -1074,9 +1076,9 @@@ (and inline-substitutions-enabled (or (not argc) (= rargc argc)) (intrinsic? name) - (or unsafe - (if (eq? safe 'specialized) - unchecked-specialized-arithmetic - safe)) + (or unsafe safe) (make-node - '##core#call '(#t) + '##core#call (list #t) (list cont (make-node '##core#inline_allocate diff --cc unboxing.scm index ed6fae4f,40224766..28de35bd --- a/unboxing.scm +++ b/unboxing.scm @@@ -307,159 -255,130 +307,154 @@@ (let ((subs (node-subexpressions n)) (params (node-parameters n)) (class (node-class n)) ) - (d "walk: (~a) ~a ~a" pass2? class params) - (case class - - ((##core#undefined - ##core#proc - ##core#global-ref - ##core#inline_ref - ##core#inline_loc_ref) #f) - - ((##core#lambda ##core#direct_lambda) - (decompose-lambda-list - (third params) - (lambda (vars argc rest) - (unless pass2? - (walk-lambda - (first params) - (map (cut cons <> #f) vars) - (first subs)) ) - #f))) - - ((##core#variable) - (let* ((v (first params)) - (a (assq v e))) - (cond (pass2? - (when (and a (cdr a)) - (copy-node! - (make-node '##core#unboxed_ref (list (alias v) (cdr a)) '()) - n))) - ((not a) #f) ; global - ((not udest) (boxed! v))) - a)) - - ((##core#inline ##core#inline_allocate) - (let* ((rw1 (##sys#get (symbolify (first params)) '##compiler#unboxed-op)) - (rw (and unsafe rw1)) - (args (map (cut walk <> #f rw pass2?) subs))) - (cond ((not rw) #f) - ((or (not pass2?) - (and dest (unboxed? dest)) - (any unboxed-value? args)) - (let ((alt (first rw)) - (atypes (second rw)) - (rtype (third rw))) - ;; result or arguments are unboxed - rewrite node to alternative - (when pass2? - (rewrite! - n alt subs args atypes rtype - (and dest (assq dest e)))) - (cons #f rtype)) ) - (else - (let ((rtype (third rw))) - ;; mark argument-vars and dest as unboxed if alternative exists - (unless pass2? - (for-each - (lambda (a) - (when (and a (car a) (cdr a)) - (unboxed! (car a) (cdr a)))) - args) - (when dest - (unboxed! dest rtype))) - (cons #f rtype)))))) - - ((let) - (let* ((v (first params)) - (r1 (walk (first subs) v #t pass2?))) - (when (and (not pass2?) r1 (cdr r1)) - (unboxed! (first params) (cdr r1))) - (let ((r (walk (second subs) dest udest pass2?))) - (when pass2? - (let ((a (assq v e))) - (if (and a (cdr a)) - (rebind-unboxed! n (cdr a)) - (straighten-binding! n))) ) - r))) - - ((set!) - (let* ((var (first params)) - (a (assq var e)) - (val (walk (first subs) var (and a (cdr a)) pass2?))) - (cond (pass2? - (when (and a (cdr a)) ; may have mutated - (copy-node! - (make-node - '##core#unboxed_set! (list (alias var) (cdr a)) subs) - n))) - ((and val (cdr val)) - (unboxed! var (cdr val))) - (else - (boxed! var) - (invalidate val) ) ) - #f)) - - ((quote) #f) - - ((if ##core#cond) - (invalidate (walk (first subs) #f #f pass2?)) - (straighten-conditional! n) - (let ((r1 (walk (second subs) dest udest pass2?)) - (r2 (walk (third subs) dest udest pass2?))) - (merge r1 r2))) - - ((##core#switch) - (invalidate (walk (first subs) #f #f pass2?)) - (do ((clauses (cdr subs) (cddr clauses)) - (r 'none - (if (eq? r 'none) - (walk (second clauses) dest udest pass2?) - (merge r (walk (second clauses) dest udest pass2?))))) - ((null? (cdr clauses)) - (merge r (walk (car clauses) dest udest pass2?))) ) ) - - ((##core#call ##core#direct_call) - (for-each (o invalidate (cut walk <> #f #f pass2?)) subs) - (when pass2? - (straighten-call! n)) - #f) - - (else - (for-each (o invalidate (cut walk <> #f #f pass2?)) subs) - #f)))) - - (d "walk lambda: ~a" id) + (d "walk: (~a) ~a ~a" (if pass2? 2 1) class params) + (set! d-depth (add1 d-depth)) + (let ((result + (case class + + ((##core#undefined + ##core#proc + ##core#global-ref + ##core#inline_ref + ##core#inline_loc_ref) #f) + + ((##core#lambda ##core#direct_lambda) + (decompose-lambda-list + (third params) + (lambda (vars argc rest) + (unless pass2? + (walk-lambda + (first params) + (map (cut cons <> #f) vars) + (first subs)) ) + #f))) + + ((##core#variable) + (let* ((v (first params)) + (a (assq v e))) + (cond (pass2? + (when (and a (cdr a)) + (copy-node! + (make-node + '##core#unboxed_ref + (list (alias v) (cdr a)) + '()) + n))) + ((not a) #f) ; global + ((not udest) (boxed! v))) + a)) + + ((##core#inline ##core#inline_allocate) + (let* ((rw1 (##sys#get + (symbolify (first params)) + '##compiler#unboxed-op)) - (rw (and rw1 - (or unsafe - (and (fourth rw1) - unchecked-specialized-arithmetic)) - rw1)) ++ (rw (and unsafe rw1)) + (args (map (cut walk <> #f rw pass2?) subs))) + ;; rewrite inline operation to unboxed one, if possible + (cond ((not rw) #f) + ((or (not pass2?) + (and dest (unboxed? dest)) + (any unboxed-value? args)) + (let ((alt (first rw)) + (atypes (second rw)) + (rtype (third rw))) + ;; result or arguments are unboxed - rewrite node to alternative + (when pass2? + (rewrite! + n alt subs args atypes rtype + (and dest (assq dest e)))) + (cons #f rtype)) ) + (else + (let ((rtype (third rw))) + ;; mark argument-vars and dest as unboxed if alternative exists + (unless pass2? + (for-each + (lambda (a) + (when (and a (car a) (cdr a)) + (unboxed! (car a) (cdr a)))) + args) + (when dest + (unboxed! dest rtype))) + (cons #f rtype)))))) + + ((let) + (let* ((v (first params)) + (r1 (walk (first subs) v #t pass2?))) + (when (and (not pass2?) r1 (cdr r1)) + (unboxed! (first params) (cdr r1))) + (let ((r (walk (second subs) dest udest pass2?))) - (when pass2? + (let ((a (assq v e))) + (if (and a (cdr a)) + (rebind-unboxed! n (cdr a)) + (straighten-binding! n))) ) + r))) + + ((set!) + (let* ((var (first params)) + (a (assq var e)) + (val (walk (first subs) var (and a (cdr a)) pass2?))) + (cond (pass2? + (when (and a (cdr a)) ; may have mutated + (copy-node! + (make-node + '##core#unboxed_set! (list (alias var) (cdr a)) subs) + n))) + ((and val (cdr val)) + (unboxed! var (cdr val))) + (else + (boxed! var) + (invalidate val) ) ) + #f)) + + ((quote) #f) + + ((if ##core#cond) + (invalidate (walk (first subs) #f #f pass2?)) + (straighten-conditional! n) + (let ((r1 (walk (second subs) dest udest pass2?)) + (r2 (walk (third subs) dest udest pass2?))) + (merge r1 r2))) + + ((##core#switch) + (invalidate (walk (first subs) #f #f pass2?)) + (do ((clauses (cdr subs) (cddr clauses)) + (r 'none + (if (eq? r 'none) + (walk (second clauses) dest udest pass2?) + (merge r (walk (second clauses) dest udest pass2?))))) + ((null? (cdr clauses)) + (merge r (walk (car clauses) dest udest pass2?))) ) ) + + ((##core#call ##core#direct_call) + (for-each (o invalidate (cut walk <> #f #f pass2?)) subs) + (when pass2? + (straighten-call! n)) + #f) + + (else + (for-each (o invalidate (cut walk <> #f #f pass2?)) subs) + #f)))) + (set! d-depth (sub1 d-depth)) + result))) + + (d "walk lambda: ~a (pass 1)" id) + ;; walk once and mark boxed/unboxed variables in environment (walk body #f #f #f) + ;; walk a second time and rewrite + (d "walk lambda: ~a (pass 2)" id) (walk body #f #f #t))) + + ;;XXX Note: lexical references ("##core#ref" nodes) are unboxed + ;; repeatedly which is sub-optimal: the unboxed temporaries bound + ;; via "##core#let_unboxed" could be re-used in many cases. + ;; One possible approach would be an additional "cleanup" pass + ;; that replaces + ;; + ;; (##core#let_unboxed (TU TYPE) X (##core#ref VAR (SLOT)) Y) + ;; + ;; with + ;; + ;; (##core#let_unboxed (TU TYPE) (##core#unboxed_ref TU1) Y) (walk-lambda #f '() node) (when (and any-rewritesTrap