Ver Fonte

Now using pointer instead of array index

Taddeus Kroes há 11 anos atrás
pai
commit
9a3c281f60
2 ficheiros alterados com 43 adições e 42 exclusões
  1. 21 20
      README.md
  2. 22 22
      bf.ml

+ 21 - 20
README.md

@@ -72,36 +72,37 @@ The compiler generates very verbose code:
     entry:
         ; initialization
         %mem = alloca [30000 x i8]
-        %idx = alloca i32
+        %ptr = alloca i8*
         %0 = bitcast [30000 x i8]* %mem to i8*
         call void @llvm.memset.p0i8.i32(i8* %0, i8 0, i32 30000, i32 0, i1 false)
-        store i32 0, i32* %idx
+        %1 = getelementptr inbounds [30000 x i8]* %mem, i32 0, i32 0
+        store i8* %1, i8** %ptr
 
         ; command: +
-        %1 = load i32* %idx
-        %2 = getelementptr inbounds [30000 x i8]* %mem, i32 0, i32 %1
-        %3 = load i8* %2
-        %4 = add i8 %3, 1
-        %5 = load i32* %idx
-        %6 = getelementptr inbounds [30000 x i8]* %mem, i32 0, i32 %5
-        store i8 %4, i8* %6
+        %2 = load i8** %ptr
+        %3 = getelementptr inbounds i8* %2, i32 0
+        %4 = load i8* %3
+        %5 = add i8 %4, 1
+        %6 = load i8** %ptr
+        %7 = getelementptr inbounds i8* %6, i32 0
+        store i8 %5, i8* %7
 
         ; command: +
-        %7 = load i32* %idx
-        %8 = getelementptr inbounds [30000 x i8]* %mem, i32 0, i32 %7
-        %9 = load i8* %8
-        %10 = add i8 %9, 1
-        %11 = load i32* %idx
-        %12 = getelementptr inbounds [30000 x i8]* %mem, i32 0, i32 %11
-        store i8 %10, i8* %12
+        %8 = load i8** %ptr
+        %9 = getelementptr inbounds i8* %8, i32 0
+        %10 = load i8* %9
+        %11 = add i8 %10, 1
+        %12 = load i8** %ptr
+        %13 = getelementptr inbounds i8* %12, i32 0
+        store i8 %11, i8* %13
 
         ...
 
         ; command: . (outputs 'H' after 72 times a '+' command)
-        %433 = load i32* %idx
-        %434 = getelementptr inbounds [30000 x i8]* %mem, i32 0, i32 %433
-        %435 = load i8* %434
-        %436 = call i32 @putchar(i8 %435)
+        %434 = load i8** %ptr
+        %435 = getelementptr inbounds i8* %434, i32 0
+        %436 = load i8* %435
+        %437 = call i32 @putchar(i8 %436)
 
         ...
 

+ 22 - 22
bf.ml

@@ -37,6 +37,14 @@ let compile memsize program =
   let i32_ty = i32_type ctx in
   let void_ty = void_type ctx in
 
+  let i w n = const_int (integer_type ctx w) n in
+  let i8 = i 8 in
+  let i32 = i 32 in
+
+  let memset =
+    let arg_types = [|byteptr_ty; byte_ty; i32_ty; i32_ty; bool_ty|] in
+    declare_function "llvm.memset.p0i8.i32" (function_type void_ty arg_types) m
+  in
   let putchar = declare_function "putchar" (function_type i32_ty [|byte_ty|]) m in
   let getchar = declare_function "getchar" (function_type byte_ty [||]) m in
   let cexit = declare_function "exit" (function_type void_ty [|i32_ty|]) m in
@@ -51,30 +59,26 @@ let compile memsize program =
     bb_cur := bb
   in
 
-  let i w n = const_int (integer_type ctx w) n in
-  let i8 = i 8 in
-  let i32 = i 32 in
-
   let mem = build_alloca (array_type byte_ty memsize) "mem" b in
-  let idx = build_alloca i32_ty "idx" b in
+  let ptr = build_alloca byteptr_ty "ptr" b in
 
-  let load ptr = build_load ptr "" b in
-  let store ptr value = ignore (build_store value ptr b) in
-  let gep () = build_in_bounds_gep mem [|i32 0; load idx|] "" b in
+  let load p = build_load p "" b in
+  let store p value = ignore (build_store value p b) in
+  let gep n = build_in_bounds_gep (load ptr) [|i32 n|] "" b in
 
   let rec compile_command = function
     | Incptr ->
-      build_add (load idx) (i32 1) "" b |> store idx
+      store ptr (gep 1)
     | Decptr ->
-      build_sub (load idx) (i32 1) "" b |> store idx
+      store ptr (gep (-1))
     | Incdata ->
-      build_add (load (gep ())) (i8 1) "" b |> store (gep ())
+      build_add (load (gep 0)) (i8 1) "" b |> store (gep 0)
     | Decdata ->
-      build_sub (load (gep ())) (i8 1) "" b |> store (gep ())
+      build_sub (load (gep 0)) (i8 1) "" b |> store (gep 0)
     | Output ->
-      build_call putchar [|load (gep ())|] "" b |> ignore
+      build_call putchar [|load (gep 0)|] "" b |> ignore
     | Input ->
-      build_call getchar [||] "" b |> store (gep ())
+      build_call getchar [||] "" b |> store (gep 0)
     | Loop p ->
       let bb_end = append_block ctx "" f in
       move_block_after !bb_cur bb_end;
@@ -83,7 +87,7 @@ let compile memsize program =
 
       build_br bb_cond b |> ignore;
       position_at_end bb_cond b;
-      let cond = build_icmp Icmp.Eq (load (gep ())) (i8 0) "" b in
+      let cond = build_icmp Icmp.Eq (load (gep 0)) (i8 0) "" b in
       build_cond_br cond bb_end bb_body b |> ignore;
 
       set_cur_bb bb_body;
@@ -95,15 +99,11 @@ let compile memsize program =
 
   (* zero-initialize memory (use intrinsic for optimization assumptions) *)
   set_data_layout "e" m;  (* little-endian, needed for optimization *)
-  let memset =
-    let arg_types = [|byteptr_ty; byte_ty; i32_ty; i32_ty; bool_ty|] in
-    declare_function "llvm.memset.p0i8.i32" (function_type void_ty arg_types) m
-  in
-  let ptr = build_bitcast mem byteptr_ty "" b in
-  build_call memset [|ptr; i8 0; i32 memsize; i32 0; i 1 0|] "" b |> ignore;
+  let memptr = build_bitcast mem byteptr_ty "" b in
+  build_call memset [|memptr; i8 0; i32 memsize; i32 0; i 1 0|] "" b |> ignore;
 
   (* set pivot to index 0 and compile program commands *)
-  store idx (i32 0);
+  build_in_bounds_gep mem [|i32 0; i32 0|] "" b |> store ptr;
   List.iter compile_command program;
 
   (* exit gracefully *)