1.4K Star 7.3K Fork 1.3K

GVP方舟编译器 / OpenArkCompiler

 / 详情

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

Backlog
member
Opened this issue  
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了)
输入图片说明

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

Comments (7)

lisa_xhy created任务
yi_jiang set assignee to williambillchen
yi_jiang assigned collaborator fredchow
yi_jiang set priority to Serious
Expand operation logs

从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的分配情况:

输入图片说明

Sign in to comment

Status
Assignees
Milestones
Pull Requests
Successfully merging a pull request will close this issue.
Branches
Planed to start   -   Planed to end
-
Top level
Priority
参与者(3)
C++
1
https://git.oschina.net/openarkcompiler/OpenArkCompiler.git
git@git.oschina.net:openarkcompiler/OpenArkCompiler.git
openarkcompiler
OpenArkCompiler
OpenArkCompiler

Search

161121 f78d6d6f 1850385 154831 86f8c370 1850385