1.4K Star 7.6K Fork 1.4K

GVP方舟编译器 / OpenArkCompiler

 / 详情

【RA LOOP】大函数里,循环内一些实际执行频率高的变量,没有被分配到寄存器。

待办的
成员
创建于  
2021-06-04 10:30

spec: 500.perlbench_r
文件: regexec.c:4929
函数: S_regmatch

scan变量
输入图片说明

spec 544
文件: eff.c +768
函数:nbond

输入图片说明

spec 538
文件: magick/morphology.c
函数:MorphologyPrimitive:3021~3037

(这个地方需要中端先把struct.field Promote成寄存器变量。但是,手改后,仍被spill了)
输入图片说明

看起来,循环的权重考虑似乎还不够。

评论 (7)

lisa_xhy 创建了任务
yi_jiang 负责人设置为williambillchen
yi_jiang 添加协作者fredchow
yi_jiang 优先级设置为严重
展开全部操作日志

从cpu2017 看,这是个非常普遍的问题,对几个例子都有5+%以上的影响。 主要体现在以下特点的liverange
1)横跨大函数,LR很长;
2)经过某些hot loop body
由于1)我们在计算权重的时候长度是负向因素,导致LR未能被分配到寄存器,而spill/reload 又出现在了hot loop里面。倾向应该在loop内外做区别处理,至少spill 和reload希望放到循环外

场景1里,scan对应的寄存器,存活于1601个bb中, 在循环内的50多个bb有def、ues。

(gdb) p pri
$42 = 2.02294835e+09
(gdb) p log(pri)/bbNum
$45 = 0.013384023650472029

而,跟它有冲突的其中几个权重很大的reg是,仅在一个bb里(同一层循环或更内层的循环),一个或多个def/use点,如,

priority = 14.5086575,
luMap = std::map with 1 element = {
    [903] = 0x7ffff13a73b8
  },

 priority = 15.6072702,
 luMap = std::map with 1 element = {
   [985] = 0x7ffff0d862b0
 },

另一个问题是对同一个vreg的多次reload操作:

输入图片说明

R251在这里,不是被spill了,是因为被分配到的是caller save寄存器,但是跨call了,所以插入的是caller save相关处理。

第二个例子 -- 544 的例子,还需要其他优化删掉冗余分支的代码。手动删除后,没有ra问题。暂时忽略

第三例,538的例子,与第一例相似。用最新代码,中端已经将相应的结构体field(result.xx)的访问promote的寄存器。这几个寄存器,live range都拉得很长,然后分配到了一个caller save寄存器,又跨call,导致caller save相关处理.

spec 500 S_regmatch函数:

基于0910的最后一个版本:

scan变量(R6596)没有拿到callee save寄存器,分析了跟它冲突的且权重比它高的vreg,并比对了GCC的分配情况:

输入图片说明

登录 后才可以发表评论

状态
负责人
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
参与者(3)
C++
1
https://gitee.com/openarkcompiler/OpenArkCompiler.git
git@gitee.com:openarkcompiler/OpenArkCompiler.git
openarkcompiler
OpenArkCompiler
OpenArkCompiler

搜索帮助