]> Joshua Wise's Git repositories - snipe.git/blame - top/top.sml
Initial import of l4c
[snipe.git] / top / top.sml
CommitLineData
6ade8b0a 1(* L3 Compiler
12aa4087
JW
2 * Top Level Environment
3 * Author: Kaustuv Chaudhuri <kaustuv+@cs.cmu.edu>
4 * Modified: Alex Vaynberg <alv@andrew.cmu.edu>
5 * Modified: Frank Pfenning <fp@cs.cmu.edu>
6 *)
7
8signature TOP =
9sig
10 (* main function for standalone executable
11 * use with SMLofNJ.exportFn("heapfilename", Top.main)
12 *)
13 val main : string * string list -> OS.Process.status
14
15 (* test "arguments"; is the same as executing a saved
16 * heap with arguments on the command line
17 *)
18 val test : string -> OS.Process.status
19end
20
21structure Top :> TOP =
22struct
23 structure G = GetOpt (* from $/smlnj-lib/Util/getopt-sig.sml *)
24
25 fun say s = TextIO.output (TextIO.stdErr, s ^ "\n")
26
27 fun newline () = TextIO.output (TextIO.stdErr, "\n")
28
29 exception EXIT
30
31 (* see flag explanations below *)
32 val flag_verbose = Flag.flag "verbose"
0a24e44d 33 val flag_liveness = Flag.flag "liveness"
12aa4087
JW
34 val flag_ast = Flag.flag "ast"
35 val flag_ir = Flag.flag "ir"
36 val flag_assem = Flag.flag "assem"
6ade8b0a 37 val flag_color = Flag.flag "color"
12aa4087
JW
38
39 fun reset_flags () =
40 List.app Flag.unset [flag_verbose, flag_ast,
0a24e44d 41 flag_ir, flag_assem, flag_liveness];
12aa4087
JW
42
43 val options = [{short = "v", long=["verbose"],
0a24e44d
JW
44 desc=G.NoArg (fn () => Flag.set flag_verbose),
45 help="verbose messages"},
46 {short = "a", long=["dump-ast"],
47 desc=G.NoArg (fn () => Flag.set flag_ast),
48 help="pretty print the AST"},
49 {short = "i", long=["dump-ir"],
50 desc=G.NoArg (fn () => Flag.set flag_ir),
51 help="pretty print the IR"},
52 {short = "l", long=["dump-liveness"],
53 desc=G.NoArg (fn () => Flag.set flag_liveness),
54 help="pretty print the liveness results"},
55 {short = "s", long=["dump-assem"],
56 desc=G.NoArg (fn () => Flag.set flag_assem),
6ade8b0a
JW
57 help="pretty print the assembly before register allocaction"},
58 {short = "c", long=["dump-color"],
59 desc=G.NoArg (fn () => Flag.set flag_color),
60 help="pretty print the allocated regs"}
0a24e44d 61 ]
12aa4087
JW
62
63
64 fun stem s =
65 let
0a24e44d
JW
66 val (prefix, suffix) =
67 Substring.splitr (fn c => c <> #".") (Substring.full s)
12aa4087 68 in
0a24e44d
JW
69 if Substring.isEmpty prefix (* no "." in string s *)
70 then s (* return whole string *)
71 else Substring.string (Substring.trimr 1 prefix)
12aa4087 72 end
6ade8b0a
JW
73
74 fun processir externs (Tree.FUNCTION (id, ir)) =
75 let
1144856b 76 val name = "_l4_" ^ (Symbol.name id)
6ade8b0a
JW
77
78 fun realname s = if (List.exists (fn n => s = n) externs)
79 then s
1144856b 80 else "_l4_" ^ s
6ade8b0a
JW
81
82 val _ = Flag.guard flag_verbose say ("Processing function: " ^ name)
83
84 val _ = Flag.guard flag_verbose say " Generating proto-x86_64 code..."
85 val assem = Codegen.codegen ir
86 val _ = Flag.guard flag_assem
1144856b 87 (fn () => List.app (TextIO.print o (x86.prettyprint)) assem) ()
6ade8b0a
JW
88
89 val _ = Flag.guard flag_verbose say " Analyzing liveness..."
90 val (preds, liveness) = Liveness.liveness assem;
91 val _ = Flag.guard flag_liveness
92 (fn () => List.app
93 (fn (asm, liv) =>
94 TextIO.print (
95 let
1144856b 96 val xpp = x86.prettyprint asm
6ade8b0a
JW
97 val xpp = String.extract (xpp, 0, SOME (size xpp - 1))
98 val spaces = implode (List.tabulate (40 - size xpp, fn _ => #" ")) handle size => ""
99 val lpp = Liveness.prettyprint liv
100 val lpp = String.extract (lpp, 0, SOME (size lpp - 1))
101 val spaces2 = implode (List.tabulate (40 - size lpp, fn _ => #" ")) handle size => ""
102 in
103 xpp ^ spaces ^ lpp ^ spaces2 ^ "\n"
104 end))
105 (ListPair.zip (assem, Liveness.listify liveness))) ()
106
107 val _ = Flag.guard flag_verbose say " Graphing..."
108 val (igraph,temps) = Igraph.gengraph (preds, liveness)
109
110 val _ = Flag.guard flag_verbose say " Ordering..."
111 val order = ColorOrder.colororder (igraph,temps)
112
113 val _ = Flag.guard flag_verbose say " Coloring..."
114 val colors = Colorizer.colorize order igraph;
115 val _ = Flag.guard flag_color
116 (fn () => List.app (TextIO.print o
117 (fn (t, i) =>
118 (Temp.name t) ^ " => " ^ (
1144856b 119 if (i <= x86.regtonum x86.R13D)
6ade8b0a
JW
120 then (x86.prettyprint_oper x86.Long (x86.REG (x86.numtoreg i)))
121 else
1144856b 122 "spill[" ^ Int.toString (i - x86.regtonum x86.R13D) ^ "]")
6ade8b0a
JW
123 ^ "--"^ Int.toString i ^ "\n"))
124 colors) ()
125
126 val _ = Flag.guard flag_verbose say " Solidifying x86_64 code..."
127 val x86 = Solidify.solidify colors assem;
128
129 val _ = Flag.guard flag_verbose say " Peepholing..."
130 val x86p = Peephole.peephole x86;
131
132 val _ = Flag.guard flag_verbose say " Stringifying..."
133 val x86d = [x86.DIRECTIVE(".globl " ^ name),
134 x86.DIRECTIVE(name ^ ":")]
135 @ x86p
136 val code = Stringify.stringify realname x86d
137 in
138 code
139 end
12aa4087
JW
140
141 fun main (name, args) =
142 let
0a24e44d
JW
143 val header = "Usage: compile [OPTION...] SOURCEFILE\nwhere OPTION is"
144 val usageinfo = G.usageInfo {header = header, options = options}
145 fun errfn msg = (say (msg ^ "\n" ^ usageinfo) ; raise EXIT)
146
147 val _ = Temp.reset (); (* reset temp variable counter *)
148 val _ = reset_flags (); (* return all flags to default value *)
149
150 val _ = if List.length args = 0 then
151 (say usageinfo; raise EXIT)
152 else ()
153
154 val (opts, files) =
155 G.getOpt {argOrder = G.Permute,
156 options = options,
157 errFn = errfn}
158 args
159
160 val source =
161 case files
162 of [] => errfn "Error: no input file"
163 | [filename] => filename
164 | _ => errfn "Error: more than one input file"
165
166 val _ = Flag.guard flag_verbose say ("Parsing... " ^ source)
167 val ast = Parse.parse source
1144856b 168 val (_, funcs) = ast
0a24e44d
JW
169 val _ = Flag.guard flag_ast
170 (fn () => say (Ast.Print.pp_program ast)) ()
1144856b
JW
171
172 val externs = Symbol.mapPartiali
173 (fn (a, b) => case (AstUtils.Function.data b)
174 of Ast.Extern _ => SOME(Symbol.name a)
175 | _ => NONE
176 ) funcs
177
0a24e44d
JW
178 val _ = Flag.guard flag_verbose say "Checking..."
179 val ast = TypeChecker.typecheck ast
1144856b 180
0a24e44d
JW
181 val _ = Flag.guard flag_verbose say "Translating..."
182 val ir = Trans.translate ast
183 val _ = Flag.guard flag_ir (fn () => say (Tree.Print.pp_program ir)) ()
12aa4087 184
1144856b
JW
185 val output = foldr (fn (func, code) => (processir ("calloc" (* lololololol *) :: (Symbol.elems externs)) func) ^ code)
186 (".file\t\"" ^ source ^ "\"\n.ident\t\"15-411 L4 compiler by czl@ and jwise@\"\n") ir
0a24e44d
JW
187
188 val afname = stem source ^ ".s"
189 val _ = Flag.guard flag_verbose say ("Writing assembly to " ^ afname ^ " ...")
190 val _ = SafeIO.withOpenOut afname (fn afstream =>
6ade8b0a 191 TextIO.output (afstream, output))
12aa4087 192 in
0a24e44d 193 OS.Process.success
12aa4087
JW
194 end
195 handle ErrorMsg.Error => ( say "Compilation failed" ; OS.Process.failure )
0a24e44d
JW
196 | EXIT => OS.Process.failure
197 | ErrorMsg.InternalError s => ( say ("Internal compiler error: "^s^"\n"); OS.Process.failure)
12aa4087
JW
198 | e => (say ("Unrecognized exception " ^ exnMessage e); OS.Process.failure)
199
200 fun test s = main ("", String.tokens Char.isSpace s)
201end
This page took 0.034871 seconds and 4 git commands to generate.