我面临着相当有教育意义的任务,要以以下方式扩展LLVM:
我的测试来源是:
int main() {
int acc = 0;
__builtin___srxacc(acc);
__builtin___xmac(12345,6789);
acc = __builtin___lrxacc();
return 0;
}我能够支持将内置程序转换为内在功能。我从clang得到的IR文件看起来很好:
define i32 @main() #0 {
entry:
%retval = alloca i32, align 4
%acc = alloca i32, align 4
store i32 0, i32* %retval
store i32 0, i32* %acc, align 4
%0 = load i32* %acc, align 4
call void @llvm.sparc.srxacc(i32 %0)
call void @llvm.sparc.xmac(i32 12345, i32 6789)
%1 = call i32 @llvm.sparc.lrxacc()
store i32 %1, i32* %acc, align 4
ret i32 0
}在DAG合并步骤时出现问题,最终输出代码如下所示:
.text
.file "file22.ll"
.globl main
.align 4
.type main,@function
main: ! @main
! BB#0: ! %entry
add %sp, -104, %sp
st %g0, [%sp+100]
st %g0, [%sp+96]
lrxacc %xacc, %o0
st %o0, [%sp+96]
sethi 0, %o0
retl
add %sp, 104, %sp
.Ltmp0:
.size main, .Ltmp0-main
.ident "clang version 3.6.0 (trunk)"DAGCombiner将srxacc和xmac指令删除为冗余。(在::Run方法中,它检查节点是否为use_empty(),如果是的话删除它)
组合器是这样做的,因为它们存储的结果是寄存器,所以从图中看不到,其中一个依赖于另一个。
如能就如何避免删除我的指示提出任何建议,我将不胜感激。
谢谢!
编辑
为了简化和具体化:指令,在IR代码中表示为void @llvm.sparc.srxacc(i32 %0)的指令看起来像它们不影响计算一样,相应的SDNodes接收空的UseList。怎么才能绕开呢?
发布于 2014-11-06 18:28:21
SDNode之间的控制依赖关系,这样就可以在两个指令之间添加假依赖项,即使第二个指令没有消耗第一个指令的任何输出。CopyToRegister和CopyFromRegister来处理预定义的物理寄存器Glue将几个简单的指令粘合成一个复杂的伪指令。考虑为x86编译的以下简单示例:
int foo(int aa, int bb) {
return aa / bb;
}

您可能还想研究更复杂的示例,尽管DAG图片太大,无法在这里发布(您可以使用-view-sched-dags选项查看DAG ):
void foo(int aa, int bb, int *x, int *y, int *z) {
*x = aa / bb;
*y = aa % bb;
*z = aa * bb;
}也请看一下this post。
https://stackoverflow.com/questions/25472475
复制相似问题