3

I'd like some help in understanding and fixing an SBCL compiler note that says:

; in: DEFUN PRINT-SEARCH-PROGRESS-GRAPH
;     (- (1+ WOULDWORK-PKG::*N*)
;        (LENGTH WOULDWORK-PKG::*L*))
;
; note: doing signed word to integer coercion (cost 20), for:
;       the first result of inline (signed-byte 64) arithmetic

Some possibly relevant background info:

(optimize (debug 3))

(defparameter *N* 0)
(declaim (fixnum *N*))
    
(defparameter *L* nil)
(declaim (list *L*))
    
(type-of *N*) => BIT
Barmar
  • 741,623
  • 53
  • 500
  • 612
davypough
  • 1,847
  • 11
  • 21

1 Answers1

4

You declared *N* to be a FIXNUM, which is a fixed-size integer; it's equivalent to (SIGNED-BYTE 64) in 64-bit SBCL. But if its value happens to be MOST-POSITIVE-FIXNUM, (1+ *n*) could produce a value that's doesn't fit in 64 bits, so it will have to convert to INTEGER. The note is warning you that this conversion may take place.

If you know that it will never be so high that this overflow will be necessary, you can use THE:

(- (the fixnum (1+ *n*)) (length *l*))
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Regarding the first fix, the variable `*N*` needs to be a `fixnum` because I'm declaring it with `sb-ext:defglobal` to enable parallel updating. As for the second fix using "the fixnum", I get the same compiler note as before. – davypough Feb 14 '23 at 23:46
  • 1
    It's probably because `(length *l*)` has no reason to be a fixnum (hence, the subtraction probably has to be the "generic" one). Moreover, subtracting two fixnums might still result in a "bignum": - you can wrap every expression in `(the fixnum ...)` - or you declare (possibly locally) what you know, *e.g.* `(declare (type (integer 0 42) *N*))` if you know the precise bounds of `*N*` - in general, write the rest of the program, and profile to see if this ONE operation is relevant to performance at all. – Numbra Feb 15 '23 at 07:23
  • 1
    Yes, it looks like there's the potential for exceeding the most-negative-fixnum too. Moving "the fixnum" to the front of the expression works, evidently because sbcl can then figure out the internal expressions. Appreciate the insights. – davypough Feb 15 '23 at 14:02
  • @Numbra: in fact in 64-bit SBCL (and I am sure in 32-bit as well) `length` must return a fixnum, and SBCL knows this (the longest possible list has a length which is a fixnum, and `array-dimension-limit` is a fixnum. – ignis volens Feb 20 '23 at 16:41