编译器优化故障的测试与定位

作者 | 江贺

整理 | Hana

作者简介: 

江贺,大连理工大学软件学院教授,博士生导师,研究领域:智能软件工程(软件大数据处理、编译系统测试、工业软件测试) 

个人主页:大连理工大学主页平台管理系统 江贺--jianghe--首页

本次技术分享来自 SIG-编程语言测试技术沙龙,本文内容为提取讲演视频后的文章,视频也已经发布在 B 站,欢迎大家点开学习。

SIG-编程语言测试技术沙龙回顾|编译器优化故障的测试与定位_哔哩哔哩_bilibiliSIG-编程语言测试技术沙龙回顾|编译器优化故障的测试与定位https://www.bilibili.com/video/BV1io4y1X7t3


# Introduction #

今天想分享的主题是 编译器故障的检测和定位

当前编译器的发展现状如下图示,大家可以看出编译器的发展趋势正在由通用型转向领域特定型。

图片
编译环境发展现状

但是我们分析发现,这些编译器实际上依旧占据着主流的应用市场:

图片
主流编译器流行度 —— 以 C/C++ 编译器为例

 国内也涌现出很多的编译器:

图片
国产编译器

神威睿智编译器 基于申威指令系统开发 [1]  了基于 GCC 和 Open64 的产品编译器,以及针对国产主机的二进制翻译系统(PowerPC/X86);

龙芯中科 也有基于自有架构后端定制了优化的编译器,包括基于 GCC 和 Open64 的产品编译器,以及 DigitalBridge 进程级二进制翻译系统(X86);

寒武纪  [2] 针对 AI 构建了自己的编译工具链,包括 CNCC(寒武纪 BANG C 语言编译器,基于 Clang 和 LLVM 开发)和 CNAS(寒武纪 MLISA 语言编译器);

华为也推出了自研的方舟编译器 [3]。

图片

编译器的质量会大大影响其使用和流行程度,因此在做编译器的过程中,编译器的质量是一个非常重要的要求。

确保编译器的质量有两种方式:第一种方式就是做 可信验证,这种方式的好处在于它理论上是可以完全保证编译器质量的(如 CompCert [4]),但是无法规模化应用;更常用的办法是 对编译器做测试,虽然无法保证完备性,但它可以大规模化。

图片
编译器可信验证 vs. 编译器测试

# 编译器测试

编译器测试一般会有三个阶段,

  1. 测试用例生成 如何生成测试用例来触发编译器故障

  2. Test Oracle 问题 即测试准则问题 [5]。当输入测试用例后,编译器产生的输出与我们的预期输出是否一样

  3. 测试用例约减 当我们发现了一个编译器的故障后,通常来讲测试用例可能会很长,但是要提交给社区时,必须做一些相关的约减,将测试用例减到方便开发者阅读和定位的范围内(比如 20 行左右)。

图片
编译器测试的一般流程

## 编译器测试的主要方法

这里简单介绍一下三种主流编译器测试技术:

Random Differential Testing (RDT) 即随机差异测试。简单说,就是用同个编程语言的不同的编译器(比如 GCC 和 LLVM)来进行比较,若编译器的行为不一致,则表示至少其中一个编译器是存在故障的。

Different Optimization Levels (DOL) 即优化级别测试。是 RDT 的一个变种,具体方法是对比同一个编译器的不同优化等级,若行为不一致,则表示至少有一种编译器优化存在故障。

Equivalent Modulo Inputs (EMI) [6]  即等价取模测试,由 UC Davis 的苏振东教授团队提出。EMI 的方法与 RDT 等不同,是对程序进行变换,然后观察被测编译器,是否会跑出不同的结果。

图片
编译器测试的主要方法

# 编译器架构

编译器可以分为前端、中间层及后端。业界对编译器中间这一层的分析和测试比较多,针对前端和后端的分析测试在学术界相对不是特别多。工业界也是如此,由于后端架构的多样,中间代码到指令集的翻译需要适配不同的架构,这个过程需要很严肃的测试是否有故障;另外,像 LLVM 编译器的中间优化大概有 150 多个,GCC 大概有 250 个,中间优化对传统编译器来说是相当重要的一部分,同时也是出现故障可能性很大的一部分。

图片
典型的编译器架构

正确地使用编译器优化对程序的性能(如执行速度、代码大小、功耗等)会有显著影响。

编译器优化对工业界的应用十分有意义,当你选择比较好的优化,包括优化的序列时,对程序最后的输出会有很大影响。比如通过编译器优化,甚至可以改进给定程序编译后的大小,程序执行速度,功耗等。对于嵌入式行业来说,代码的大小分分钟会影响到增减一个芯片的问题,所以优化带来的这些收益对于工业界是十分关键的。

图片
编译优化选择(Phase Ordering Problem)

有关编译优化的选择,业界当前有两类主要的方法(如上图示):

  • 第一种是 机器学习方法,即找出一些示例程序,结合不同的编译器优化序列,从而构建出训练样本,输入给算法进行学习;

  • 另外一种是 演化计算方法,不需要有训练集,给定一个程序,将对其进行的优化序列编码为一个解,然后对优化序列进行交叉编译来迭代。

讲完前面一些背景之后,接下来简单介绍一下我们团队做的几个方面的工作。

# 编译器警告缺陷检测 - DIPROM #

编译器警告缺陷,即由警告缺失、错误、冗余等而导致的编译器警告缺陷。给一个程序,这个程序有可能最后能够成功地进行编译,但代码里面也可能会存在一些警告信息,说明程序里存在的一些风险。

要做编译器警告测试,有两个挑战:

如何构造警告敏感的程序结构?

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值