golang 编译器执行流程

79 阅读1分钟

go.dev/src/cmd/com…

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

  1. It decomposes complex statements into individual, simpler statements, introducing temporary variables and respecting order of evaluation. This step is also referred to as “order.”
  2. It desugars higher-level Go constructs into more primitive ones. For example, switch statements 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.

7. Generating machine code