forked from NUDT-compiler/nudt-compiler-cpp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3.7 KiB
3.7 KiB
我先快速读取当前 IRGen 的入口与表达式/语句文件,然后按“节点到接口调用映射”给你一份可以直接交给 IRGen 同学实现的调用说明。
Read , lines 320 to 387
Read
Read
Read
Read
可以,下面给你一份面向 IRGen 同学的“如何调用你新增 IR 接口”的实现说明,按落地顺序写。
先看调用边界
- IRGen 只负责把语法树翻译成 IR,不做符号查找
变量和函数绑定依赖 Sema 结果,参考 IRGenExp.cpp 的变量读取流程。 - 所有指令创建都通过 IRBuilder
新增接口定义在 IR.h。 - 终结指令规则必须遵守
Ret/Br/CondBr 一旦插入当前块,这个块不能再插普通指令,规则在 Instruction.cpp 和 BasicBlock.cpp。
建议 IRGen 调用映射
一、表达式层
- 加减乘除模
- a + b: CreateAdd(lhs, rhs, temp)
- a - b: CreateSub(lhs, rhs, temp)
- a * b: CreateMul(lhs, rhs, temp)
- a / b: CreateDiv(lhs, rhs, temp)
- a % b: CreateMod(lhs, rhs, temp)
- 比较表达式
- == != < <= > >= 统一走 CreateCmp(op, lhs, rhs, temp)
- 返回 i32,约定 0 为假,非 0 为真
- 一元运算建议
- -x: CreateSub(const0, x, temp)
- !x: CreateCmp(Eq, x, const0, temp)
- +x: 直接返回 x
- 变量读取和赋值
- 读取: 先由 Sema 绑定 use 到 decl,再从 storage_map 找槽位,CreateLoad
- 赋值: EvalExpr(rhs) 后对槽位 CreateStore(rhs_val, slot)
对应修改文件:
- IRGenExp.cpp
- IRGenDecl.cpp
- IRGenStmt.cpp
二、控制流层
- if/else
- 创建三个块: then, else, merge
- cond = EvalExpr(condExp)
- 当前块插 CreateCondBr(cond, then, else)
- 切入 then 块生成语句,末尾若未终结则 CreateBr(merge)
- 切入 else 块同理
- 最后 SetInsertPoint(merge)
- while
- 创建三个块: cond, body, exit
- 进入前先 CreateBr(cond)
- cond 块计算条件,CreateCondBr(cond_val, body, exit)
- body 块生成循环体,若未终结则回跳 CreateBr(cond)
- 最后 SetInsertPoint(exit)
- break/continue
- IRGen 维护循环栈,每层保存 continue_target 和 break_target
- break 直接 CreateBr(break_target)
- continue 直接 CreateBr(continue_target)
对应修改文件:
- IRGenStmt.cpp
三、函数与调用层
- 函数定义
- 用 Module.CreateFunction(name, ret_type, param_types) 建函数
- 入口块 SetInsertPoint(entry)
- 形参落栈策略建议:每个参数先 alloca,再 store 到本地槽位,后续统一按 load/store 访问
- 函数调用
- 先拿到 callee 对应的 Function
- 实参逐个 EvalExpr 得到 args
- 调用 CreateCall(callee, args, temp)
- 若返回值非 void,把返回 Value 继续参与表达式计算
对应修改文件:
- IRGenFunc.cpp
- IRGenExp.cpp
四、你要提醒 IRGen 同学的两个关键点
- 插入点管理
每次生成 Br/CondBr/Ret 后,必须切换到新块再继续生成。否则会触发块已终结错误。 - grammar 上下文名先对齐
你们当前 IRGen 里还在用 ParenExpContext、AdditiveExpContext 这类命名,实际 grammar 是另一套层级时要先改 Visitor 入口,否则接口再全也接不上。可先核对 SysY.g4 与 IRGen.h。
最小接入顺序
- 先接表达式算术与比较(M1)
- 再接 if/while/break/continue(M3)
- 再接函数参数和调用(M2)
如果你要,我下一步可以给你一版“按当前 grammar 的具体 visitor 函数名”逐条对照表,IRGen 同学可以直接照着改函数签名和调用点。