跳转至

毕昇杯广告

由于实验课程学时和难度的限制, 本次实验的源语言十分简陋, 甚至不是图灵完备的语言; 同时我们使用的目标平台是也是一个不太规范的模拟器; 并且本次实验没有涉及任何优化. 如果大家对编写 "真正可用" 且带优化的编译器感兴趣, 欢迎大家来参加 计算机系统能力竞赛编译系统设计赛(华为毕昇杯).

毕昇杯简介

你说得对, 但是毕昇杯是由系统能力培养研究专家组发起、由全国高校计算机教育研究会主办、面向高校大学生的全国性大赛. 比赛发生在一个被称作树莓派的目标平台, 在这里, 被官方选中的人将被授予 "运行时库", 引导编译之力. 你将扮演一位名为 "编译器" 的神秘角色, 在 ARMv7 的旅行中访问各种指令寄存器, 向量寄存器和内存, 和他们一起通过测试用例, 找回失散的隐藏用例 —— 同时逐步发掘 SysY 的真相.

这个比赛的目标是编写一个完整的从 C 语言子集 (SysY) 到 ARMv7 汇编的编译器, 随后大家竞争各自的编译器对程序的优化水平. 不怎么看 PPT 答辩, 靠编译结果程序运行速度说话, 是实打实的技术竞赛. 大赛组委会也非常 nice, 对参赛者的提问基本上能快速回复.

比赛需组队进行, 一队 1-4 人, 每校报名数量不限, 但只能有两只初赛成绩最好的队伍作为内卡进入复赛. 外卡队伍与内卡的区别是内卡获奖有奖金, 并且内外卡颁奖列表分开, 其他的方面相同 (包括奖项与各类福利, 复赛时比成绩也是内外卡一起比). 奖金金额与获奖队数可详见官网. 报名成功就每队送一只树莓派 (赛后不收回) 作为本地测试环境.

我校近两年毕昇杯获奖状况如下:

  • 2021 年: xwh 说得都队(李宇航, 潘志伟, 徐文浩, 赵和杰) 三等奖
  • 2022 年: 萝杨空队(梁韬, 杨博康, 苏亦凡) 二等奖, lrc 队(陈思超, 涂正洲, 宋子洋) 三等奖

欢迎大家联系上述队员 (建议联系最近参赛成员), 或汪花梅老师了解比赛详情!

校内毕昇杯交流 QQ 群: 580679631

扩展阅读

一些不知道该放在哪里的拓展阅读

我校编译原理课程, 出于各种限制, 对编译原理领域的介绍只能浅尝辄止. 我们遗漏了下面这些基础但至关重要的内容:

  • 作用域与命名空间
  • 类型系统
  • 对多种基本类型的支持以及隐式转换的插入
  • 类型修饰 (如 const, mut)
  • 仿射类型 (如指针, 引用等)
  • 控制流
  • 局部结构化控制流: if, while
  • 局部非结构化控制流: goto
  • 函数
  • 函数调用约定 (传参/返回值的实现)
  • 函数活动记录维护 (栈的实现)
  • 平台无关优化
  • CFG 的创建与维护
  • 各类数据流分析 (密集优化): 到达定值
  • 基本的过程间分析: 函数内联
  • 后端代码生成
  • 如何绕开汇编的限制
  • 图着色的寄存器分配
  • 栈的维护

一般一个对上述流程的完整实现 (加上一个手写 LL() 或自动生成的前端) 便可认为是涵盖了传统编译器课程的全部内容.

现代编译器通常还会包括下面的部分:

  • 调试信息的生成与保存
  • 自己的 IR 形式:
  • 传统三地址: 变量与指令分离的 IR 形式, 类似本实验中使用的 IR
  • SSA 三地址: 满足 SSA 性质的三地值 IR
  • Sea of Nodes: GraalVM 与 LLVM IR, 用于稀疏分析
  • 链接优化 (跨翻译单元的优化)

这些内容可能需要大家去实际项目中学习, 比如上面提到的 LLVM 或 GraalVM.

如果大家有学过一些比较现代的语言, 可能还会知道下面的特性 (括号内仅为举例):

  • 面向对象特性的实现
    • 主流 (C++): 成员复制实现的继承, 虚函数表实现的多态
    • 基于原型 (JavaScript): 通过原型来实现对象的构建, 原型链实现继承, 原型方法差异实现多态
    • 基于消息传递 (Obj-C)
    • 元对象协议与广义方法 (Lisp, CLOS)
  • 函数式特性的实现:
    • 一等函数与闭包 (JavaScript)
    • 惰性计算 (Haskell)
    • 延续 (Continuation) (Lisp/Scheme)
    • 完善的宏系统 (Lisp/Rust)
  • 更加强大的类型系统:
    • 泛型: 擦除泛型 (Java), 实例化泛型 (C++/C#)
    • 显式的可空类型 (Kotlin)
    • 代数数据类型 (Haskell)
    • 编译期计算 (Zig) 与依值类型 (agda/idris)
  • 运行时系统的实现:
    • 垃圾收集算法 (Java)
    • 反射 (Java)
    • 即时编译技术 (Graal/PyPy)
    • 动态求值 (eval) (Python/JavaScript)

上边的任何特性都有其常用的实现方式与优化空间, 需要在传统编译器课程之后再进行一定的学习才能掌握.

目前编译领域比较火热或国内有需求的细分领域:

  • 自动向量化: 自动地将代码转换为使用 SIMD 或其他 CPU 上的并行指令
  • 异构计算: 在各类超算或 GPU 上这种与传统 CPU 不同的平台上的编译
  • AI 编译器: 将各个框架的 AI 代码编译为 GPU 可识别的指令/函数库
  • 高层 IR (MLIR): 在前端就获得与表示更多代码的高层信息
  • 静态代码分析: 在编译之前就对代码进行进一步的检查
  • 渐进式代码分析: 为没有类型系统的语言渐进地加入静态类型检查