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.
nudt-compiler-cpp/forIRGenInterfaces.md

3.7 KiB

我先快速读取当前 IRGen 的入口与表达式/语句文件,然后按“节点到接口调用映射”给你一份可以直接交给 IRGen 同学实现的调用说明。

Read , lines 320 to 387

Read

Read

Read

Read

可以,下面给你一份面向 IRGen 同学的“如何调用你新增 IR 接口”的实现说明,按落地顺序写。

先看调用边界

  1. IRGen 只负责把语法树翻译成 IR不做符号查找
    变量和函数绑定依赖 Sema 结果,参考 IRGenExp.cpp 的变量读取流程。
  2. 所有指令创建都通过 IRBuilder
    新增接口定义在 IR.h。
  3. 终结指令规则必须遵守
    Ret/Br/CondBr 一旦插入当前块,这个块不能再插普通指令,规则在 Instruction.cpp 和 BasicBlock.cpp。

建议 IRGen 调用映射

一、表达式层

  1. 加减乘除模
  • 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)
  1. 比较表达式
  • == != < <= > >= 统一走 CreateCmp(op, lhs, rhs, temp)
  • 返回 i32约定 0 为假,非 0 为真
  1. 一元运算建议
  • -x: CreateSub(const0, x, temp)
  • !x: CreateCmp(Eq, x, const0, temp)
  • +x: 直接返回 x
  1. 变量读取和赋值
  • 读取: 先由 Sema 绑定 use 到 decl再从 storage_map 找槽位CreateLoad
  • 赋值: EvalExpr(rhs) 后对槽位 CreateStore(rhs_val, slot)

对应修改文件:

  • IRGenExp.cpp
  • IRGenDecl.cpp
  • IRGenStmt.cpp

二、控制流层

  1. if/else
  • 创建三个块: then, else, merge
  • cond = EvalExpr(condExp)
  • 当前块插 CreateCondBr(cond, then, else)
  • 切入 then 块生成语句,末尾若未终结则 CreateBr(merge)
  • 切入 else 块同理
  • 最后 SetInsertPoint(merge)
  1. while
  • 创建三个块: cond, body, exit
  • 进入前先 CreateBr(cond)
  • cond 块计算条件CreateCondBr(cond_val, body, exit)
  • body 块生成循环体,若未终结则回跳 CreateBr(cond)
  • 最后 SetInsertPoint(exit)
  1. break/continue
  • IRGen 维护循环栈,每层保存 continue_target 和 break_target
  • break 直接 CreateBr(break_target)
  • continue 直接 CreateBr(continue_target)

对应修改文件:

  • IRGenStmt.cpp

三、函数与调用层

  1. 函数定义
  • 用 Module.CreateFunction(name, ret_type, param_types) 建函数
  • 入口块 SetInsertPoint(entry)
  • 形参落栈策略建议:每个参数先 alloca再 store 到本地槽位,后续统一按 load/store 访问
  1. 函数调用
  • 先拿到 callee 对应的 Function
  • 实参逐个 EvalExpr 得到 args
  • 调用 CreateCall(callee, args, temp)
  • 若返回值非 void把返回 Value 继续参与表达式计算

对应修改文件:

  • IRGenFunc.cpp
  • IRGenExp.cpp

四、你要提醒 IRGen 同学的两个关键点

  1. 插入点管理
    每次生成 Br/CondBr/Ret 后,必须切换到新块再继续生成。否则会触发块已终结错误。
  2. grammar 上下文名先对齐
    你们当前 IRGen 里还在用 ParenExpContext、AdditiveExpContext 这类命名,实际 grammar 是另一套层级时要先改 Visitor 入口,否则接口再全也接不上。可先核对 SysY.g4 与 IRGen.h。

最小接入顺序

  1. 先接表达式算术与比较M1
  2. 再接 if/while/break/continueM3
  3. 再接函数参数和调用M2

如果你要,我下一步可以给你一版“按当前 grammar 的具体 visitor 函数名”逐条对照表IRGen 同学可以直接照着改函数签名和调用点。