【发布时间】:2016-02-05 15:23:29
【问题描述】:
我在玩具编译器上取得了进展(第一次),并试图了解如何分配/构造 LLVM 结构类型。 Kaleidoscope 教程没有包括甚至提到这一点,我不知道我在 LLVM 源代码/测试中寻找什么以找到可能的示例。
所以我写了一个简单的 C++ 示例,用 clang 转储了 IR,试图理解它产生了什么,但老实说,我并没有完全遵循它。对我来说显而易见的是函数定义/声明和一些函数调用以及memset 调用,所以我得到了它的一部分,但对我来说还没有全部组合在一起。 (PS 我对 alloca 指令文档的解释是它创建的任何东西都会在返回时被释放,所以我不能使用它,它基本上只用于局部变量?)
我所做的是:
alloc.cpp
struct Alloc {
int age;
};
//Alloc allocCpy() {
// return *new Alloc();
//}
Alloc *allocPtr() {
return new Alloc();
}
int main() {
Alloc *ptr = allocPtr();
// ptr->name = "Courtney";
// Alloc cpy = allocCpy();
// cpy.name = "Robinson";
// std::cout << ptr->name << std::endl;
// std::cout << cpy.name << std::endl;
return 0;
}
然后运行clang -S -emit-llvm alloc.cpp生成alloc.ll
; ModuleID = 'alloc.cpp'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.11.0"
%struct.Alloc = type { i32 }
; Function Attrs: ssp uwtable
define %struct.Alloc* @_Z8allocPtrv() #0 {
entry:
%call = call noalias i8* @_Znwm(i64 4) #3
%0 = bitcast i8* %call to %struct.Alloc*
%1 = bitcast %struct.Alloc* %0 to i8*
call void @llvm.memset.p0i8.i64(i8* %1, i8 0, i64 4, i32 4, i1 false)
ret %struct.Alloc* %0
}
; Function Attrs: nobuiltin
declare noalias i8* @_Znwm(i64) #1
; Function Attrs: nounwind
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) #2
; Function Attrs: ssp uwtable
define i32 @main() #0 {
entry:
%retval = alloca i32, align 4
%ptr = alloca %struct.Alloc*, align 8
store i32 0, i32* %retval
%call = call %struct.Alloc* @_Z8allocPtrv()
store %struct.Alloc* %call, %struct.Alloc** %ptr, align 8
ret i32 0
}
attributes #0 = { ssp uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nobuiltin "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind }
attributes #3 = { builtin }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"PIC Level", i32 2}
!1 = !{!"clang version 3.7.0 (tags/RELEASE_370/final)"}
有人能解释一下这个 IR 中发生了什么以及它如何映射回 C++ 吗?或者忽略这个特定示例,如何/应该如何为 LLVM StructType 分配堆内存,该 LLVM StructType 超出了创建它的函数(如果您觉得很慷慨,以后如何释放内存)。
我注释掉的部分来自我原来的例子,但作为一个完全新手,IR 的洞察力更差......
【问题讨论】:
标签: c++ memory-management clang llvm llvm-ir