LLVM用数组索引替换指针算法
我想使用LLVM3.1使用指针算法来转换循环,而不是使用数组索引。例如(为了清晰起见,用C而不是位代码显示): 第二个f的位代码:LLVM用数组索引替换指针算法,llvm,Llvm,我想使用LLVM3.1使用指针算法来转换循环,而不是使用数组索引。例如(为了清晰起见,用C而不是位代码显示): 第二个f的位代码: define void @f() nounwind uwtable { entry: %buf = alloca [10 x i32], align 16 %arraydecay = getelementptr inbounds [10 x i32]* %buf, i32 0, i32 0 br label %for.cond for.cond:
define void @f() nounwind uwtable {
entry:
%buf = alloca [10 x i32], align 16
%arraydecay = getelementptr inbounds [10 x i32]* %buf, i32 0, i32 0
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
%cmp = icmp slt i32 %i.0, 10
br i1 %cmp, label %for.body, label %for.end
for.body: ; preds = %for.cond
%idxprom = sext i32 %i.0 to i64
%arrayidx = getelementptr inbounds i32* %arraydecay, i64 %idxprom
store i32 0, i32* %arrayidx, align 4
br label %for.inc
for.inc: ; preds = %for.body
%inc = add nsw i32 %i.0, 1
br label %for.cond
for.end: ; preds = %for.cond
ret void
}
没有任何LLVM转换可以做到这一点。我写了自己的instcombine转换来实现它。我不确定LLVM中是否有分析可以实现这一点。你能不能也发一下位码来帮助我们了解分析需要识别什么?不管怎样,“指针算术”和“数组索引”之间没有区别。在IR级别,所有操作都是通过GEP指令完成的。我唯一能想到的是用有界GEP替换GEP,如果静态分析可以证明这个指针有一个已知的界。@SK logic:区别在于第一种情况下,指针值是使用循环中索引为1的GEP更新的,而在第二种情况下,存储在循环中的指针被计算为GEP from p with indexi@daniel,我不确定经过多次instSK logic后,是否会有任何这样的差异,谢谢您的帮助,但它仍然不能产生我想要的结果,即直接从IV计算指针。我使用的命令是“opt-instcombine-instcombine-scalarrepl-instcombine-instcombine-indvars-instcombine-instcombine”(大量instcombine只是为了确保)是否还需要其他传球?
void f() {
int buf[10];
int i;
int *p = buf;
for (i = 0; i < 10; i++)
p[i] = 0;
}
void g(int *p, int n) {
int *end = p + n;
for (; p < end, p++)
*p = 0;
}
void g(int *p, int n) {
int i;
for (i = 0; i < n, i++)
p[i] = 0;
}
opt -mem2reg -indvars <bc-file> -S
define void @f() nounwind uwtable {
entry:
%buf = alloca [10 x i32], align 16
%arraydecay = getelementptr inbounds [10 x i32]* %buf, i32 0, i32 0
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%p.0 = phi i32* [ %arraydecay, %entry ], [ %incdec.ptr, %for.inc ]
%i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
%cmp = icmp slt i32 %i.0, 10
br i1 %cmp, label %for.body, label %for.end
for.body: ; preds = %for.cond
%incdec.ptr = getelementptr inbounds i32* %p.0, i32 1
store i32 0, i32* %p.0, align 4
br label %for.inc
for.inc: ; preds = %for.body
%inc = add nsw i32 %i.0, 1
br label %for.cond
for.end: ; preds = %for.cond
ret void
}
define void @f() nounwind uwtable {
entry:
%buf = alloca [10 x i32], align 16
%arraydecay = getelementptr inbounds [10 x i32]* %buf, i32 0, i32 0
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
%cmp = icmp slt i32 %i.0, 10
br i1 %cmp, label %for.body, label %for.end
for.body: ; preds = %for.cond
%idxprom = sext i32 %i.0 to i64
%arrayidx = getelementptr inbounds i32* %arraydecay, i64 %idxprom
store i32 0, i32* %arrayidx, align 4
br label %for.inc
for.inc: ; preds = %for.body
%inc = add nsw i32 %i.0, 1
br label %for.cond
for.end: ; preds = %for.cond
ret void
}