1. Parsing
cmd/compile/internal/syntax(lexer, parser, syntax tree)
In the first phase of compilation, source code is tokenized (lexical analysis), parsed (syntax analysis), and a syntax tree is constructed for each source file.
Each syntax tree is an exact representation of the respective source file, with nodes corresponding to the various elements of the source such as expressions, declarations, and statements. The syntax tree also includes position information which is used for error reporting and the creation of debugging information.
2. Type checking
cmd/compile/internal/types2(type checking)
3. IR construction (“noding”)
The compiler middle end uses its own AST definition and representation of Go types carried over from when it was written in C. All of its code is written in terms of these, so the next step after type checking is to convert the syntax and types2 representations to ir and types. This process is referred to as “noding.”
4. Middle end
cmd/compile/internal/deadcode(dead code elimination)cmd/compile/internal/inline(function call inlining)cmd/compile/internal/devirtualize(devirtualization of known interface method calls)cmd/compile/internal/escape(escape analysis)
5. Walk
- It decomposes complex statements into individual, simpler statements, introducing temporary variables and respecting order of evaluation. This step is also referred to as “order.”
- It desugars higher-level Go constructs into more primitive ones. For example,
switchstatements are turned into binary search or jump tables, and operations on maps and channels are replaced with runtime calls.
6. Generic SSA
In this phase, IR is converted into Static Single Assignment (SSA) form, a lower-level intermediate representation with specific properties that make it easier to implement optimizations and to eventually generate machine code from it.