From: danb
Subject: Deleting un(?)reachable code
Date: 
Message-ID: <164b76f3-97cb-4edd-bab8-68e4908c9937@p73g2000hsd.googlegroups.com>
Does anyone have any idea why sbcl would delete these
code segments?  There are three FORMAT forms and one
CDR form.

The FORMATs occur in an inlined function (USABLE), and are
called conditionally, depending on the value of an optional arg
(TESTING).  I understand that the conditional calls can be elim-
inated for any call to the inline function that doesn't specify
a value for the condition, which defaults to nil.  But there's
still some strangeness left over:

1.  Why does the compiler single out the format strings as
    being the unreachable part?
2.  Why aren't the PAUSE forms eliminated, since they're in
    the same WHEN forms as the FORMATs?
3.  Why is the (cdr cell) form that's called inside the
      (while (cdr cell) ...) form eliminated?  An obvious thought
    would be that I got the test backwards in WHILE, but it's tested
    and seems to work.  The conditional test in WHILE is
      (unless ,test (return-from ,block))
    I don't see how that could be wrong.

(compiler output & code snippets below;
affected code is under-careted)

--Dan

Compiler output:

; in: DEF-INLINE USABLE
;     (FORMAT T "n-div = ~D. " PANPAL::N-DIV)
; ==> "n-div = ~D. "
; note: deleting unreachable code
;     (FORMAT T "~A is usable.~%" PANPAL::WORD)
; ==> "~A is usable.~%"
; note: deleting unreachable code
;     (FORMAT T "~A is not usable.~%" PANPAL::WORD)
; ==> "~A is not usable.~%"
; note: deleting unreachable code

; in: DEF TRIM-WORDS
;     (CDR PANPAL::CELL)
; ==> PANPAL::CELL
; note: deleting unreachable code

Code snippets:

(def-inline usable (word fortree baktree &optional verbose)
  ...
  (dotimes (n-div (1- num-chars))
    (when verbose
      (format t "n-div = ~D. " n-div)
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      (pause "try-subs<RTRN>"))
    (when (try-subs n-div)
      (when verbose
        (format t "~A is usable.~%" word)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        (pause "return-from usable."))
      (return-from usable t)))
  (when verbose
    (format t "~A is not usable.~%" word)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    (pause "End usable."))
  nil)))

...
(while (cdr cell)
  (let* ((wrd (cadr cell))
         (ok (usable wrd fortree baktree)))
    (cond
      (ok (setf cell (cdr cell))) ;move down the list
                     ^^^^^^^^^^
      (t  (setf (cdr cell) (cddr cell)) ;delete the wrd
          (delete-wrd wrd fortree baktree)))))

------------------------------------------------
Dan Bensen
http://www.prairienet.org/~dsb/

From: Kaz Kylheku
Subject: Re: Deleting un(?)reachable code
Date: 
Message-ID: <f6f4ecea-2496-49e0-8432-0e7878666f75@x30g2000hsd.googlegroups.com>
On Mar 17, 6:53 pm, danb <·········@gmail.com> wrote:
> 1.  Why does the compiler single out the format strings as
>     being the unreachable part?

Here are some wild-assed guesses:

Format strings can be compiled to code. Are you familiar with the
FORMATTER macro? Since it makes sense for format strings to be code,
it makes sense for them to be reported as unreachable code when that
is the case.

> 2.  Why aren't the PAUSE forms eliminated, since they're in
>     the same WHEN forms as the FORMATs?

Perhaps when an entire subtree of the code is eliminated, the compiler
reports a diagnostic about just one of the constituents, rather than
for every node. That is to say, given the function call (A B C), if (A
B C) itself is unreachable, then of course B is unreachable and so is
C. This could be reported as three messages, but that would be
annoying. Reporting that (A B C) is unreachable would be best, but
perhaps there are code generation algorithms where it's not convenient
to do it this way. Suppose that reachability is not computed on Lisp
forms but on a transformed representation of the program (which has
association to the original Lisp forms for reporting diagnostics
only). Translated code for (A B C) might do something like: ``evaluate
B to a temporary location T1; evaluate C to a temporary location T2;
evaluate function binding of A to a temporary location T3, do the
function call (T3 T1 T2). Now suppose that this whole block is
eliminated as unreachable code. What do you report on? The obvious
thing is to pull out the first instruction: ``evaluate B to a
temporary location T1''. So it is B that is used in the diagnostic.

> ...
> (while (cdr cell)

Are you sure it is not /this/ (CDR CELL) that is unreachable? Maybe
the entire WHILE is unreachable. You have three occurences of (CDR
CELL) in this form, and no line number is given in the diagnostic to
pinpoint which one.

Idea: change the spelling to (REST CELL) of each one of these one by
one in turn to see how the compiler message changes. :)
From: danb
Subject: Re: Deleting un(?)reachable code
Date: 
Message-ID: <00ffcccf-32ee-46b8-915f-441a64728214@8g2000hsu.googlegroups.com>
> On Mar 17, 6:53 pm, danb <·········@gmail.com> wrote:
> > 1.  Why does the compiler single out the format strings
> >     as being the unreachable part?

On Mar 17, 11:41 pm, Kaz Kylheku <········@gmail.com> wrote:
> Format strings can be compiled to code. Are you familiar
> with the FORMATTER macro?
No, and FORMAT is a function, so I still don't understand
why the format strings were singled out for special treatment.

> > 2.  Why aren't the PAUSE forms eliminated, since they're
> >     in the same WHEN forms as the FORMATs?

> Perhaps when an entire subtree of the code is eliminated,
> the compiler reports a diagnostic about just one of the
> constituents,
Assuming you mean the *first* constituent, that sounds
reasonable.

> > (while (cdr cell)

> Are you sure it is not /this/ (CDR CELL) that is unreachable?
I'm sure it's not the one that slime underlined.
However, I have seen strangely placed messages from
slime before.

> Maybe the entire WHILE is unreachable.
That's a good point if slime put the message in the
wrong spot.  I still don't see any other bugs though.
Anyway, the whole thing just disappeared when I changed
some variable names recently, so I don't know what to
make of it.

> Idea: change the spelling to (REST CELL) of each one
> of these one by one in turn to see how the compiler
> message changes. :)
I'll keep that in mind if I have a similar problem
in the future.  Thanks for the help.

--Dan

------------------------------------------------
Dan Bensen
http://www.prairienet.org/~dsb/
From: danb
Subject: Re: Deleting un(?)reachable code
Date: 
Message-ID: <45c5c376-2374-41a1-8c33-81298ba15c31@d62g2000hsf.googlegroups.com>
On Mar 17, 8:53 pm, danb <·········@gmail.com> wrote:
> 3.  Why is the (cdr cell) form that's called inside the
>       (while (cdr cell) ...) form eliminated?

Oh great, the (cdr cell) message disappeared when I
renamed some variables.  In light of that case and the
reader issue in my previous thread, maybe a better
question would be whether sbcl is subject to some kind
of flakiness that would explain these problems.

--Dan

------------------------------------------------
Dan Bensen
http://www.prairienet.org/~dsb/
From: D Herring
Subject: Re: Deleting un(?)reachable code
Date: 
Message-ID: <VZydnZNyMo3LwkLanZ2dnUVZ_qjinZ2d@comcast.com>
danb wrote:
> On Mar 17, 8:53 pm, danb <·········@gmail.com> wrote:
>> 3.  Why is the (cdr cell) form that's called inside the
>>       (while (cdr cell) ...) form eliminated?
> 
> Oh great, the (cdr cell) message disappeared when I
> renamed some variables.  In light of that case and the
> reader issue in my previous thread, maybe a better
> question would be whether sbcl is subject to some kind
> of flakiness that would explain these problems.

Which version of sbcl?  Which platform (arch/OS)?

Could you submit a complete example to the sbcl-devel mailing list?

- Daniel
(who does not represent sbcl)
From: Tobias C. Rittweiler
Subject: Re: Deleting un(?)reachable code
Date: 
Message-ID: <873aqoidsu.fsf@freebits.de>
danb <·········@gmail.com> writes:

> On Mar 17, 8:53 pm, danb <·········@gmail.com> wrote:
> > 3.  Why is the (cdr cell) form that's called inside the
> >       (while (cdr cell) ...) form eliminated?
>
> Oh great, the (cdr cell) message disappeared when I
> renamed some variables.  In light of that case and the
> reader issue in my previous thread, maybe a better
> question would be whether sbcl is subject to some kind
> of flakiness that would explain these problems.

It rather sounds like your macro is screwed up. In fact, if you look at
the output, you'll see that everything that directly depends on the
VERBOSE &optional parameter of your lambda-list is flagged to be
unreachable---SBCL probably recognizes that it's always NIL by constant
propagation.

  -T.
From: D Herring
Subject: Re: Deleting un(?)reachable code
Date: 
Message-ID: <N7ydnd46h4Ro1ULanZ2dnUVZ_qXinZ2d@comcast.com>
danb wrote:
> Does anyone have any idea why sbcl would delete these
> code segments?  There are three FORMAT forms and one
> CDR form.

Since you didn't copy the whole code, I can't compile and give an 
educated comment...  but when did that stop me?

Usually when I get these "deleting unreachable code" errors its 
because I did something stupid, generally rather far from the code 
which is flagged.  Type conversion errors, other optimization errors, 
and the like.

I often back out of these by setting debug to 3 and optimization to 0 
and then running or refactoring into smaller pieces until the critical 
section appears.

- Daniel


> 
> The FORMATs occur in an inlined function (USABLE), and are
> called conditionally, depending on the value of an optional arg
> (TESTING).  I understand that the conditional calls can be elim-
> inated for any call to the inline function that doesn't specify
> a value for the condition, which defaults to nil.  But there's
> still some strangeness left over:
> 
> 1.  Why does the compiler single out the format strings as
>     being the unreachable part?
> 2.  Why aren't the PAUSE forms eliminated, since they're in
>     the same WHEN forms as the FORMATs?
> 3.  Why is the (cdr cell) form that's called inside the
>       (while (cdr cell) ...) form eliminated?  An obvious thought
>     would be that I got the test backwards in WHILE, but it's tested
>     and seems to work.  The conditional test in WHILE is
>       (unless ,test (return-from ,block))
>     I don't see how that could be wrong.
> 
> (compiler output & code snippets below;
> affected code is under-careted)
> 
> --Dan
> 
> Compiler output:
> 
> ; in: DEF-INLINE USABLE
> ;     (FORMAT T "n-div = ~D. " PANPAL::N-DIV)
> ; ==> "n-div = ~D. "
> ; note: deleting unreachable code
> ;     (FORMAT T "~A is usable.~%" PANPAL::WORD)
> ; ==> "~A is usable.~%"
> ; note: deleting unreachable code
> ;     (FORMAT T "~A is not usable.~%" PANPAL::WORD)
> ; ==> "~A is not usable.~%"
> ; note: deleting unreachable code
> 
> ; in: DEF TRIM-WORDS
> ;     (CDR PANPAL::CELL)
> ; ==> PANPAL::CELL
> ; note: deleting unreachable code
> 
> Code snippets:
> 
> (def-inline usable (word fortree baktree &optional verbose)
>   ...
>   (dotimes (n-div (1- num-chars))
>     (when verbose
>       (format t "n-div = ~D. " n-div)
>       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>       (pause "try-subs<RTRN>"))
>     (when (try-subs n-div)
>       (when verbose
>         (format t "~A is usable.~%" word)
>         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>         (pause "return-from usable."))
>       (return-from usable t)))
>   (when verbose
>     (format t "~A is not usable.~%" word)
>     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>     (pause "End usable."))
>   nil)))
> 
> ...
> (while (cdr cell)
>   (let* ((wrd (cadr cell))
>          (ok (usable wrd fortree baktree)))
>     (cond
>       (ok (setf cell (cdr cell))) ;move down the list
>                      ^^^^^^^^^^
>       (t  (setf (cdr cell) (cddr cell)) ;delete the wrd
>           (delete-wrd wrd fortree baktree)))))
> 
> ------------------------------------------------
> Dan Bensen
> http://www.prairienet.org/~dsb/