\f
;;; Entry points.
+(defun comp-cstr-imm-vld-p (cstr)
+ "Return t if one and only one immediate value can be extracted from CSTR."
+ (with-comp-cstr-accessors
+ (when (and (null (typeset cstr))
+ (null (neg cstr)))
+ (let* ((v (valset cstr))
+ (r (range cstr))
+ (valset-len (length v))
+ (range-len (length r)))
+ (if (and (= valset-len 1)
+ (= range-len 0))
+ t
+ (when (and (= valset-len 0)
+ (= range-len 1))
+ (let* ((low (caar r))
+ (high (cdar r)))
+ (and (integerp low)
+ (integerp high)
+ (= low high)))))))))
+
+(defun comp-cstr-imm (cstr)
+ "Return the immediate value of CSTR.
+`comp-cstr-imm-vld-p' *must* be satisfied before calling
+`comp-cstr-imm'."
+ (declare (gv-setter
+ (lambda (val)
+ `(with-comp-cstr-accessors
+ (if (integerp ,val)
+ (setf (typeset ,cstr) nil
+ (range ,cstr) (list (cons ,val ,val)))
+ (setf (typeset ,cstr) nil
+ (valset ,cstr) (list ,val)))))))
+ (with-comp-cstr-accessors
+ (let ((v (valset cstr)))
+ (if (= (length v) 1)
+ (car v)
+ (caar (range cstr))))))
+
+(defun comp-cstr-fixnum-p (cstr)
+ "Return t if CSTR is certainly a fixnum."
+ (with-comp-cstr-accessors
+ (when (null (neg cstr))
+ (when-let (range (range cstr))
+ (let* ((low (caar range))
+ (high (cdar (last range))))
+ (unless (or (eq low '-)
+ (< low most-negative-fixnum)
+ (eq high '+)
+ (> high most-positive-fixnum))
+ t))))))
+
+(defun comp-cstr-symbol-p (cstr)
+ "Return t if CSTR is certainly a symbol."
+ (with-comp-cstr-accessors
+ (and (null (range cstr))
+ (null (neg cstr))
+ (or (and (null (valset cstr))
+ (equal (typeset cstr) '(symbol)))
+ (and (or (null (typeset cstr))
+ (equal (typeset cstr) '(symbol)))
+ (cl-every #'symbolp (valset cstr)))))))
+
+(defsubst comp-cstr-cons-p (cstr)
+ "Return t if CSTR is certainly a cons."
+ (with-comp-cstr-accessors
+ (and (null (valset cstr))
+ (null (range cstr))
+ (null (neg cstr))
+ (equal (typeset cstr) '(cons)))))
+
(defun comp-cstr-> (dst old-dst src)
"Constraint DST being > than SRC.
SRC can be either a comp-cstr or an integer."
:documentation "Slot number in the array if a number or
'scratch' for scratch slot."))
-(defun comp-mvar-value-vld-p (mvar)
- "Return t if one single value can be extracted by the MVAR constrains."
- (when (and (null (comp-mvar-typeset mvar))
- (null (comp-mvar-neg mvar)))
- (let* ((v (comp-mvar-valset mvar))
- (r (comp-mvar-range mvar))
- (valset-len (length v))
- (range-len (length r)))
- (if (and (= valset-len 1)
- (= range-len 0))
- t
- (when (and (= valset-len 0)
- (= range-len 1))
- (let* ((low (caar r))
- (high (cdar r)))
- (and (integerp low)
- (integerp high)
- (= low high))))))))
-
-;; FIXME move these into cstr?
-
-(defun comp-mvar-value (mvar)
- "Return the constant value of MVAR.
-`comp-mvar-value-vld-p' *must* be satisfied before calling
-`comp-mvar-const'."
- (declare (gv-setter
- (lambda (val)
- `(if (integerp ,val)
- (setf (comp-mvar-typeset ,mvar) nil
- (comp-mvar-range ,mvar) (list (cons ,val ,val)))
- (setf (comp-mvar-typeset ,mvar) nil
- (comp-mvar-valset ,mvar) (list ,val))))))
- (let ((v (comp-mvar-valset mvar)))
- (if (= (length v) 1)
- (car v)
- (caar (comp-mvar-range mvar)))))
-
-(defun comp-mvar-fixnum-p (mvar)
- "Return t if MVAR is certainly a fixnum."
- (when (null (comp-mvar-neg mvar))
- (when-let (range (comp-mvar-range mvar))
- (let* ((low (caar range))
- (high (cdar (last range))))
- (unless (or (eq low '-)
- (< low most-negative-fixnum)
- (eq high '+)
- (> high most-positive-fixnum))
- t)))))
-
-(defun comp-mvar-symbol-p (mvar)
- "Return t if MVAR is certainly a symbol."
- (and (null (comp-mvar-range mvar))
- (null (comp-mvar-neg mvar))
- (or (and (null (comp-mvar-valset mvar))
- (equal (comp-mvar-typeset mvar) '(symbol)))
- (and (or (null (comp-mvar-typeset mvar))
- (equal (comp-mvar-typeset mvar) '(symbol)))
- (cl-every #'symbolp (comp-mvar-valset mvar))))))
-
-(defsubst comp-mvar-cons-p (mvar)
- "Return t if MVAR is certainly a cons."
- (and (null (comp-mvar-valset mvar))
- (null (comp-mvar-range mvar))
- (null (comp-mvar-neg mvar))
- (equal (comp-mvar-typeset mvar) '(cons))))
-
(defun comp-mvar-type-hint-match-p (mvar type-hint)
"Match MVAR against TYPE-HINT.
In use by the backend."
(cl-ecase type-hint
- (cons (comp-mvar-cons-p mvar))
- (fixnum (comp-mvar-fixnum-p mvar))))
+ (cons (comp-cstr-cons-p mvar))
+ (fixnum (comp-cstr-fixnum-p mvar))))
\f
(let ((mvar (make--comp-mvar :slot slot)))
(when const-vld
(comp-add-const-to-relocs constant)
- (setf (comp-mvar-value mvar) constant))
+ (setf (comp-cstr-imm mvar) constant))
(when type
(setf (comp-mvar-typeset mvar) (list type)))
mvar))
kind)))
(push `(assume ,(make-comp-mvar :slot lhs-slot)
(,kind ,lhs
- ,(if-let* ((vld (comp-mvar-value-vld-p rhs))
- (val (comp-mvar-value rhs))
+ ,(if-let* ((vld (comp-cstr-imm-vld-p rhs))
+ (val (comp-cstr-imm rhs))
(ok (integerp val)))
val
(make-comp-mvar :slot (comp-mvar-slot rhs)))))
for insn in (comp-block-insns b)
do (pcase insn
(`(setimm ,lval ,v)
- (setf (comp-mvar-value lval) v))))))
+ (setf (comp-cstr-imm lval) v))))))
(defun comp-mvar-propagate (lval rval)
"Propagate into LVAL properties of RVAL."
(defun comp-function-foldable-p (f args)
"Given function F called with ARGS return non-nil when optimizable."
(and (comp-function-pure-p f)
- (cl-every #'comp-mvar-value-vld-p args)))
+ (cl-every #'comp-cstr-imm-vld-p args)))
(defun comp-function-call-maybe-fold (insn f args)
"Given INSN when F is pure if all ARGS are known remove the function call.
(cond
((eq f 'symbol-value)
(when-let* ((arg0 (car args))
- (const (comp-mvar-value-vld-p arg0))
- (ok-to-optim (member (comp-mvar-value arg0)
+ (const (comp-cstr-imm-vld-p arg0))
+ (ok-to-optim (member (comp-cstr-imm arg0)
comp-symbol-values-optimizable)))
- (rewrite-insn-as-setimm insn (symbol-value (comp-mvar-value
+ (rewrite-insn-as-setimm insn (symbol-value (comp-cstr-imm
(car args))))))
((comp-function-foldable-p f args)
(ignore-errors
;; and know to be pure.
(comp-func-byte-func f-in-ctxt)
f))
- (value (comp-apply-in-env f (mapcar #'comp-mvar-value args))))
+ (value (comp-apply-in-env f (mapcar #'comp-cstr-imm args))))
(rewrite-insn-as-setimm insn value)))))))
(defun comp-fwprop-call (insn lval f args)
Fold the call in case."
(unless (comp-function-call-maybe-fold insn f args)
(when (and (eq 'funcall f)
- (comp-mvar-value-vld-p (car args)))
- (setf f (comp-mvar-value (car args))
+ (comp-cstr-imm-vld-p (car args)))
+ (setf f (comp-cstr-imm (car args))
args (cdr args)))
(when-let ((cstr-f (gethash f comp-known-func-cstr-h)))
(let ((cstr (comp-cstr-f-ret cstr-f)))
(<=
(comp-cstr-<= lval (car operands) (cadr operands)))))
(`(setimm ,lval ,v)
- (setf (comp-mvar-value lval) v))
+ (setf (comp-cstr-imm lval) v))
(`(phi ,lval . ,rest)
(let* ((from-latch (cl-some
(lambda (x)
(pcase insn
(`(set ,lval (callref funcall ,f . ,rest))
(when-let ((new-form (comp-call-optim-form-call
- (comp-mvar-value f) rest)))
+ (comp-cstr-imm f) rest)))
(setf insn `(set ,lval ,new-form))))
(`(callref funcall ,f . ,rest)
(when-let ((new-form (comp-call-optim-form-call
- (comp-mvar-value f) rest)))
+ (comp-cstr-imm f) rest)))
(setf insn new-form)))))))
(defun comp-call-optim (_)
,(comp-cstr-to-type-spec res-mvar))))
(comp-add-const-to-relocs type)
;; Fix it up.
- (setf (comp-mvar-value (comp-func-type func)) type))))
+ (setf (comp-cstr-imm (comp-func-type func)) type))))
(defun comp-finalize-container (cont)
"Finalize data container CONT."