4.2 KiB
4.2 KiB
NGRA → HIR → SSA → LLVM 设计笔记
当前结论
NGRA 不应直接承担完整 SSA 构建与数据流分析职责。
NGRA 的职责是:
- Token 分析
- 岛屿压缩(Island Compression)
- 结构识别
- 局部语义绑定
- 元数据传播
- AST 构建
SSA 的职责是:
- CFG 构建
- Def-Use 分析
- Phi 插入
- Value Versioning
- 全局优化
总体架构
推荐架构:
Source Code
↓
NGRA
↓
五角星AST
↓
HIR(寄存器式)
↓
CFG
↓
SSA
↓
LLVM IR
↓
LLVM Backend
↓
Native Code / SPIR-V / CUDA
而不是:
AST
↓
直接LLVM IR
原因:
LLVM IR 过于底层。
NGRA 与语言语义高度相关。
中间需要一个:
Language HIR
作为桥梁。
五角星AST职责
五角星AST承担:
Syntax
+
Metadata
+
Partial Semantic
信息。
节点包含:
Parent
Prev
Next
Left
Right
同时可附带:
Type
Symbol
Attribute
SourceSpan
Flags
因此无需再构造独立 Bound AST。
SCG(Semi Context Grammar)
SCG 不等于 SSA。
SCG 只负责:
1. 声明语义
例如:
class Foo : Bar
直接得到:
Foo
Bar
Inheritance
2. Token级语义
例如:
123
立即得到:
Int32
例如:
int a = "abc";
立即报错。
3. 局部表达式语义
例如:
int + float
归约时:
Implicit Conversion
Operator Resolution
直接完成。
4. 上下文元数据
允许读取:
当前岛屿
父岛屿
全局声明表
中的信息。
例如:
namespace A
{
class B
}
Class Island 自动继承:
CurrentNamespace=A
SCG边界
SCG允许:
当前节点
当前归约栈
当前岛屿元数据
父岛屿元数据
全局声明表
SCG禁止:
CFG
Phi
Def-Use
Alias Analysis
Call Graph
Loop Analysis
这些属于 SSA 阶段。
HIR设计
最终决定:
不采用栈机IR。
原因:
AST 已经表达了操作数关系。
如果先降成:
load
load
add
store
属于:
丢失结构
再恢复结构
没有意义。
HIR采用寄存器式设计
推荐形式:
%0 = const 2
%1 = mul c, %0
%2 = add b, %1
a := %2
而不是:
load b
load c
push 2
mul
add
store a
Value模型
HIR中的表达式全部返回 Value。
例如:
HirValue EmitExpr(AstNode node)
返回:
ValueId
Symbol与Value分离
保留:
SymbolId
ValueId
两套体系。
例如:
a
b
c
属于:
SymbolId
表达式结果:
%0
%1
%2
属于:
ValueId
Assignment处理
例如:
a = b + c;
生成:
%0 = add b,c
a := %0
此时:
a
仍不是 SSA。
只是:
Symbol → Current Value
映射。
SSA阶段
SSA阶段负责:
a
↓
a_0
a_1
a_2
...
版本化。
例如:
a = 1;
a = 2;
变:
a_0 = 1
a_1 = 2
CFG构建
真正的分界线
不是:
AST
↓
HIR
而是:
HIR
↓
CFG
因为:
树
↓
图
在这里发生。
例如:
if(cond)
{
}
else
{
}
生成:
BB0
br cond
BB1
...
BB2
...
BB3
LLVM IR定位
LLVM IR不是语言IR。
LLVM IR是:
SSA Optimization IR
职责:
跨平台
优化
后端接口
不负责:
泛型
属性
高级语义
最终路线
NGRA
↓
SCG
↓
五角星AST
↓
寄存器式HIR
↓
CFG
↓
SSA
↓
LLVM IR
↓
x86/ARM
或
SPIR-V
或
CUDA/NVVM
对蓝图系统的启发
SSA最重要的启发:
程序可以拆成:
Control Flow Graph
+
Data Flow Graph
两张图。
因此未来节点管线系统可考虑:
State Graph
+
Value Graph
双图结构。
从:
DAG
演化为:
Parallel State Machine
+
Data Dependency Graph
这样能够自然支持:
Branch
Loop
Coroutine
Async
Event
等复杂控制流。