#| -*-Scheme-*-
-$Id: declar.scm,v 1.10 2007/01/05 21:19:20 cph Exp $
+$Id: declar.scm,v 1.11 2007/04/14 22:00:09 riastradh Exp $
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
(declare (usual-integrations))
\f
-(define (process-top-level-declarations! block declarations)
+;;; A block's declarations are processed in two phases: before and
+;;; after the flow graph is generated for the block's children. See
+;;; GENERATE/BODY in fggen/fggen.scm. Some declarations need to refer
+;;; to information about variables bound by the block, so they use
+;;; post-declarations; others need to establish information that the
+;;; children can inherit from, so they use pre-declarations.
+
+(define (process-top-level-declarations! block declarations handlers)
(process-declarations!
block
(let loop
(loop (if (assq (caar defaults) declarations)
declarations
(cons (car defaults) declarations))
- (cdr defaults))))))
+ (cdr defaults))))
+ handlers))
-(define (process-declarations! block declarations)
+(define (process-declarations! block declarations handlers)
(for-each (lambda (declaration)
- (process-declaration! block declaration))
+ (process-declaration! block declaration handlers))
declarations))
-(define (process-declaration! block declaration)
- (let ((entry (assq (car declaration) known-declarations)))
+(define (process-declaration! block declaration handlers)
+ (let ((entry (assq (car declaration) handlers)))
(if entry
((cdr entry) block (car declaration) (cdr declaration))
(warn "Unknown declaration name" (car declaration)))))
-(define known-declarations
- '())
-
-(define (define-declaration keyword handler)
- (let ((entry (assq keyword known-declarations)))
- (if entry
- (set-cdr! entry handler)
- (set! known-declarations
- (cons (cons keyword handler)
- known-declarations))))
- keyword)
+(define (declaration-processor get-handlers)
+ (lambda (block declarations)
+ (process-top-level-declarations! block declarations (get-handlers))))
+
+(define (declaration-definer get-handlers set-handlers!)
+ (lambda (keyword handler)
+ (let ((handlers (get-handlers)))
+ (cond ((assq keyword handlers)
+ => (lambda (entry)
+ (set-cdr! entry handler)))
+ (else
+ (set-handlers! (cons (cons keyword handler) handlers)))))
+ keyword))
+
+(define pre-declarations '())
+(define post-declarations '())
+
+(define process-pre-declarations!
+ (declaration-processor (lambda () pre-declarations)))
+
+(define process-post-declarations!
+ (declaration-processor (lambda () post-declarations)))
+
+(define define-pre-declaration
+ (declaration-definer (lambda () pre-declarations)
+ (lambda (handlers) (set! pre-declarations handlers))))
+
+(define define-post-declaration
+ (declaration-definer (lambda () post-declarations)
+ (lambda (handlers) (set! post-declarations handlers))))
+
+(define (define-pre-only-declaration keyword handler)
+ (define-pre-declaration keyword handler)
+ (define-post-declaration keyword ignored-declaration))
+
+(define (define-post-only-declaration keyword handler)
+ (define-pre-declaration keyword ignored-declaration)
+ (define-post-declaration keyword handler))
+
+(define ignored-declaration
+ (lambda (block keyword parameters)
+ block keyword parameters ;ignore
+ unspecific))
\f
(package (boolean-variable-property)
)
-(define-declaration 'UUO-LINK boolean-variable-property)
-(define-declaration 'CONSTANT boolean-variable-property)
-(define-declaration 'IGNORE-REFERENCE-TRAPS boolean-variable-property)
-(define-declaration 'IGNORE-ASSIGNMENT-TRAPS boolean-variable-property)
-(define-declaration 'USUAL-DEFINITION boolean-variable-property)
-(define-declaration 'SIDE-EFFECT-FREE boolean-variable-property)
-(define-declaration 'PURE-FUNCTION boolean-variable-property)
\ No newline at end of file
+(define-post-only-declaration 'UUO-LINK boolean-variable-property)
+(define-post-only-declaration 'CONSTANT boolean-variable-property)
+(define-post-only-declaration 'IGNORE-REFERENCE-TRAPS
+ boolean-variable-property)
+(define-post-only-declaration 'IGNORE-ASSIGNMENT-TRAPS
+ boolean-variable-property)
+(define-post-only-declaration 'USUAL-DEFINITION boolean-variable-property)
+(define-post-only-declaration 'SIDE-EFFECT-FREE boolean-variable-property)
+(define-post-only-declaration 'PURE-FUNCTION boolean-variable-property)
+\f
+;;;; Safety Check Declarations
+
+(let ()
+ (define (check-property block-checks set-block-checks! enable?)
+ (lambda (block keyword primitives)
+ keyword ;ignore
+ (set-block-checks!
+ block
+ (let ((checks (block-checks block)))
+ (if (null? primitives)
+ enable?
+ (if (boolean? checks)
+ (if (eqv? checks enable?)
+ checks
+ (if enable?
+ (list checks primitives '())
+ (list checks '() primitives)))
+ (let ((default (car checks))
+ (do-check (cadr checks))
+ (dont-check (caddr checks)))
+ (if enable?
+ (list default
+ (eq-set-adjoin primitives do-check)
+ dont-check)
+ (list default
+ do-check
+ (eq-set-adjoin primitives dont-check))))))))))
+ (define-pre-only-declaration 'TYPE-CHECKS
+ (check-property block-type-checks set-block-type-checks! #t))
+ (define-pre-only-declaration 'NO-TYPE-CHECKS
+ (check-property block-type-checks set-block-type-checks! #f))
+ (define-pre-only-declaration 'RANGE-CHECKS
+ (check-property block-range-checks set-block-range-checks! #t))
+ (define-pre-only-declaration 'NO-RANGE-CHECKS
+ (check-property block-range-checks set-block-range-checks! #f)))
#| -*-Scheme-*-
-$Id: opncod.scm,v 4.79 2007/03/28 02:29:24 riastradh Exp $
+$Id: opncod.scm,v 4.80 2007/04/14 22:00:09 riastradh Exp $
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
(define (try-handler combination primitive entry)
(let ((operands (combination/operands combination)))
(and (primitive-arity-correct? primitive (length operands))
- (with-values (lambda () ((vector-ref entry 0) operands))
- (lambda (generator indices internal-close-coding?)
- (and generator
- (make-inliner entry
- generator
- indices
- (if (boolean? internal-close-coding?)
- internal-close-coding?
- (internal-close-coding?)))))))))
+ (receive (generator indices internal-close-coding?)
+ ((vector-ref entry 0) operands
+ primitive
+ (combination/block combination))
+ (and generator
+ (make-inliner entry
+ generator
+ indices
+ (if (boolean? internal-close-coding?)
+ internal-close-coding?
+ (internal-close-coding?
+ primitive
+ (combination/block combination)))))))))
\f
;;;; Code Generator
;;;; Operand Filters
(define (simple-open-coder generator operand-indices internal-close-coding?)
- (lambda (operands)
- operands
+ (lambda (operands primitive block)
+ operands primitive block
(values generator operand-indices internal-close-coding?)))
(define (conditional-open-coder predicate open-coder)
- (lambda (operands)
- (if (predicate operands)
- (open-coder operands)
+ (lambda (operands primitive block)
+ (if (predicate operands primitive block)
+ (open-coder operands primitive block)
(values false '() false))))
(define (constant-filter predicate)
(lambda (generator constant-index operand-indices internal-close-coding?)
- (lambda (operands)
+ (lambda (operands primitive block)
+ primitive block ;ignore
(let ((operand (rvalue-known-value (list-ref operands constant-index))))
(if (and operand
(rvalue/constant? operand)
(and (exact-nonnegative-integer? operand)
(back-end:< operand scheme-type-limit)))))
-(define (internal-close-coding-for-type-checks)
- compiler:generate-type-checks?)
+(define (internal-close-coding-for-type-checks primitive block)
+ (block/generate-type-checks? block primitive))
-(define (internal-close-coding-for-range-checks)
- compiler:generate-range-checks?)
+(define (internal-close-coding-for-range-checks primitive block)
+ (block/generate-range-checks? block primitive))
-(define (internal-close-coding-for-type-or-range-checks)
- (or compiler:generate-type-checks?
- compiler:generate-range-checks?))
+(define (internal-close-coding-for-type-or-range-checks primitive block)
+ (or (block/generate-type-checks? block primitive)
+ (block/generate-range-checks? block primitive)))
\f
;;;; Constraint Checkers
continuation-label
primitive))))
\f
-(define (open-code:type-check expression type)
- (if (and type compiler:generate-type-checks?)
+(define (open-code:type-check expression type primitive block)
+ (if (and type
+ (block/generate-type-checks? block primitive))
(generate-type-test type
expression
make-false-pcfg
;; This is not reasonable since the port may not include such open codings.
#|
-(define (open-code:range-check index-expression limit-locative)
- (cond ((and limit-locative compiler:generate-range-checks?)
+(define (open-code:range-check index-expression limit-locative
+ primitive block)
+ (cond ((and limit-locative (block/generate-range-checks? block primitive))
(pcfg/prefer-consequent!
(rtl:make-fixnum-pred-2-args
'UNSIGNED-LESS-THAN-FIXNUM?
(make-true-pcfg))))
|#
-(define (open-code:index-check index-expression limit-locative)
+(define (open-code:index-check index-expression limit-locative
+ primitive block)
(cond ((not limit-locative)
- (open-code:index-fixnum-check index-expression))
- (compiler:generate-range-checks?
+ (open-code:index-fixnum-check index-expression primitive block))
+ ((block/generate-range-checks? block primitive)
(pcfg*pcfg->pcfg!
- (open-code:type-check index-expression (ucode-type fixnum))
+ (open-code:type-check index-expression (ucode-type fixnum)
+ primitive block)
(pcfg/prefer-consequent!
(rtl:make-fixnum-pred-2-args
'UNSIGNED-LESS-THAN-FIXNUM?
(rtl:make-object->fixnum index-expression)
(rtl:make-object->fixnum limit-locative)))
(make-false-pcfg)))
- (compiler:generate-type-checks?
- (open-code:type-check index-expression (ucode-type fixnum)))
+ ((block/generate-type-checks? block primitive)
+ (open-code:type-check index-expression (ucode-type fixnum)
+ primitive block))
(else
(make-true-pcfg))))
-(define (open-code:nonnegative-check expression)
- (if compiler:generate-range-checks?
+(define (open-code:nonnegative-check expression primitive block)
+ (if (block/generate-range-checks? block primitive)
(generate-nonnegative-check expression)
(make-true-pcfg)))
'NEGATIVE-FIXNUM?
(rtl:make-object->fixnum expression))))))
-(define (open-code:index-fixnum-check expression)
- (if (or compiler:generate-range-checks?
- compiler:generate-type-checks?)
+(define (open-code:index-fixnum-check expression primitive block)
+ (if (or (block/generate-range-checks? block primitive)
+ (block/generate-type-checks? block primitive))
(generate-index-fixnum-check expression)
(make-true-pcfg)))
(index (cadr expressions)))
(open-code:with-checks
combination
- (cons*
- (open-code:type-check object base-type)
- (open-code:index-check index (length-expression object))
- (if value-type
- (list (open-code:type-check (caddr expressions) value-type))
- '()))
+ (let ((block (combination/block combination)))
+ (cons*
+ (open-code:type-check object base-type name block)
+ (open-code:index-check index (length-expression object) name block)
+ (if value-type
+ (list (open-code:type-check (caddr expressions)
+ value-type
+ name
+ block))
+ '())))
(index-locative object index
(lambda (locative)
(generator locative expressions finish)))
false))
\f
(define-open-coder/predicate 'OBJECT-TYPE?
- (lambda (operands)
+ (lambda (operands primitive block)
+ primitive block ;ignore
(let ((operand (rvalue-known-value (car operands))))
(if (and operand
(rvalue/constant? operand)
(object (cadr expressions)))
(open-code:with-checks
combination
- (list
- (open-code:index-check type
- (rtl:make-constant
- scheme-type-limit)))
+ (list (open-code:index-check
+ type
+ (rtl:make-constant scheme-type-limit)
+ 'OBJECT-TYPE?
+ (combination/block combination)))
(finish
(rtl:make-eq-test (rtl:make-object->datum type)
(rtl:make-object->type object)))
(let ((mask (car expressions)))
(open-code:with-checks
combination
- (list (open-code:type-check mask (ucode-type fixnum)))
+ (list (open-code:type-check mask
+ (ucode-type fixnum)
+ 'SET-INTERRUPT-ENABLES!
+ (combination/block combination)))
(let ((assignment
(rtl:make-assignment register:int-mask
(rtl:make-object->datum mask))))
(let ((length (car expressions)))
(open-code:with-checks
combination
- (list (open-code:index-fixnum-check length))
+ (list (open-code:index-fixnum-check length
+ 'PRIMITIVE-INCREMENT-FREE
+ (combination/block combination)))
(let ((assignment
((index-locative-generator rtl:locative-object-offset
rtl:locative-object-index
(let ((length (car expressions)))
(open-code:with-checks
combination
- (list (open-code:index-fixnum-check length))
+ (list (open-code:index-fixnum-check length
+ 'HEAP-AVAILABLE?
+ (combination/block combination)))
((index-locative-generator rtl:locative-object-offset
rtl:locative-object-index
0
(filter/type-code open-code/pair-cons 0 '(1 2) false)))
(define-open-coder/value 'VECTOR
- (lambda (operands)
+ (lambda (operands primitive block)
+ primitive block ;ignore
(if (< (length operands) 32)
(values (lambda (combination expressions finish)
combination
(values false false false))))
(define-open-coder/value '%RECORD
- (lambda (operands)
+ (lambda (operands primitive block)
+ primitive block ;ignore
(if (< 1 (length operands) 32)
(values (lambda (combination expressions finish)
combination
(let ((length (car expressions)))
(open-code:with-checks
combination
- (list (open-code:nonnegative-check length))
+ (list (open-code:nonnegative-check length
+ 'STRING-ALLOCATE
+ (combination/block combination)))
(scfg*scfg->scfg!
(finish
(rtl:make-typed-cons:string
(let ((length (car expressions)))
(open-code:with-checks
combination
- (list (open-code:index-fixnum-check length)
+ (list (open-code:index-fixnum-check length
+ name
+ (combination/block combination))
(make-false-pcfg))
(make-null-cfg)
finish
(let ((expression (car expressions)))
(open-code:with-checks
combination
- (list (open-code:type-check expression type))
+ (list (open-code:type-check expression
+ type
+ name
+ (combination/block combination)))
(finish (make-fetch (rtl:locative-offset expression index)))
finish
name
(let ((object (car expressions)))
(open-code:with-checks
combination
- (list (open-code:type-check object type))
+ (list (open-code:type-check object
+ type
+ name
+ (combination/block combination)))
(finish-vector-assignment (rtl:locative-offset object index)
(cadr expressions)
finish)
(length (cadr expressions)))
(open-code:with-checks
combination
- (list (open-code:type-check object (ucode-type string))
- (open-code:index-fixnum-check length))
+ (let ((name 'SET-STRING-LENGTH!)
+ (block (combination/block combination)))
+ (list (open-code:type-check object (ucode-type string) name block)
+ (open-code:index-fixnum-check length name block)))
(finish-vector-assignment (rtl:locative-offset object 1)
(rtl:make-object->datum length)
finish)
(define-open-coder/value 'INTEGER->CHAR
(conditional-open-coder
- (lambda (operands)
+ (lambda (operands primitive block)
operands
- (not compiler:generate-range-checks?))
+ (not (block/generate-range-checks? block primitive)))
(simple-open-coder
(lambda (combination expressions finish)
(let ((arg (car expressions)))
(open-code:with-checks
combination
- (list (open-code:type-check arg (ucode-type fixnum)))
+ (list (open-code:type-check arg
+ (ucode-type fixnum)
+ 'INTEGER->CHAR
+ (combination/block combination)))
(finish
(rtl:make-cons-non-pointer
(rtl:make-machine-constant (ucode-type character))
(let ((char (car expressions)))
(open-code:with-checks
combination
- (list (open-code:type-check char (ucode-type character)))
+ (list (open-code:type-check char
+ (ucode-type character)
+ 'CHAR->INTEGER
+ (combination/block combination)))
(finish
(rtl:make-cons-non-pointer
(rtl:make-machine-constant (ucode-type fixnum))
(define (floating-point-open-coder generator indices internal-close-coding?)
(conditional-open-coder
- (lambda (operands)
- operands ; ignored
+ (lambda (operands primitive block)
+ operands primitive block ; ignored
compiler:open-code-floating-point-arithmetic?)
(simple-open-coder generator indices internal-close-coding?)))
(let ((argument (car expressions)))
(open-code:with-checks
combination
- (list (open-code:type-check argument (ucode-type flonum)))
+ (list (open-code:type-check argument
+ (ucode-type flonum)
+ flonum-operator
+ (combination/block combination)))
(finish (rtl:make-float->object
(rtl:make-flonum-1-arg
flonum-operator
(arg2 (cadr expressions)))
(open-code:with-checks
combination
- (list (open-code:type-check arg1 (ucode-type flonum))
- (open-code:type-check arg2 (ucode-type flonum)))
+ (let ((name flonum-operator)
+ (block (combination/block combination)))
+ (list (open-code:type-check arg1 (ucode-type flonum) name block)
+ (open-code:type-check arg2 (ucode-type flonum) name block)))
(finish
(rtl:make-float->object
(rtl:make-flonum-2-args
(let ((argument (car expressions)))
(open-code:with-checks
combination
- (list (open-code:type-check argument (ucode-type flonum)))
+ (list (open-code:type-check argument
+ (ucode-type flonum)
+ flonum-pred
+ (combination/block combination)))
(finish
(rtl:make-flonum-pred-1-arg
flonum-pred
(arg2 (cadr expressions)))
(open-code:with-checks
combination
- (list (open-code:type-check arg1 (ucode-type flonum))
- (open-code:type-check arg2 (ucode-type flonum)))
+ (let ((name flonum-pred)
+ (block (combination/block combination)))
+ (list (open-code:type-check arg1 (ucode-type flonum) name block)
+ (open-code:type-check arg2 (ucode-type flonum) name block)))
(finish (rtl:make-flonum-pred-2-args
flonum-pred
(rtl:make-object->float arg1)