mirror of
https://github.com/golang/go
synced 2024-11-27 04:31:21 -07:00
cmd/compile/internal/ssa: add initial README
This is the first version of an introductory document that should help developers who want to get started with this package. I recently started poking around this part of the compiler, and was confused by a few basic ideas such as memory arguments. I also hadn't heard about GOSSAFUNC until another developer pointed it out. Both of those are essential if one wants to do any non-trivial work here. This document can of course be expanded with more pointers and tips to better understand this package's code and behavior. Its intent is not to cover all of its features; but it should be enough for most developers to start playing with it without extensive compiler experience. Change-Id: Ifd2d047fbd038ab50f4625a15c4d49932b42fd66 Reviewed-on: https://go-review.googlesource.com/99715 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
parent
8a525b8e7f
commit
ec60e4a0d2
59
src/cmd/compile/internal/ssa/README.md
Normal file
59
src/cmd/compile/internal/ssa/README.md
Normal file
@ -0,0 +1,59 @@
|
||||
This package contains the compiler's Static Single Assignment form
|
||||
component. If you're not familiar with SSA, Wikipedia is a good starting
|
||||
point:
|
||||
|
||||
https://en.wikipedia.org/wiki/Static_single_assignment_form
|
||||
|
||||
SSA is useful to perform transformations and optimizations, which can be
|
||||
found in this package in the form of compiler passes and rewrite rules.
|
||||
The former can be found in the "passes" array in compile.go, while the
|
||||
latter are generated from gen/*.rules.
|
||||
|
||||
Like most other SSA forms, funcs consist of blocks and values. Values
|
||||
perform an operation, which is encoded in the form of an operator and a
|
||||
number of arguments. The semantics of each Op can be found in
|
||||
gen/*Ops.go.
|
||||
|
||||
gen/* is used to generate code in the ssa package. This includes
|
||||
opGen.go from gen/*Ops.go, and the rewrite*.go files from gen/*.rules.
|
||||
To regenerate these files, see gen/README.
|
||||
|
||||
Blocks can have multiple forms. For example, BlockPlain will always hand
|
||||
the control flow to another block, and BlockIf will flow to one of two
|
||||
blocks depending on a value. See block.go for more details.
|
||||
|
||||
Values also have types. For example, a constant boolean value will have
|
||||
a Bool type, and a variable definition value will have a memory type.
|
||||
|
||||
The memory type is special - it represents the global memory state. For
|
||||
example, an Op that takes a memory argument depends on that memory
|
||||
state, and an Op which has the memory type impacts the state of memory.
|
||||
This is important so that memory operations are kept in the right order.
|
||||
|
||||
For example, take this program:
|
||||
|
||||
func f(a, b *int) {
|
||||
*a = 3
|
||||
*b = *a
|
||||
}
|
||||
|
||||
The two generated stores may show up as follows:
|
||||
|
||||
v10 (4) = Store <mem> {int} v6 v8 v1
|
||||
v14 (5) = Store <mem> {int} v7 v8 v10
|
||||
|
||||
Since the second store has a memory argument v10, it cannot be reordered
|
||||
before the first store, which sets that global memory state. And the
|
||||
logic translates to the code; reordering the two assignments would
|
||||
result in a different program.
|
||||
|
||||
A good way to see and get used to the compiler's SSA in action is via
|
||||
GOSSAFUNC. For example, to see func Foo's initial SSA form and final
|
||||
generated assembly, one can run:
|
||||
|
||||
GOSSAFUNC=Foo go build
|
||||
|
||||
The generated ssa.html file will also contain the SSA func at each of
|
||||
the compile passes, making it easy to see what each pass does to a
|
||||
particular program. You can also click on values and blocks to highlight
|
||||
them, to help follow the control flow and values.
|
Loading…
Reference in New Issue
Block a user