peephole.ml 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. open Types
  2. open Util
  3. let rec strip_comments = function
  4. | Comment _ :: tl -> strip_comments tl
  5. | InlineComment (EmptyLine, _) :: tl -> strip_comments tl
  6. | InlineComment (instr, _) :: tl -> strip_comments (instr :: tl)
  7. | hd :: tl -> hd :: (strip_comments tl)
  8. | [] -> []
  9. let rec peephole = function
  10. (* Constant load before branch becomes a jump when the branch condition
  11. * matches the loaded value ... *)
  12. | LoadImm (BoolVal b) :: Branch (cond, tgt) :: tl when cond = b ->
  13. InlineComment (Jump tgt, "branch -> jump") :: (peephole tl)
  14. (* ... otherwise, both instructions can be removed *)
  15. | LoadImm (BoolVal _) :: Branch (_, tgt) :: tl ->
  16. InlineComment (EmptyLine, "load + branch removed") :: peephole tl
  17. (* Transform addition/subtraction by constant to increment/decrement:
  18. * iload L | iload L
  19. * iloadc[_ ]C | iloadc_1
  20. * i{add,sub} | i{add,sub}
  21. * istore L | istore L
  22. * | |
  23. * v v
  24. * i{inc,dec} L C | i{inc,dec}_1 L
  25. *)
  26. | (Load (Int, Current, index) :: LoadConst (_, i) :: Op (Add, Int) ::
  27. Store (Int, Current, store) :: tl
  28. | LoadConst (_, i) :: Load (Int, Current, index) :: Op (Add, Int) ::
  29. Store (Int, Current, store) :: tl) when store = index ->
  30. InlineComment (Inc (index, i), "add -> inc") :: (peephole tl)
  31. | (Load (Int, Current, index) :: LoadConst (_, i) :: Op (Sub, Int) ::
  32. Store (Int, Current, store) :: tl
  33. | LoadConst (_, i) :: Load (Int, Current, index) :: Op (Sub, Int) ::
  34. Store (Int, Current, store) :: tl) when store = index ->
  35. InlineComment (Dec (index, i), "sub -> dec") :: (peephole tl)
  36. | (Load (Int, Current, index) :: LoadImm (IntVal 1) :: Op (Add, Int) ::
  37. Store (Int, Current, store) :: tl
  38. | LoadImm (IntVal 1) :: Load (Int, Current, index) :: Op (Add, Int) ::
  39. Store (Int, Current, store) :: tl) when store = index ->
  40. InlineComment (IncOne index, "add -> inc") :: (peephole tl)
  41. | (Load (Int, Current, index) :: LoadImm (IntVal 1) :: Op (Sub, Int) ::
  42. Store (Int, Current, store) :: tl
  43. | LoadImm (IntVal 1) :: Load (Int, Current, index) :: Op (Sub, Int) ::
  44. Store (Int, Current, store) :: tl) when store = index ->
  45. InlineComment (DecOne index, "sub -> dec") :: (peephole tl)
  46. | hd :: tl -> hd :: (peephole tl)
  47. | [] -> []
  48. let phase input =
  49. match input with
  50. | Assembly instrs ->
  51. if args.optimize then (
  52. log_line 1 "- Peephole optimization";
  53. Assembly (peephole (strip_comments instrs))
  54. ) else
  55. input
  56. | _ -> raise (InvalidInput "peephole")