]> Joshua Wise's Git repositories - snipe.git/blobdiff - top/top.sml
Initial import of l3c
[snipe.git] / top / top.sml
index cb409bf0c8377e1079da3a956d871accfd9ee7eb..5e564b18ad2e487f26b9b2d6b7ec557dd607a94d 100644 (file)
@@ -1,4 +1,4 @@
-(* L1 Compiler
+(* L3 Compiler
  * Top Level Environment
  * Author: Kaustuv Chaudhuri <kaustuv+@cs.cmu.edu>
  * Modified: Alex Vaynberg <alv@andrew.cmu.edu>
@@ -30,117 +30,168 @@ struct
 
   (* see flag explanations below *)
   val flag_verbose = Flag.flag "verbose"
+  val flag_liveness = Flag.flag "liveness"
   val flag_ast = Flag.flag "ast"
   val flag_ir = Flag.flag "ir"
   val flag_assem = Flag.flag "assem"
+  val flag_color = Flag.flag "color"
 
   fun reset_flags () =
       List.app Flag.unset [flag_verbose, flag_ast,
-                          flag_ir, flag_assem];
+                           flag_ir, flag_assem, flag_liveness];
 
   val options = [{short = "v", long=["verbose"], 
-                 desc=G.NoArg (fn () => Flag.set flag_verbose),
-                 help="verbose messages"},
-                {short = "", long=["dump-ast"],
-                 desc=G.NoArg (fn () => Flag.set flag_ast),
-                 help="pretty print the AST"},
-                {short = "", long=["dump-ir"],
-                 desc=G.NoArg (fn () => Flag.set flag_ir),
-                 help="pretty print the IR"},
-                {short = "", long=["dump-assem"],
-                 desc=G.NoArg (fn () => Flag.set flag_assem),
-                 help="pretty print the assembly before register allocaction"}
-               ]
+                  desc=G.NoArg (fn () => Flag.set flag_verbose),
+                  help="verbose messages"},
+                 {short = "a", long=["dump-ast"],
+                  desc=G.NoArg (fn () => Flag.set flag_ast),
+                  help="pretty print the AST"},
+                 {short = "i", long=["dump-ir"],
+                  desc=G.NoArg (fn () => Flag.set flag_ir),
+                  help="pretty print the IR"},
+                 {short = "l", long=["dump-liveness"],
+                  desc=G.NoArg (fn () => Flag.set flag_liveness),
+                  help="pretty print the liveness results"},
+                 {short = "s", long=["dump-assem"],
+                  desc=G.NoArg (fn () => Flag.set flag_assem),
+                  help="pretty print the assembly before register allocaction"},
+                 {short = "c", long=["dump-color"],
+                  desc=G.NoArg (fn () => Flag.set flag_color),
+                  help="pretty print the allocated regs"}
+                ]
 
 
   fun stem s =
       let
-         val (prefix, suffix) =
-             Substring.splitr (fn c => c <> #".") (Substring.full s)
+          val (prefix, suffix) =
+              Substring.splitr (fn c => c <> #".") (Substring.full s)
       in
-         if Substring.isEmpty prefix (* no "." in string s *)
-            then s (* return whole string *)
-         else Substring.string (Substring.trimr 1 prefix)
+          if Substring.isEmpty prefix (* no "." in string s *)
+             then s (* return whole string *)
+          else Substring.string (Substring.trimr 1 prefix)
       end
-
-  fun main (name, args) =
+  
+  fun processir externs (Tree.FUNCTION (id, ir)) =
       let
-       val header = "Usage: compile [OPTION...] SOURCEFILE\nwhere OPTION is"
-       val usageinfo = G.usageInfo {header = header, options = options}
-       fun errfn msg = (say (msg ^ "\n" ^ usageinfo) ; raise EXIT)
-
-       val _ = Temp.reset (); (* reset temp variable counter *)
-       val _ = reset_flags (); (* return all flags to default value *)
-
-       val _ = if List.length args = 0 then
-                   (say usageinfo; raise EXIT)
-               else ()
-
-       val (opts, files) =
-           G.getOpt {argOrder = G.Permute,
-                     options = options,
-                     errFn = errfn}
-                    args
-
-       val source =
-           case files
-             of [] => errfn "Error: no input file"
-              | [filename] => filename
-              | _ => errfn "Error: more than one input file"
-
-       val _ = Flag.guard flag_verbose say ("Parsing... " ^ source)
-       val ast = Parse.parse source
-       val _ = Flag.guard flag_ast
-                 (fn () => say (Ast.Print.pp_program ast)) ()
-
-       val _ = Flag.guard flag_verbose say "Checking..."
-       val _ = TypeChecker.typecheck ast
-
-       val _ = Flag.guard flag_verbose say "Translating..."
-       val ir = Trans.translate ast
-       val _ = Flag.guard flag_ir (fn () => say (Tree.Print.pp_program ir)) ()
-
-       val _ = Flag.guard flag_verbose say "Generating proto-x86_64 code..."
-       val assem = Codegen.codegen ir
-       val _ = Flag.guard flag_assem
-                 (fn () => List.app (TextIO.print o x86.prettyprint) assem) ()
-
-        val _ = Flag.guard flag_verbose say "Analyzing liveness..."
-        val liveness = Liveness.liveness assem;
-        
-        val _ = Flag.guard flag_verbose say "Graphing..."
-        val igraph = Igraph.gengraph liveness;
+        val name = "_l3_" ^ (Symbol.name id)
         
-        val _ = Flag.guard flag_verbose say "Ordering..."
-        val order = ColorOrder.colororder igraph;
+        fun realname s = if (List.exists (fn n => s = n) externs)
+                         then s
+                         else "_l3_" ^ s
+      
+        val _ = Flag.guard flag_verbose say ("Processing function: " ^ name)
+
+        val _ = Flag.guard flag_verbose say "  Generating proto-x86_64 code..."
+        val assem = Codegen.codegen ir
+        val _ = Flag.guard flag_assem
+                  (fn () => List.app (TextIO.print o (x86.prettyprint x86.Long)) assem) ()
+
+        val _ = Flag.guard flag_verbose say "  Analyzing liveness..."
+        val (preds, liveness) = Liveness.liveness assem;
+        val _ = Flag.guard flag_liveness
+                  (fn () => List.app
+                    (fn (asm, liv) =>
+                      TextIO.print (
+                        let
+                          val xpp = x86.prettyprint x86.Long asm
+                          val xpp = String.extract (xpp, 0, SOME (size xpp - 1))
+                          val spaces = implode (List.tabulate (40 - size xpp, fn _ => #" ")) handle size => ""
+                          val lpp = Liveness.prettyprint liv
+                          val lpp = String.extract (lpp, 0, SOME (size lpp - 1))
+                          val spaces2 = implode (List.tabulate (40 - size lpp, fn _ => #" ")) handle size => ""
+                        in
+                          xpp ^ spaces ^ lpp ^ spaces2 ^ "\n"
+                        end))
+                    (ListPair.zip (assem, Liveness.listify liveness))) ()
+
+        val _ = Flag.guard flag_verbose say "  Graphing..."
+        val (igraph,temps) = Igraph.gengraph (preds, liveness)
+
+        val _ = Flag.guard flag_verbose say "  Ordering..."
+        val order = ColorOrder.colororder (igraph,temps)
         
-        val _ = Flag.guard flag_verbose say "Coloring..."
+        val _ = Flag.guard flag_verbose say "  Coloring..."
         val colors = Colorizer.colorize order igraph;
-        
-        val _ = Flag.guard flag_verbose say "Solidifying x86_64 code..."
+        val _ = Flag.guard flag_color
+                  (fn () => List.app (TextIO.print o
+                    (fn (t, i) =>
+                      (Temp.name t) ^ " => " ^ (
+                        if (i <= x86.regtonum x86.R14D)
+                          then (x86.prettyprint_oper x86.Long (x86.REG (x86.numtoreg i)))
+                        else
+                          "spill[" ^ Int.toString (i - x86.regtonum x86.R14D) ^ "]")
+                        ^ "--"^ Int.toString i ^ "\n"))
+                    colors) ()
+
+        val _ = Flag.guard flag_verbose say "  Solidifying x86_64 code..."
         val x86 = Solidify.solidify colors assem;
 
-        val _ = Flag.guard flag_verbose say "Peepholing..."
+        val _ = Flag.guard flag_verbose say "  Peepholing..."
         val x86p = Peephole.peephole x86;
+
+        val _ = Flag.guard flag_verbose say "  Stringifying..."
+        val x86d = [x86.DIRECTIVE(".globl " ^ name),
+                    x86.DIRECTIVE(name ^ ":")]
+                    @ x86p
+        val code = Stringify.stringify realname x86d
+      in
+        code
+      end
+
+  fun main (name, args) =
+      let
+        val header = "Usage: compile [OPTION...] SOURCEFILE\nwhere OPTION is"
+        val usageinfo = G.usageInfo {header = header, options = options}
+        fun errfn msg = (say (msg ^ "\n" ^ usageinfo) ; raise EXIT)
+
+        val _ = Temp.reset (); (* reset temp variable counter *)
+        val _ = reset_flags (); (* return all flags to default value *)
+
+        val _ = if List.length args = 0 then
+                    (say usageinfo; raise EXIT)
+                else ()
+
+        val (opts, files) =
+            G.getOpt {argOrder = G.Permute,
+                      options = options,
+                      errFn = errfn}
+                     args
+
+        val source =
+            case files
+              of [] => errfn "Error: no input file"
+               | [filename] => filename
+               | _ => errfn "Error: more than one input file"
+
+        val _ = Flag.guard flag_verbose say ("Parsing... " ^ source)
+        val ast = Parse.parse source
+        val _ = Flag.guard flag_ast
+                  (fn () => say (Ast.Print.pp_program ast)) ()
+        
+        val externs = List.mapPartial 
+                        (fn (Ast.Function _) => NONE
+                          | (Ast.Extern (_, s, _)) => SOME (Symbol.name s)) ast
         
-        val _ = Flag.guard flag_verbose say "Stringifying..."
-       val x86d = [x86.DIRECTIVE(".file\t\"" ^ source ^ "\""),
-                    x86.DIRECTIVE(".globl _l1_main"),
-                   x86.DIRECTIVE("_l1_main:")]
-                   @ x86p
-                   @ [x86.DIRECTIVE ".ident\t\"15-411 L1 compiler v2 by czl@ and jwise@\""]
-       val code = Stringify.stringify x86d
-
-       val afname = stem source ^ ".s"
-       val _ = Flag.guard flag_verbose say ("Writing assembly to " ^ afname ^ " ...")
-       val _ = SafeIO.withOpenOut afname (fn afstream =>
-                  TextIO.output (afstream, code))
+        val _ = Flag.guard flag_verbose say "Checking..."
+        val ast = TypeChecker.typecheck ast
+        
+        val _ = Flag.guard flag_verbose say "Translating..."
+        val ir = Trans.translate ast
+        val _ = Flag.guard flag_ir (fn () => say (Tree.Print.pp_program ir)) ()
+        
+        val output = foldr (fn (func, code) => (processir externs func) ^ code) 
+          (".file\t\"" ^ source ^ "\"\n.ident\t\"15-411 L3 compiler by czl@ and jwise@\"\n") ir
+
+        val afname = stem source ^ ".s"
+        val _ = Flag.guard flag_verbose say ("Writing assembly to " ^ afname ^ " ...")
+        val _ = SafeIO.withOpenOut afname (fn afstream =>
+                   TextIO.output (afstream, output))
       in
-         OS.Process.success
+          OS.Process.success
       end
       handle ErrorMsg.Error => ( say "Compilation failed" ; OS.Process.failure )
-          | EXIT => OS.Process.failure
-          | ErrorMsg.InternalError s => ( say ("Internal compiler error: "^s^"\n"); OS.Process.failure)
+           | EXIT => OS.Process.failure
+           | ErrorMsg.InternalError s => ( say ("Internal compiler error: "^s^"\n"); OS.Process.failure)
            | e => (say ("Unrecognized exception " ^ exnMessage e); OS.Process.failure)
 
   fun test s = main ("", String.tokens Char.isSpace s)
This page took 0.029564 seconds and 4 git commands to generate.