main.ml 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. open Printf
  2. open Lexing
  3. open Types
  4. open Util
  5. (* For some reason OCaml wants me to redefine this type's implementation -.- *)
  6. type phase_func = Types.intermediate -> Types.intermediate
  7. (* Parse command-line arguments *)
  8. let parse_args () =
  9. let usage =
  10. "Usage: " ^ Sys.argv.(0) ^ " \
  11. [-h] [-o <file>] [-v <verbosity>] [-nocpp] [-noopt] [-upto <phase>] [<file>]
  12. -h Display this help message
  13. -o <file> Optional output file (defaults to stdout)
  14. -v <num> Set verbosity: 0: nothing, 1: errors (default), 2: intermediate, 3: debug
  15. -nocpp Disable C preprocessor
  16. -noopt Disable optimization phases (constprop, unroll, peephole)
  17. -upto <phase> Stop after the specified phase, and print the intermediate
  18. representation to stderr.
  19. Possible options are (in order of execution):
  20. load : Load input file and run C preprocessor
  21. parse : Parse input
  22. desug : Desugaring
  23. context : Context analysis
  24. typecheck : Type checking
  25. dimreduce : Array dimension reduction
  26. boolop : Convert boolean operations
  27. constprop : Constant propagation and folding
  28. unroll : Loop unrolling
  29. assemble : Assembly code generation
  30. peephole : Peephole optimization
  31. <file> Optional input file (default is to read from stdin)
  32. "
  33. in
  34. let rec handle = function
  35. | [("-v" | "-o" | "-upto") as arg] ->
  36. raise (Failure ("missing argument value for \"" ^ arg ^ "\""))
  37. | ("-v" | "-o" | "-upto") as arg :: next :: _ when next.[0] = '-' ->
  38. raise (Failure ("missing argument value for \"" ^ arg ^ "\""))
  39. | "-h" :: _ ->
  40. prerr_string usage;
  41. exit 0
  42. | "-v" :: num :: tl ->
  43. begin
  44. try
  45. Globals.args.verbose <- int_of_string num;
  46. handle tl
  47. with Failure "int_of_string" ->
  48. raise (Failure ("invalid verbosity level"))
  49. end
  50. | "-o" :: filename :: tl ->
  51. Globals.args.outfile <- Some filename;
  52. handle tl
  53. | "-nocpp" :: tl ->
  54. Globals.args.cpp <- false;
  55. handle tl
  56. | "-noopt" :: tl ->
  57. Globals.args.optimize <- false;
  58. handle tl
  59. | "-upto" :: id :: tl ->
  60. Globals.args.endphase <- id;
  61. handle tl
  62. | arg :: tl when arg.[0] = '-' ->
  63. raise (Failure ("unknown option \"" ^ arg ^ "\""))
  64. | filename :: tl ->
  65. Globals.args.infile <- Some filename;
  66. handle tl
  67. | [] -> ()
  68. in
  69. try
  70. handle (List.tl (Array.to_list Sys.argv))
  71. with Failure msg ->
  72. prerr_endline msg;
  73. prerr_string usage;
  74. exit 1
  75. (* Main function, returns exit status
  76. * Command-line arguments are stored in Globals.args *)
  77. let () =
  78. parse_args ();
  79. let run_phase condition phase msg = function
  80. | Some input when condition ->
  81. if String.length msg > 0 then log_plain_line 2 ("- " ^ msg);
  82. Some (phase input)
  83. | value -> value
  84. in
  85. let always = true in
  86. let when_opt = Globals.args.optimize in
  87. let print_ir condition only_if_endphase id = function
  88. | Some input when id = Globals.args.endphase ->
  89. ignore (Print.phase input);
  90. None
  91. | Some input when condition && not only_if_endphase && Globals.args.verbose >= 2 ->
  92. ignore (Print.phase input);
  93. Some input
  94. | value -> value
  95. in
  96. try
  97. Some Empty
  98. |> run_phase always Load.phase "Load input file"
  99. |> print_ir always false "load"
  100. |> run_phase always Parse.phase "Parse input"
  101. |> print_ir always false "parse"
  102. |> run_phase always Desug.phase "Desugaring"
  103. |> print_ir always false "desug"
  104. |> run_phase always Context.phase "Context analysis"
  105. |> print_ir always true "context"
  106. |> run_phase always Typecheck.phase "Type checking"
  107. |> print_ir always true "typecheck"
  108. |> run_phase always Dimreduce.phase "Array dimension reduction"
  109. |> print_ir always false "dimreduce"
  110. |> run_phase always Boolop.phase "Convert boolean operations"
  111. |> print_ir always false "boolop"
  112. |> run_phase when_opt Constprop.phase "Constant propagation"
  113. |> print_ir when_opt false "constprop"
  114. |> run_phase when_opt Unroll.phase "Loop unrolling"
  115. |> run_phase when_opt Constprop.phase ""
  116. |> print_ir when_opt false "unroll"
  117. |> run_phase always Index.phase ""
  118. |> run_phase always Assemble.phase "Assembly"
  119. |> print_ir always false "assemble"
  120. |> run_phase when_opt Peephole.phase "Peephole optimization"
  121. |> print_ir when_opt false "peephole"
  122. |> run_phase always Output.phase ""
  123. |> ignore
  124. with FatalError err ->
  125. print_error err;
  126. exit 1