如何访问LLVM IR的阵列?
我对LLVM如何访问数组感到困惑。
对于一个2维数组,就像
int a[5][5];
int func1(){
return a[1][2];
}
翻译后的LLVM-IR一样,
@a = global [5 x [5 x i32]] zeroinitializer, align 16
define i32 @func1() #0 {
entry:
%0 = load i32, i32* getelementptr inbounds ([5 x [5 x i32]], [5 x [5 x i32]]* @a, i64 0, i64 1, i64 2), align 4
ret i32 %0
}
我认为做的是首先使用索引1来获取内部维度“ [5 x I32]”,然后使用索引2来获取“ i32”。
但是,当一个2维数组作为函数参数(或数组指针)时,事情变得很奇怪,
int func2(int a[][5]){
return a[2][3];
}
define i32 @func2([5 x i32]* %a) #0 {
entry:
%a.addr = alloca [5 x i32]*, align 8
store [5 x i32]* %a, [5 x i32]** %a.addr, align 8
%0 = load [5 x i32]*, [5 x i32]** %a.addr, align 8
%arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* %0, i64 2
%arrayidx1 = getelementptr inbounds [5 x i32], [5 x i32]* %arrayidx, i64 0, i64 3
%1 = load i32, i32* %arrayidx1, align 4
ret i32 %1
}
我不知道我的理解是否正确。
看来“ A”的位置已加载到%0,并且当前%0具有类型“ [5 x I32]*”,
%0 = load [5 x i32]*, [5 x i32]** %a.addr, align 8
然后使用“%0”访问“ A”的外部维度,但现在“%0”被认为是“ [5 x i32]”,“%arrayidx”将具有“ i32”类型。
%arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* %0, i64 2
然后更奇怪,“%arrayidx”仍然被认为是“ [5 x i32]”,但实际上是“ i32”
%arrayidx1 = getelementptr inbounds [5 x i32], [5 x i32]* %arrayidx, i64 0, i64 3
如何解释它?以及如何使用api喜欢builder.createinboundsgep(type,array,idxs);
生成它?似乎不可能,因为我尝试了
// type is "[5 x i32]" and array also has a type of "[5 x i32]", inorder to generate the same ir
// as %arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* %0, i64 2
auto arrayidx = Builder.CreateInBoundsGEP(type, array, Idxs)
// but now arrayidx is "i32" and now type and the type of arrayidx is not match
auto arrayidx1 = Builder.CreateInBoundsGEP(type, arrayidx, Idxs)
I am confused about how llvm visits an array.
For a 2-dimension array, like
int a[5][5];
int func1(){
return a[1][2];
}
The translated llvm-ir is
@a = global [5 x [5 x i32]] zeroinitializer, align 16
define i32 @func1() #0 {
entry:
%0 = load i32, i32* getelementptr inbounds ([5 x [5 x i32]], [5 x [5 x i32]]* @a, i64 0, i64 1, i64 2), align 4
ret i32 %0
}
I think what had been done is to first use index 1 to fetch the inner dimension "[5 x i32]" and then use index 2 to fetch "i32".
But when a 2-dimension array as a function parameter(or array pointer), then things go weird
int func2(int a[][5]){
return a[2][3];
}
define i32 @func2([5 x i32]* %a) #0 {
entry:
%a.addr = alloca [5 x i32]*, align 8
store [5 x i32]* %a, [5 x i32]** %a.addr, align 8
%0 = load [5 x i32]*, [5 x i32]** %a.addr, align 8
%arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* %0, i64 2
%arrayidx1 = getelementptr inbounds [5 x i32], [5 x i32]* %arrayidx, i64 0, i64 3
%1 = load i32, i32* %arrayidx1, align 4
ret i32 %1
}
I don't know if my understanding is correct.
It seems that the location of "a" is loaded to %0 and currently %0 has type "[5 x i32]*"
%0 = load [5 x i32]*, [5 x i32]** %a.addr, align 8
Then use "%0" to visit the outer dimension of "a", but now "%0" is considered to be "[5 x i32]", and "%arrayidx" will have type "i32".
%arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* %0, i64 2
Then it is more strange, "%arrayidx" is still considered as "[5 x i32]", but it is actually "i32"
%arrayidx1 = getelementptr inbounds [5 x i32], [5 x i32]* %arrayidx, i64 0, i64 3
How to explain it? And how to use API like Builder.CreateInBoundsGEP(type, array, Idxs);
to generate it? It seems impossible because I tried
// type is "[5 x i32]" and array also has a type of "[5 x i32]", inorder to generate the same ir
// as %arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* %0, i64 2
auto arrayidx = Builder.CreateInBoundsGEP(type, array, Idxs)
// but now arrayidx is "i32" and now type and the type of arrayidx is not match
auto arrayidx1 = Builder.CreateInBoundsGEP(type, arrayidx, Idxs)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
%0
和%arrayIdx
是[5 x i32]*
。b = getElementPtr< type>,type>* a,i64 idx0
typb =& a [idx0]
。%arrayidx1
是i32*
。c = getElementPtr< type>,type>* b,i64 idx0,i64 idx1
or类似于c =& b [idx0] [idx1] [idx1]
Both
%0
and%arrayidx
are[5 x i32]*
.B = getelementptr <type>, <type>* A, i64 idx0
is something likeB = &A[idx0]
.%arrayidx1
isi32*
.C = getelementptr <type>, <type>* B, i64 idx0, i64 idx1
is something likeC = &B[idx0][idx1]