Skip to content

Commit

Permalink
feat(compiler): compiler init
Browse files Browse the repository at this point in the history
  • Loading branch information
shgopher committed Nov 17, 2023
1 parent ae0eb0d commit d1327d9
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 6 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ hey~,我是科科人神,目前就职于国内一家互联网公司,你们
- [栈内存管理](./runtime/栈内存管理)
- [系统监控](./runtime/系统监控)
- [netpool](./runtime/netpool)
## 编译器
- [gc](./编译器/gc)
- [llvm](./编译器/llvm)
- [gccgo](./编译器/gccgo)
## 工程
- [go 编程范式/设计模式](./工程/go编程范式/README.md)
- [包管理工具](./工程/包及其构建工具)
Expand Down
4 changes: 2 additions & 2 deletions changelog.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @Author: shgopher [email protected]
* @Date: 2023-05-06 12:20:49
* @LastEditors: shgopher [email protected]
* @LastEditTime: 2023-05-06 13:13:05
* @LastEditTime: 2023-11-17 12:41:29
* @FilePath: /GOFamily/changelog.config.js
* @Description:
*
Expand All @@ -15,7 +15,7 @@ module.exports = {
maxMessageLength: 64,
minMessageLength: 3,
questions: ['type', 'scope', 'subject', 'body', 'breaking', 'issues', 'lerna'],
scopes: ['basic','root','all','runtime','concurrency','project','.vuepress','.github'],
scopes: ['basic','root','all','runtime','compiler','concurrency','project','.vuepress','.github'],
types: {
chore: {
description: 'Build process or auxiliary tool changes',
Expand Down
8 changes: 4 additions & 4 deletions 工程/错误处理/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @Author: shgopher [email protected]
* @Date: 2022-11-17 20:40:42
* @LastEditors: shgopher [email protected]
* @LastEditTime: 2023-11-16 21:20:57
* @LastEditTime: 2023-11-16 22:01:32
* @FilePath: /GOFamily/工程/错误处理/README.md
* @Description:
*
Expand Down Expand Up @@ -578,15 +578,15 @@ func Countlines(r io.Reader)(int,error){
// 代码看起来也是很合理的样子,也很简洁,但是,我们其实用的函数不是特别的合适

//其实这里使用 scan 更加合适,代码量更加精简,并且结构异常舒服
func Countlines(r io.Reader) (int,error){

func Countlines(r io.Reader) (int,error){
sc := bufio.NewScanner(r)
lines := 0

for sc.Scan() {
lines++
}
return lines,sc.Err()

return lines, sc.Err()
}

```
Expand Down
36 changes: 36 additions & 0 deletions 编译器/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!--
* @Author: shgopher [email protected]
* @Date: 2023-11-17 12:10:27
* @LastEditors: shgopher [email protected]
* @LastEditTime: 2023-11-17 12:10:36
* @FilePath: /GOFamily/编译器/README.md
* @Description:
*
* Copyright (c) 2023 by shgopher, All Rights Reserved.
-->
# go 编译器
## 编译器概述
默认编译器 gc 介绍
编译原理和过程
编译器组件工具链
编译优化技术
## 编译器特性
编译速度快
生成自包含可执行文件
内存安全保证
跨平台支持
模块化支持
## 编译器实战
常见编译错误和解决方法
编译参数和定制
增量编译
hook 编译过程
交叉编译
## 编译器源码
gc 编译器源码解析
编译器前端实现
编译器后端实现
## 其他编译器
gccgo
gollvm
编译器比较
18 changes: 18 additions & 0 deletions 编译器/gc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# go 语言官方编译器 gc

Go 语言默认的编译器全称是 gc,它是 Go 语言官方实现的编译器,主要功能包括:

- gc - Go 语言编译器前端,负责分析和转换 Go 语言源代码。
- ssa - 生成静态单赋值 (SSA) 中间表示。
- scheduler - 根据依赖关系安排指令执行顺序。
- linker - 链接程序依赖的库。
- runtime - Go 运行时,提供垃圾回收,并发等功能。
- assembler - 将汇编指令转换为机器码。

gc 编译器由 Go 语言的创造者 Robert Griesemer、Rob Pike 及 Ken Thompson 开发,首次在2007年与 Go 一起开源发布。

gc 实现了对 Go 语言的完整支持,可以编译包括复杂特性如 goroutine、channel 和接口在内的所有 Go 语言程序。它输出自包含的可执行文件,不需要外部依赖。

gc 编译器写在 Go 语言本身并采用了 Go 的并发特性,编译速度非常快。它与 Go 的发布周期同步,确保语言 feature 得到及时支持。

所以 Go 语言默认编译器的全称就是 gc,它是官方提供的 Go 语言编译器。
15 changes: 15 additions & 0 deletions 编译器/gccgo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# gccgo
gccgo 是 Gо 语言到 C 语言的编译器,它将 Gо 语言源代码编译成 C 语言源代码。

gccgo 本身只是一个编译器前端,负责解析 Gо 语言代码并生成 C 语言代码。要生成最终的可执行文件,还需要一个编译器后端。

gccgo 常见的后端有:

gcc - GNU 编译器,可以将 gccgo 生成的 C 语言代码进一步编译成机器代码,生成最终的可执行文件。
clang - LLVM 编译器,同样可以将 C 语言编译成机器代码。
tcc - Tiny C Compiler,一个小型快速的 C 语言编译器。
所以简单来说,gccgo 编译器的常见后端是 gcc 和 clang。完整的编译流程是:

gccgo 前端 → C 语言代码 → gcc/clang 后端 → 机器代码 (可执行文件)

开发者可以根据需要选择不同的编译器后端,来编译 gccgo 生成的 C 语言代码。
60 changes: 60 additions & 0 deletions 编译器/llvm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!--
* @Author: shgopher [email protected]
* @Date: 2023-11-17 12:28:57
* @LastEditors: shgopher [email protected]
* @LastEditTime: 2023-11-17 12:34:29
* @FilePath: /GOFamily/编译器/llvm/README.md
* @Description:
*
* Copyright (c) 2023 by shgopher, All Rights Reserved.
-->
# llvm
LLVM 可以通过以下两种主要方式为 Go 语言代码提供编译支持:

## gollvm
gollvm 项目实现了将 Go 代码编译为 LLVM IR 的 frontend。它可以直接生成 LLVM IR,然后通过 LLVM 进行后端代码生成。

主要步骤是:

- gollvm 解析 Go 代码,生成对应的 LLVM IR
- 执行 LLVM 优化流水线进行优化
- LLVM 后端生成目标平台的机器码
- 嵌入 LLVM pass
## 可以通过修改 Go Compiler 工具链,在编译过程中调用 LLVM Pass 执行优化。

主要步骤是:

- Go Compiler 前端生成 initial IR
- 将 IR 传递给 LLVM Pass 执行优化
- LLVM Pass 输出优化后的 IR
- Go Compiler 后端根据 IR 生成机器码

这种方式需要 invasive 修改 Go 编译器,较为复杂。

总结:

gollvm 通过完全 External 的方式引入 LLVM,而嵌入 LLVM Pass 需要修改 Go Compiler。

gollvm 方式集成更简单,但是需要保证 IR 的转换正确性;嵌入 Pass 可以利用 Go Compiler 的 Context 信息进行更准确的优化。

根据需求和成本进行抉择。
## llvm -golang
llvm-golang 是另一个用于 Go 语言编译的 LLVM 集成项目。

它与 gollvm 的主要区别有:

实现方式不同
- gollvm 是独立的 Go frontend,将 Go 代码编译成 LLVM IR
- llvm-golang 直接使用 LLVM 对 Go 代码进行编译
编译入口不同
- gollvm 通过调用 gollvm 命令,传入 Go 源文件
- llvm-golang 编译时调用 clang 命令,并使用-femulate-llvm-golang 参数
编译过程不同
- gollvm 编译生成完整的 LLVM IR 然后优化
- llvm-golang 是逐函数生成 LLVM IR 并编译
项目状态不同
- gollvm 活跃维护,可正常使用
- llvm-golang 最后更新在5年前,未维护
总之,llvm-golang 是直接使用 LLVM 编译 Go 的早期尝试,但维护情况不佳。gollvm 作为独立 frontend 集成 LLVM,是更可靠的解决方案。

但 llvm-golang 的直接编译方式也具有借鉴意义,合理结合两种方式可以获得更好的 LLVM 集成效果。

0 comments on commit d1327d9

Please sign in to comment.