从LLVM生成OCaml GC宏

时间:2015-09-17 23:59:04

标签: ocaml llvm

要正确使用OCaml GC,您需要使用CAMLparam0CAMLlocal等宏。如何从LLVM生成此文件?添加GC" ocaml" llvalue函数似乎不会改变生成的IR。

用于连接某些字符串的示例C代码:

 int main(void) {

    CAMLparam0();

    subsetphp_gc_init();

    CAMLlocal1(val1);
    CAMLlocal1(val2);

    val1 = subsetphp_string_init("asd", 3, 1);
    val2 = subsetphp_string_init("qwe", 3, 1);

    for (int i = 0; i < 100000; i++) {
      val1 = subsetphp_concat_function(val1, val2);
    }

    CAMLreturn(0);
  }

这是我生成的LLVM IR,它将使用下面的valgrind消息进行sigfault:

; ModuleID = 'llvm_test.bc'

%caml_value = type opaque

@asd = private unnamed_addr constant [4 x i8] c"asd\00"
@qwe = private unnamed_addr constant [4 x i8] c"qwe\00"

declare %caml_value* @subsetphp_string_init(i8*, i32, i32)

declare %caml_value* @subsetphp_concat_function(%caml_value*, %caml_value*)

declare void @subsetphp_gc_init()

define i32 @main() gc "ocaml" {
entry:
  %"$i1" = alloca double
  %"$i" = alloca double
  %"$b" = alloca %caml_value*
  call void @subsetphp_gc_init()
  %str = call %caml_value* @subsetphp_string_init(i8* getelementptr inbounds ([4 x i8]* @asd, i32 0, i32 0), i32 3, i32 1)
  store %caml_value* %str, %caml_value** %"$b"
  store double 0.000000e+00, double* %"$i1"
  store double 0.000000e+00, double* %"$i1"
  store double 0.000000e+00, double* %"$i"
  br label %loop

loop:                                             ; preds = %loop, %entry
  %str2 = call %caml_value* @subsetphp_string_init(i8* getelementptr inbounds ([4 x i8]* @qwe, i32 0, i32 0), i32 3, i32 1)
  %"$b3" = load %caml_value** %"$b"
  %concat = call %caml_value* @subsetphp_concat_function(%caml_value* %str2, %caml_value* %"$b3")
  store %caml_value* %concat, %caml_value** %"$b"
  %"$i4" = load double* %"$i"
  %addtmp = fadd double %"$i4", 1.000000e+00
  store double %addtmp, double* %"$i"
  %"$i5" = load double* %"$i"
  %EQeqeq = fcmp olt double %"$i5", 1.000000e+05
  %booltmp = uitofp i1 %EQeqeq to double
  store double %addtmp, double* %"$i"
  %loopcond = fcmp one double %booltmp, 0.000000e+00
  br i1 %loopcond, label %loop, label %afterloop

afterloop:                                        ; preds = %loop
  ret i32 0
}

Valgrind的:

==5938== Invalid read of size 1
==5938==    at 0x4C2F950: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5938==    by 0x4D7FDF: subsetphp_concat_function (bindings.c:203)
==5938==    by 0x4D8430: main (llvm_test.s:46)
==5938==  Address 0x6a84558 is 24 bytes inside a block of size 8,224 free'd
==5938==    at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5938==    by 0x4D83BA: subsetphp_finalize_string (bindings.c:38)
==5938==    by 0x4D2C70: caml_empty_minor_heap (in /home/olle/kod/subsetphp/test)
==5938==    by 0x4D2DC8: caml_minor_collection (in /home/olle/kod/subsetphp/test)
==5938==    by 0x4BFB36: caml_alloc_small (in /home/olle/kod/subsetphp/test)
==5938==    by 0x4C328B: caml_alloc_custom (in /home/olle/kod/subsetphp/test)
==5938==    by 0x4D7CB0: subsetphp_string_alloc (bindings.c:114)
==5938==    by 0x4D7DFE: subsetphp_string_init (bindings.c:161)
==5938==    by 0x4D8423: main (llvm_test.s:42)

对不起大量的代码。任何帮助表示赞赏。

编辑:最后找到一些关于IR如何看起来像here的例子。

0 个答案:

没有答案