LLVM中alloca / memset的预期用法

时间:2014-02-03 23:57:49

标签: llvm memset alloca

使用alloca()在堆栈上分配空间时,是否需要清除内存或保证仅包含零?

我提出了以下LLVM代码。虽然它编译,但它会导致核心转储。

在代码中,我试图实现对象的实例化,然后将其分配给“成员变量”。

%Main = type { %A*, i32 }
%A = type { %String, %String }
%String = type { i32, i8* }

define i32 @main() {
body:
  %Main = alloca %Main
  %0 = bitcast %Main* %Main to i8*
  call void @llvm.memset.p0i8.i32(i8* %0, i8 0, i32 4, i32 4, i1 false)
  call void @test(%Main* %Main)
  ret i32 0
}

define void @test(%Main* %self) {
body:
  %0 = load %Main* %self
  %1 = extractvalue %Main %0, 0

  ; Overwrite the object A in Main by a new instance.
  %A = alloca %A

  ; Set to zero.
  %2 = bitcast %A* %A to i8*
  call void @llvm.memset.p0i8.i32(i8* %2, i8 0, i32 4, i32 4, i1 false)

  ; ... execute the constructor of A ...

  ; Set the new instance in Main.
  %3 = load %A* %A
  store %A %3, %A* %1

  br label %return

return:                                           ; preds = %body
  ret void
}

; Function Attrs: nounwind
declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) #0

declare i32 @printf(i8*, ...)

1 个答案:

答案 0 :(得分:1)

不,使用alloca创建的内存不是0初始化 - 由您来初始化它。

至于下一个问题,我强烈建议使用Clang将C代码片段编译为LLVM IR,而不是手工制作后者。这是一个例子:

#include <memory.h>

struct Foo {
  int a, b;
};

void test() {
  Foo f;
  memset(&f, 0, sizeof(f));
}

编译(没有优化)会产生:

%struct.Foo = type { i32, i32 }

; Function Attrs: nounwind uwtable
define void @_Z4testv() #0 {
entry:
  %f = alloca %struct.Foo, align 4
  %0 = bitcast %struct.Foo* %f to i8*
  call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 8, i32 4, i1 false)
  ret void
}

; Function Attrs: nounwind
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) #1

attributes #0 = { nounwind uwtable "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" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
相关问题