Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Style warning cleanup #826

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

Conversation

gefjon
Copy link

@gefjon gefjon commented Jun 7, 2022

Quiet a few SBCL style warnings, mostly related to forward-referencing struct accessors that would otherwise be inlined.

Phoebe Goldman added 13 commits June 1, 2022 11:59
…ing benchmarks

This assignment must be outdated, because it binds a name `*cost-fn-weight-style*` which
uses the special variable convention, but is not defined or declaimed special
anywhere. The benchmarks do not use this assignment, so I believe it's safe to remove.
magicl-constructors.lisp has a compile-time dependency on ast.lisp because it uses some
inline functions (struct accessors) defined in the latter file, but ast.lisp has no
compile-time dependency on magicl-constructors.lisp. SBCL warned about the old order, but
doesn't about the new order.
In order to inline a function, it must be declaimed `inline` before its definition, and
its definition must appear before any of its uses. SBCL issues style-warnings if any of
those conditions don't apply. This commit reorders some forms in clifford/stabilizer.lisp
to allow inlining and make the warning go away.
…nd compilation-methods

Prior to this commit, chip-specification.lisp globally declaimed the accessors on
`hardware-object` as `notinline`, in the hopes that would shut SBCL up about its inability
to inline the accessors. It didn't work.

Now, each usage of one of those accessors before their definitions is locally declared
`notinline`, which makes the warnings go away. The global `notinline` declaimations are
removed, as they never accomplished anything other than preventing optimizations.
The keyword argument `:initial-rewiring` appeared in the arglist for the default method,
and in the generic function's docstring, but it did not appear in the generic function's
declared arglist (nor did `&allow-other-keys`), and the default method never read from
`initial-rewiring`. References in the method arglist and the docstring are removed.
SBCL will warn when it compiles a call to a function for which an `inline` declaration is
in effect, but for which inlining is impossible. It will also warn when it compiles the
definition of a function for which an `inline` declaration is effect, but to which
not-inlined calls have previously been compiled.

Both of these cases appeared in define-compiler.lisp. CL-HEAP contains `inline`
declaimations for `enqueue` and `dequeue`, but those are generic functions and therefore
not elligible for inlining. Structure accessors are always `inline`, but define-compiler
forward-references accessors to the `gate-record` struct. Rather than addressing the root
of either of those problems, this commit adds local `notinline` declarations so SBCL will
not warn.
No warning to fix here, but an opportunity for some minor missed compiler
optimizations. CL compilers are generally unable to do any useful optimization or
compile-time type checking with `satisfies` types, because they are incapable of
understanding the behavior of the `satisfies` function. The traditional solution is, for a
type FOO and a predicate function FOO-WITH-SOME-PROPERTY-P, to define the type
FOO-WITH-SOME-PROPERTY as `(and FOO (satisfies FOO-WITH-SOME-PROPERTY-P))`, not just
`(satisfies FOO-WITH-SOME-PROPERTY-P)`. That way, the compiler knows at compile time that
every `FOO-WITH-SOME-PROPERTY` is at the very least a `FOO`, and also that any `(not FOO)`
is also not a `FOO-WITH-SOME-PROPERTY`. Footgun: `FOO-WITH-SOME-PROPERTY-P` still needs to
check `(typep thing 'FOO)`.
Copy link
Member

@stylewarning stylewarning left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some small requests; biggest one is treatment of inline/notinline

also remember to M-q comments

@@ -240,10 +240,14 @@ The keys are typically INSTRUCTION instances and associated values are STRINGs."
(integer-vec
(map 'vector
(lambda (token)
(declare
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we just move this whole rewiring section to be defined after token is?

hardware-object-rewriting-rules
hardware-object-cxns
hardware-object-misc-data))
;;; Note that a previous file "compilation-methods.lisp" uses this structure, but the dependency is circular,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we reverse it? Can we

(declaim inline)
(defstruct)
(declaim notinline)

and just inline whenever we feel we need to?

Adding bulky notinline decls everywhere just to quiet SBCL is sort of a code smell to me; I'd rather condense it all, and use inline to drive performance, not notinline to hush warnings.

@@ -77,9 +77,16 @@
(application-thread-invocation-thread instruction)))
;; then try the compilers attached to the hardware object
(when hardware-object
(map nil #'try-compiler (hardware-object-compilation-methods hardware-object)))
(map nil #'try-compiler
(locally
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see prev comment

(instr nil :type application)
(prev nil :type (or null peephole-rewriter-node))
(next nil :type (or null peephole-rewriter-node))
(context nil)) ; compressor context *after* this instruction is applied
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this comment got lost in the copy-paste

@@ -654,6 +661,10 @@ N.B.: The word \"shortest\" here is a bit fuzzy. In practice it typically means
(let ((queue (make-instance 'cl-heap:priority-queue :sort-fun (complement #'occurrence-table-metric-worsep))))
(flet ((collect-bindings (occurrence-table)
(a:hash-table-keys (occurrence-table-map occurrence-table))))
(declare
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this notinline is totally fine.

Also can you M-q the comment?

@gefjon
Copy link
Author

gefjon commented Jun 7, 2022

Also can you M-q the comment?

What line length do you prefer?

can we just move this whole rewiring section to be defined after token is?

My gut says no; token is defined in the parser, which sorta necessarily comes after the ast is defined. We could adopt a policy of moving all definitions earlier into a defs.lisp file.

Can we reverse it? Can we

(declaim inline)
(defstruct)
(declaim notinline)

and just inline whenever we feel we need to?

Adding bulky notinline decls everywhere just to quiet SBCL is sort of a code smell to me; I'd rather condense it all, and use inline to drive performance, not notinline to hush warnings.

No, I don't believe this works. If it did, the previous version that just notinline'd the struct accessors before definition would have prevented the warnings. Unfortunately, I think that the only ways to prevent these warnings are:

  1. Use ASDF's :around-compile to sb-ext:muffle-warnings.
  2. Break circular dependencies by moving structure definitions into a defs.lisp file.
  3. Complain to the SBCL devs to remove this style warning, because it's stupid.
  4. What I did.

I aimed for 4 because it seemed the least invasive fix, but 2 seems more correct. 1 feels like a gross hack, and 3 seems unlikely to work.

@karlosz
Copy link
Contributor

karlosz commented Jun 7, 2022

If you just want SBCL to stop complaining about certain warnings, sb-ext:muffle-conditions does that for you.

I think adding inline/notinline to shut the compiler up would be poor style. Moving definitions around works if you want speed, as the style warnings note. Maybe those warnings should get downgraded to just compiler notes...

@gefjon
Copy link
Author

gefjon commented Jun 7, 2022

Putting a "global" muffle-conditions (I mistakenly wrote muffle-warnings in my prev comment, but that's the declaration I meant) around ASDF compiling feels unfortunate, and putting locally muffle-conditions around callsites feels strictly worse than the locally notinlines because it would involve additional #+sbcl syntactic overhead.

If SBCL could be convinced to downgrade "unable to inline" from a style-warning to a note from a style-warning (either specifically for defstruct accessors because their inline declarations are implicit, or for all inline functions), I think that would be an improvement.

What should be a style-warning is using setf on a forward-referenced struct accessor, because the spec permits those to be implemented as setf-expanders rather than setf-functions. I don't believe QuilC does this, but the fact that I have to write about the distinction tells me that maybe we should move all our defstructs into an early defs.lisp file.

@karlosz
Copy link
Contributor

karlosz commented Jun 8, 2022

What's wrong with wrapping muffle conditions with asdf?

The condition class for failure to inline is 'inlining-dependency-failure. You can use that to muffle of all inlining failure notes (and only those notes) if it's felt that all such failure notices are pointless.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants