我想使用 LLVM 3.1 来使用指针算术来转换循环,而不是使用数组索引。例如(为了清楚起见,以 C 语言而不是位码显示):
void f() {
int buf[10];
int i;
int *p = buf;
for (i = 0; i < 10; i++)
*p++ = 0;
}
应该转变为
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
但我没有看到任何变化。我确实看到了示例的更改,例如 IndVarSimplify.cpp 文件注释中的示例,仅使用整数循环变量。但我看不到任何使用数组下标进行指针算术的示例,如文档中订阅的那样。是否有可能达到我想要的结果?
编辑:
下面是上面两个“f”函数的位码(在 mem2reg 之后)。关键区别在于循环内的 GEP,在第一种情况下,它是从上一次迭代中递增指针,而在第二种情况下,每次使用基指针和索引 i 计算指针。这就是我想要的 - 根据归纳变量 i 存储地址。
第一个 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: ; 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
}
第二个 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: ; 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 用数组索引替换指针算术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22706444/