Page 14 - 《软件学报》2025年第12期
P. 14
于恒彪 等: 面向编译优化结果不一致的代码高效定位 5395
10. return flag, list
11. P right ← transform(P, right)
12. if Execute(P right , C 2 ) == Execute(P, C 1 ) then
13. flag, list = DDFuncLoc(P, right, C 1 , C 2 )
14. return flag, list
15. else
16. flag 1 , list 1 = DDFuncLoc(P left , right, C 1 , C 2 )
17. flag 2 , list 2 = DDFuncLoc(P right , left, C 1 , C 2 )
18. flag = flag 1 ∧ flag 2
19. list = list 1 ∪ list 2
20. return flag, list
回到二分搜索不能有效定位多源问题代码的例子, 即程序 P 包含 4 个函数<func 1 , func 2 , func 3 , func 4 >且问题代
码位于函数 func 2 和 func 3 中; Delta-Debugging 在判定元组 (<func 1 , func 2 >, <func 3 , func 4 >) 和 (<func 3 , func 4 >,
<func 1 , func 2 >) 不能消除不一致性后, 会回溯递归搜索. 首先, 在增强左侧列表<func 1 , func 2 >精度的前提下, 递归搜
索右侧列表<func 3 , func 4 >. 显然元组 (<func 1 , func 2 , func 3 >, <func 4 >) 修复成功, 因此基于左侧精度增强的右侧搜索
会返回 true 和<func 3 >. 类似的, 在增强右侧列表<func 3 , func 4 >精度的前提下, 递归搜索左侧列表<func 1 , func 2 >. 显
然元组 (<func 3 , func 4 , func 2 >, <func 1 >) 修复成功, 因此基于右侧精度增强的左侧搜索会返回 true 和<func 2 >. 因此,
Delta-Debugging 搜索最终会成功返回 true 和<func 2 , func 3 >.
3.4 多文件项目支持
现有最先进编译优化结果不一致性定位工具 PLiner 不支持多问题文件的精化搜索定位; FI3D 在文件层面扩
展了 Delta-Debugging 搜索定位机制. 首先, 基于第 3.3 节介绍的 Delta-Debugging 搜索定位到触发结果不一致性的
文件列表 filelist=<file 1 , file 2 ,…, file n >. 接着按照如下策略进行每个文件上的精化搜索 (i 初始取值为 0):
(1) 如果 i>n 跳转执行步骤 4, 否则, 精化搜索 file i . 对于列表中其他文件 file j (j≠i∧1≤j≤n), 首先对其进行备份,
l l
接着如果存在已经定位好的 file , 则使用 file 替换 file j , 否则直接使用 file j 的高精度版本进行替换.
j j
(2) 对 file i 进行单文件精化搜索定位, 即依次在函数级、循环级、基本块级和语句级依次进行精化搜索, 记录
l
只将 file i 最终定位的问题语句进行精度提升的文件版本为 file .
i
(3) 将文件 file j (j≠i ∧ 1≤j≤n) 恢复成备份的原始文件, 执行 i=i+1 并跳转执行步骤 1.
l
(4) 多文件最终的搜索定位结果记录为 {file | 1≤i≤n} ( file 和 l file i 差异性即为每个文件的定位结果).
i i
显然, 多文件精化搜索定位的过程是一个增量式控制变量定位过程, 每次都将当前搜索定位文件外的其他文
件替换为针对定位结果进行高精度修复的版本或者完全高精度版本, 然后再对当前文件进行单文件上的精化搜索
定位. 实验中选取了多文件用例进行了评测, FI3D 成功定位到了多个目标文件中触发编译优化结果不一致性的代
码, 显示了本文方法的有效性.
4 实验分析
4.1 工具实现
本文基于 LLVM 编译器、Python difflib 模块和经典编译优化结果不一致性定位工具 PLiner 实现了 FI3D. 如
图 4 所示, FI3D 主要包括 3 个模块: 不同编译选项下的浮点指令记录模块、浮点指令序列差异性计算模块、基
于 Delta-Debugging 的代码搜索定位模块; FI3D 支持用户指定待搜索文件/函数列表, 并且设置差异性系数阈值来
过滤待搜索函数/文件 (默认情况 FI3D 会过滤掉差异性系数为 0 的函数/文件).
(1) 浮点指令记录模块. 本文在 LLVM 17.0.1 中实现了一个函数优化遍 fpids, 该优化遍能够在 LLVM IR 层面

