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  层面
   9   10   11   12   13   14   15   16   17   18   19