Commit 4f98a38c authored by Taddeüs Kroes's avatar Taddeüs Kroes

Cleanup, added some comments, and implemented sorted offset commands

parent c86205d1
...@@ -3,7 +3,6 @@ open Llvm ...@@ -3,7 +3,6 @@ open Llvm
type program = command list type program = command list
and command = and command =
| Shift of int | Shift of int
| Goto of int
| Add of int | Add of int
| Set of int | Set of int
| Out | In | Out | In
...@@ -42,7 +41,6 @@ and string_of_command = function ...@@ -42,7 +41,6 @@ and string_of_command = function
| Shift -1 -> "<" | Shift -1 -> "<"
| Shift n when n < 0 -> "(<" ^ string_of_int (-n) ^ ")" | Shift n when n < 0 -> "(<" ^ string_of_int (-n) ^ ")"
| Shift n -> "(+" ^ string_of_int n ^ ")" | Shift n -> "(+" ^ string_of_int n ^ ")"
| Goto n -> "(_" ^ string_of_int n ^ ")"
| Add 1 -> "+" | Add 1 -> "+"
| Add -1 -> "-" | Add -1 -> "-"
| Add n when n < 0 -> "(-" ^ string_of_int (-n) ^ ")" | Add n when n < 0 -> "(-" ^ string_of_int (-n) ^ ")"
...@@ -53,7 +51,7 @@ and string_of_command = function ...@@ -53,7 +51,7 @@ and string_of_command = function
| In -> "," | In -> ","
| Loop p -> "[" ^ string_of_program p ^ "]" | Loop p -> "[" ^ string_of_program p ^ "]"
| Offset (o, cmd) -> | Offset (o, cmd) ->
"(" ^ string_of_int o ^ ":" ^ string_of_command cmd ^ ")" "(" ^ string_of_command cmd ^ "@" ^ string_of_int o ^ ")"
let compile_llvm memsize program = let compile_llvm memsize program =
let ctx = global_context () in let ctx = global_context () in
...@@ -97,9 +95,6 @@ let compile_llvm memsize program = ...@@ -97,9 +95,6 @@ let compile_llvm memsize program =
let rec compile_command = function let rec compile_command = function
| Shift n -> | Shift n ->
store ptr (gep n) store ptr (gep n)
| Goto n ->
let memptr = build_in_bounds_gep mem [|i32 0; i32 n|] "" b in
build_bitcast memptr byteptr_ty "" b |> store ptr
| Offset (o, Add n) -> | Offset (o, Add n) ->
build_add (load (gep o)) (i8 n) "" b |> store (gep o) build_add (load (gep o)) (i8 n) "" b |> store (gep o)
| Offset (o, Set n) -> | Offset (o, Set n) ->
...@@ -161,14 +156,12 @@ let compile_c memsize program = ...@@ -161,14 +156,12 @@ let compile_c memsize program =
| cmd :: tl -> compile_commands (buf ^ compile_command cmd ^ "\n") tl | cmd :: tl -> compile_commands (buf ^ compile_command cmd ^ "\n") tl
and compile_command = function and compile_command = function
| Loop p -> | Loop p ->
"while (*p) {\n" ^ indent (compile_commands "" p) ^ "}" "while (*p != 0) {\n" ^ indent (compile_commands "" p) ^ "}"
| Offset (o, cmd) -> | Offset (o, cmd) ->
begin begin
match cmd with match cmd with
| Shift n -> "p" ^ add n | Shift n -> "p" ^ add n
| Add n -> ptr o ^ add n | Add n -> ptr o ^ add n
| Goto 0 -> "p = mem"
| Goto n -> "p = mem + " ^ string_of_int n
| Set n -> ptr o ^ " = " ^ string_of_int n | Set n -> ptr o ^ " = " ^ string_of_int n
| Out -> "putchar(" ^ ptr o ^ ")" | Out -> "putchar(" ^ ptr o ^ ")"
| In -> ptr o ^ " = getchar()" | In -> ptr o ^ " = getchar()"
...@@ -189,72 +182,76 @@ let compile_c memsize program = ...@@ -189,72 +182,76 @@ let compile_c memsize program =
"}\n" "}\n"
let optimize program = let optimize program =
let opt_loop p = let should_swap i a j b =
let rec next buf counter_found = function i > j && begin
| Add -1 :: tl when not counter_found -> match a, b with
next buf true tl | Mul (xa, _), Mul (xb, _) -> i + xa <> j && j + xb <> i
| Offset (o, Add n) :: tl -> | (Add _ | Set _ | Out | In), Mul (x, _) -> j + x <> i
next (Offset (o, Mul (-o, n)) :: buf) counter_found tl | Mul (x, _), (Add _ | Set _ | Out | In) -> i + x <> j
| [] when counter_found -> | In, In | Out, Out -> false
List.rev (Offset (0, Set 0) :: buf) | (Add _ | Set _ | Out | In), (Add _ | Set _ | Out | In) -> true
| _ ->
[Loop p]
in
next [] false p
in
let can_offset = function
| Add _ | Set _ | Out | In | Mul _ -> true
| _ -> false | _ -> false
end
in in
let rec opt = function let rec opt = function
(* combine shift/add commands *)
| Shift a :: Shift b :: tl -> | Shift a :: Shift b :: tl ->
Shift (a + b) :: tl |> opt Shift (a + b) :: tl |> opt
| Add a :: Add b :: tl -> | Add a :: Add b :: tl ->
Add (a + b) :: tl |> opt Add (a + b) :: tl |> opt
| Set a :: Add b :: tl ->
Set (a + b) :: tl |> opt
(* remove dead code *)
| Set 0 :: Loop _ :: tl -> | Set 0 :: Loop _ :: tl ->
Set 0 :: tl |> opt Set 0 :: tl |> opt
| Goto a :: Shift b :: tl ->
Goto (a + b) :: tl |> opt
| Set a :: Add b :: tl ->
Set (a + b) :: tl |> opt
| (Shift 0 | Add 0) :: tl | (Shift 0 | Add 0) :: tl
| (Shift _ | Goto _) :: (Goto _ :: _ as tl) | (Add _ | Set _ | Mul _) :: (Set _ :: _ as tl) ->
| (Add _ | Set _) :: (Set _ :: _ as tl) ->
opt tl opt tl
| Goto o :: cmd :: tl when can_offset cmd -> (* postpone shifts by wrapping commands in offset nodes *)
Offset (o, cmd) :: Goto o :: tl |> opt | Shift o :: (Add _ | Set _ | Out | In | Mul _ as cmd) :: tl ->
| Shift o :: cmd :: tl when can_offset cmd ->
Offset (o, cmd) :: Shift o :: tl |> opt Offset (o, cmd) :: Shift o :: tl |> opt
| Shift i :: Offset (j, cmd) :: tl ->
Offset (i + j, cmd) :: Shift i :: tl |> opt
| Offset (a, Offset (b, cmd)) :: tl -> | Offset (a, Offset (b, cmd)) :: tl ->
Offset (a + b, cmd) :: tl |> opt Offset (a + b, cmd) :: tl |> opt
| Offset (0, cmd) :: tl -> | Offset (0, cmd) :: tl ->
cmd :: tl |> opt cmd :: tl |> opt
(* combine adjacent commands that work on the same offset *)
| Offset (i, a) :: Offset (j, b) :: tl when i = j -> | Offset (i, a) :: Offset (j, b) :: tl when i = j ->
begin match opt [a; b] with begin match opt [a; b] with
| [cmd] -> Offset (i, cmd) :: tl |> opt | [cmd] -> Offset (i, cmd) :: tl |> opt
| _ -> Offset (i, a) :: opt (Offset (j, b) :: tl) | _ -> Offset (i, a) :: opt (Offset (j, b) :: tl)
end end
| Shift i :: Offset (j, cmd) :: tl -> (* sort offset operations so that they are likely to be combined *)
Offset (i + j, cmd) :: Shift i :: tl |> opt | Offset (i, a) :: Offset (j, b) :: tl when should_swap i a j b ->
Offset (j, b) :: Offset (i, a) :: tl |> opt
| Shift i :: cmd :: tl when can_offset cmd -> | Offset (i, a) :: b :: tl when should_swap i a 0 b ->
Offset (i, cmd) :: Shift i :: tl |> opt b :: Offset (i, a) :: tl |> opt
(* flatten reset loops *)
| Loop [Add (1 | -1)] :: tl -> | Loop [Add (1 | -1)] :: tl ->
Set 0 :: tl |> opt Set 0 :: tl |> opt
(* unfold multiplication loops *)
| Loop p :: tl -> | Loop p :: tl ->
begin match opt_loop (check_change p) with let p = check_change p in
| [Loop _ as loop] -> loop :: opt tl let rec next buf counter_found = function
| replacement -> opt (replacement @ tl) | Add -1 :: tl when not counter_found ->
end next buf true tl
| Offset (o, Add n) :: tl ->
next (Offset (o, Mul (-o, n)) :: buf) counter_found tl
| [] when counter_found ->
List.rev (Offset (0, Set 0) :: buf) @ tl |> opt
| _ ->
Loop p :: opt tl
in
next [] false p
| hd :: tl -> hd :: opt tl | hd :: tl -> hd :: opt tl
| [] -> [] | [] -> []
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment