-
Notifications
You must be signed in to change notification settings - Fork 3
IR1 optimization macros
all compiler information is stored in a so-called info
database.
The API for accessing this database is (sb-int:info category kind name)
e.g. (sb-int:info :function :info 'make-list)
.
In the source code I saw following combinations. They are not well documented:
- category
:function
: kind::source-location
:type
:where-from
:kind
:info
:macro-function
:compiler-macro-function
:emitted-full-calls
:ir1-convert
:source-transform
:inlinep
:assumed-type
:inline-expansion-designator
- category
:variable
: kind::source-location
:type
:declaration
:where-from
:variable-tls
:always-bound
- category
:declaration
:recognized
- category
:source-location
kind:declaration
- category
:setf
kind:expander
- category
:typed-structure
:info
- category
:random-documentation
:stuff
- category
:type
:compiler-layout
:deprecated
:expander
- category
:prin1
- category
:no-ir2-yet
- category
:test
- category
:rest-p
- category
:ref-trans
Infodb slots specified by :function :info
contains a SB-C::FUN-INFO
structure.
Most internal / standard functions have its fun-info, which stores information on several optimization methods.
The macros to manipulate (mostly only adding) fun-info are sb-c:defknown
, sb-c:defoptimizer
, sb-c:deftransform
.
defknown
sets up a fun-info
entry in the infodb. Thus it should be called before other macros are evaluated.
Re-evaluating this macro inserts a new fun-info
instance, which is equivalent to wiping the infodb for that function.
It provides the following information:
- function attributes, such as
movable
,flushable
,dx-safe
. This is discussed in function attributes. - function types. This is a static one, similar to the
ftype
'd information. What you see fromdeclared type
also comes from this.
Original documentation here.
deftransform
can be seen as an implementation-specific, internal version of define-compiler-macro
dispatched by the inferred argument types. For example, if the type of an argument of a call to copy-seq
is known to be a vector
in compile time, and if there is a deftransform
specialized with vector
with a loop-based, specialized version of the function, then the call can be replaced with the transformation result.
These functions are stored in the transforms
slot in fun-info
.
You may attach a docstring to deftransform
. When the optimization policy is high, the compiler uses this docstring as a note when the transform was failed due to the type requirement.
Original documentation here.
Original documentation here.
Used to implement methods for deriving other types of information. Syntax is (defoptimizer name ...)
or (defoptimzer (name kind) ...)
. However, the first type of defoptimizer
without kind
is rare, only used in vm-ir2tran.lisp
. It looks like they are some kind of hack to implement functions that happened to have the same function signatures. So, let's focus on the second type of defoptimizer
.
Documentation says kind
is one of DERIVE-TYPE
, OPTIMIZER
, LTN-ANNOTATE
and IR2-CONVERT
. This is not true, there is no such restriction. There is no real documentation for each kind
. However, the result of these optimization functions are stored in the corresponding slot with the same name in fun-info
. See fun-info documentation.
Following kinds
are actually used.
derive-type
the optimizer function defined by derive-type
is used to derive the return-type of a function call from the types of arguments.
For example, the result type of (random arg)
is equivalent to the type of arg
, and this can be implemented by derive-type
.
It should be a function that returns a type specifier a CTYPE
object. CTYPE
object can be constructed from a type specifier using sb-kernel:specifier-type
. CTYPE documentation
stack-allocate-result
Returns a boolean, allows stack allocation if true.
optimizer
It allows misc optimizations, modifying the LVARs. Returns true if further optimizations of the call shouldn't be attempted.
Example: converting (values-list (list x y z))
into (values x y z)
.
Example: constant folding coerce
.
-
ltn-annotate
: I have no idea whatLTN
means. SBCL contains lots of these unreadable abbreviations and it sucks. -
ir2-convert
provides special ir2 conversion for irregular functions. ir2-hook
-
constraint-propagate-if
: Used only once incompiler/typetran.lisp:(defoptimizer (%typep-wrapper constraint-propagate-if)
.
This is essentially the same as compiler macros. It does not investigate the arguments and unconditionally expands a function call into another form. Expander functions are stored in (info :function :source-transform)
.
While a compiler-macro must deal with being invoked when its
whole form matches (FUNCALL <f> ...)
so that it must skip over <f>
to find
the arguments, a source-transform need not worry about that situation.
Original documentation here.
Used to implement a special form. Stores information in (info :function :ir1-convert)
. Original documentation here.