summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--driver.fun20
-rw-r--r--emit.fun364
-rw-r--r--emit.sig2
-rw-r--r--il.fun144
-rw-r--r--il.sig2
-rw-r--r--parser.fun68
-rw-r--r--parser.sig2
7 files changed, 308 insertions, 294 deletions
diff --git a/driver.fun b/driver.fun
index 0f80f41..19adcaa 100644
--- a/driver.fun
+++ b/driver.fun
@@ -42,7 +42,19 @@ functor Driver(E: EMIT): DRIVER = struct
parseFlag C arg tail
else
case file of
- NONE => parseCmdArgs (updateC C s#file (SOME arg) %) tail
+ NONE =>
+ let
+ val size = size arg
+ in
+ if String.extract (arg, size - 2, NONE) <> ".c" then
+ die `arg `": expected file with .c suffix" %
+ else
+ let
+ val file = String.substring (arg, 0, size - 2)
+ in
+ parseCmdArgs (updateC C s#file (SOME file) %) tail
+ end
+ end
| SOME _ => die `arg `": file already specified" %
fun exec () =
@@ -53,7 +65,7 @@ functor Driver(E: EMIT): DRIVER = struct
case (#mode config) of
Normal =>
let
- val parseCtx = P.createCtx file (#includeDirs config)
+ val parseCtx = P.createCtx file (#includeDirs config) true
fun collect ctx =
let
@@ -67,9 +79,9 @@ functor Driver(E: EMIT): DRIVER = struct
val parseCtx = collect parseCtx
val progInfo = P.explode parseCtx
- val ilCtx = I.createCtx progInfo
+ val ilCtx = I.createCtx progInfo (SOME $ file ^ ".i")
in
- E.emit "/tmp/prog.s" ilCtx
+ E.emit (file ^ ".s") ilCtx (SOME $ file ^ ".e")
end
| DebugT => P.P.T.debugPrint file
| DebugE => P.P.debugPrint file (#includeDirs config)
diff --git a/emit.fun b/emit.fun
index ccdb6ce..d42a085 100644
--- a/emit.fun
+++ b/emit.fun
@@ -20,29 +20,31 @@ functor Emit(I: IL) = struct
datatype affinity = AfHard of reg | AfSoft of int list | AfUnk
val regs = [
- (Rcx, 0),
- (Rsi, 1),
- (Rdi, 2),
- (R8, 3),
- (R9, 4),
- (R10, 5),
- (R11, 6),
-
- (Rbx, 7),
- (R12, 8),
- (R13, 9),
- (R14, 10),
- (R15, 11),
-
- (Rdx, 12),
+ (R8, 0),
+ (R9, 1),
+ (R10, 2),
+ (R11, 3),
+
+ (Rbx, 4),
+ (R12, 5),
+ (R13, 6),
+ (R14, 7),
+ (R15, 8),
+
+ (Rdi, 9),
+ (Rsi, 10),
+ (Rdx, 11),
+ (Rcx, 12),
(Rax, 13),
(Rsp, 14),
(Rbp, 15)
]
- val callerSavedRegs = 7
- val usedRegNum = 12 (* rdx is not counted *)
+ val callerSavedRegs = 4
+ val usedRegNum = 9
+
+ val usedOverallRegNum = 13
fun reg2idx reg =
case List.find (fn (r, _) => r = reg) regs of
@@ -54,6 +56,24 @@ functor Emit(I: IL) = struct
NONE => raise Unreachable
| SOME (r, _) => r
+ val debugFile = ref NONE
+
+ local
+ fun output s =
+ let
+ val outstream = !debugFile
+ in
+ case outstream of
+ NONE => ()
+ | SOME outstream => TextIO.output (outstream, s)
+ end
+
+ val ctx = ((false, makePrintfBase output),
+ fn (_: bool * ((string -> unit) * (unit -> unit))) => ())
+ in
+ fun dprintf g = Fold.fold ctx g
+ end
+
local
fun output s =
let
@@ -294,10 +314,11 @@ functor Emit(I: IL) = struct
fun printInts ints =
let
- val () = printfn `"\nsorted intervals:\n" %
- fun p (id, s, e) = printfn `"id: %" I id `" {" I s `", " I e `"}" %
+ val () = dprintf `"\nsorted intervals:\n" %
+ fun p (id, s, e) = dprintf `"id: %" I id `" {" I s `", " I e `"}\n" %
in
- List.app p ints
+ List.app p ints;
+ dprintf `"\n" %
end
fun updAff arr idx aff =
@@ -451,25 +472,33 @@ functor Emit(I: IL) = struct
let
val rinfo = Array.array (D.length vregs, (AfUnk, VtUnk))
+ val () = compAffinity rinfo ops paramNum;
+
fun transfer idx acc =
if idx = D.length vregs then
rev acc
else
let
+ val (aff, _) = Array.sub (rinfo, idx)
+
val (vt, cand) =
case #t $ D.get vregs idx of
I.RtRem => (VtUnk, NONE)
| I.RtConst w => (VtConst (VConst w), NONE)
- | I.RtAddrConst (id, w) => (VtConst (VAddrConst (id, w)), NONE)
- | I.RtReg => (VtUnk, SOME idx)
+ | I.RtAddrConst (id, w) =>
+ (VtConst (VAddrConst (id, w)), NONE)
+ | I.RtReg => (
+ case aff of
+ AfHard reg => (VtReg reg, NONE)
+ | _ => (VtUnk, SOME idx)
+ )
in
- Array.update (rinfo, idx, (AfUnk, vt));
+ Array.update (rinfo, idx, (aff, vt));
transfer (idx + 1) (if isSome cand then valOf cand :: acc else acc)
end
val toAlloc = transfer 0 []
in
- compAffinity rinfo ops paramNum;
(toAlloc, rinfo)
end
@@ -505,12 +534,12 @@ functor Emit(I: IL) = struct
fun p (idx, (aff, _)) =
let
- val () = printf `"%" I idx %
+ val () = dprintf `"%" I idx %
in
case aff of
- AfUnk => printfn `" = unk" %
- | AfHard reg => printfn `" <- " Preg reg %
- | AfSoft rss => printfn `" <- " Plist pv rss (", ", true, 1) %
+ AfUnk => dprintf `" = unk\n" %
+ | AfHard reg => dprintf `" <- " Preg reg `"\n" %
+ | AfSoft rss => dprintf `" <- " Plist pv rss (", ", true, 1) `"\n" %
end
in
Array.appi p rinfo
@@ -526,12 +555,11 @@ functor Emit(I: IL) = struct
FRU.makeUpdate5 (from, from, to) i
end z
- fun returnToPool (_, rdxRef) Rdx = rdxRef := NONE
- | returnToPool (arr, _) reg =
+ fun returnToPool pool reg =
let
val idx = reg2idx reg
in
- Array.update (arr, idx, NONE)
+ Array.update (pool, idx, NONE)
end
fun expireOne { rinfo, active, pool, ... } (_, start, _) =
@@ -545,9 +573,9 @@ functor Emit(I: IL) = struct
val (_, vt) = Array.sub (rinfo, j)
val reg = case vt of VtReg reg => reg | _ => raise Unreachable
- val () = printfn `"III!!! interval %"
+ val () = dprintf `"III!!! interval %"
ip j `"(" ip startp `", " ip endp `") "
- `"with " Preg reg `" has expired" %
+ `"with " Preg reg `" has expired\n" %
in
returnToPool pool reg;
active := acts;
@@ -558,12 +586,12 @@ functor Emit(I: IL) = struct
let
fun loop I =
case expireOne I int of
- false => ()
+ false => dprintf `"\n" %
| true => loop I
in
case !active of
[] => ()
- | _ => loop I
+ | _ => (dprintf `"\n" %; loop I)
end
fun addToActive int [] = [int]
@@ -580,22 +608,17 @@ functor Emit(I: IL) = struct
Array.update (arr, idx, (aff, reg))
end
- fun getUser (_, rdxRef) Rdx = !rdxRef
- | getUser (arr, _) r = Array.sub (arr, reg2idx r)
-
- fun setUser (_, rdxRef) u Rdx: unit = rdxRef := SOME u
- | setUser (arr, _) u r = Array.update(arr, reg2idx r, SOME u)
+ fun getUser pool r = Array.sub (pool, reg2idx r)
+ fun setUser pool u r = Array.update(pool, reg2idx r, SOME u)
fun assignFirstReg poff { rinfo, pool, ... } vr =
let
- val regArr = #1 pool
-
fun loop idx =
- if idx = Array.length regArr then
+ if idx = Array.length pool then
raise Unreachable
else
let
- val user = Array.sub (regArr, idx)
+ val user = Array.sub (pool, idx)
in
case user of
SOME _ => loop (idx + 1)
@@ -604,8 +627,8 @@ functor Emit(I: IL) = struct
val reg = idx2reg idx
val () = setUser pool vr reg
- val () = printfn R poff
- `"assigned (first) reg " Preg reg `" to %" ip vr %
+ val () = dprintf R poff
+ `"assigned (first) reg " Preg reg `" to %" ip vr `"\n" %
in
updReg rinfo vr (VtReg reg)
end
@@ -614,7 +637,7 @@ functor Emit(I: IL) = struct
loop 0
end
- fun freeRegList (pool, _) =
+ fun freeRegList pool =
let
fun loop idx acc =
if idx = Array.length pool then
@@ -660,22 +683,22 @@ functor Emit(I: IL) = struct
fun assignSoftReg poff affs (I as { rinfo, pool, ... }) vr =
let
- val () = printfn R poff
- `"trying to assign register (by affinity) to %" ip vr %
+ val () = dprintf R poff
+ `"trying to assign register (by affinity) to %" ip vr `"\n" %
val regs = freeRegList pool
val affRegs = getAffRegList rinfo affs
val common = findCommonRegs regs affRegs
- val () = printfn R (poff + 1)
- `"free registers: " Plist preg regs (", ", true, 0) %
- val () = printfn R (poff + 1)
- `"affinity registers: " Plist preg affRegs (", ", true, 0) %
+ val () = dprintf R (poff + 1)
+ `"free registers: " Plist preg regs (", ", true, 0) `"\n" %
+ val () = dprintf R (poff + 1)
+ `"affinity registers: " Plist preg affRegs (", ", true, 0) `"\n" %
in
case common of
[] =>
let
- val () = printfn R (poff + 1) `"affinity was not satisfied" %
+ val () = dprintf R (poff + 1) `"affinity was not satisfied\n" %
in
assignFirstReg (poff + 2) I vr
end
@@ -685,56 +708,24 @@ functor Emit(I: IL) = struct
updReg rinfo vr (VtReg reg);
setUser pool vr reg;
- printfn R (poff + 1)
- `"assigned (by affinity) reg " Preg reg `" to %" ip vr %;
- printfn R (poff + 1)
- `"free registers: " Plist preg (freeRegList pool) (", ", true, 0) %
+ dprintf R (poff + 1)
+ `"assigned (by affinity) reg " Preg reg `" to %" ip vr `"\n" %;
+ dprintf R (poff + 1)
+ `"free registers: " Plist preg (freeRegList pool) (", ", true, 0)
+ `"\n" %
end
end
fun putToStack poff { rinfo, stackOff, ... } vr =
let
val newStackOff = !stackOff - 8
- val () = printfn R poff
- `"puting %" ip vr `" to stack: " ip newStackOff %
+ val () = dprintf R poff
+ `"puting %" ip vr `" to stack: " ip newStackOff `"\n" %
in
updReg rinfo vr (VtStack newStackOff);
stackOff := newStackOff
end
- fun assignHardReg poff (I as { rinfo, pool, ... }) vr reg =
- let
- val () = printfn R poff
- `"trying to assign hard reg " A1 preg reg `" to %" ip vr %
-
- val user = getUser pool reg
-
- fun setOurReg () =
- let
- val () = printfn R (poff + 1) `"reg assigned" %
- in
- setUser pool vr reg;
- updReg rinfo vr (VtReg reg)
- end
- in
- case user of
- NONE => setOurReg ()
- | SOME u =>
- let
- val () = if reg = Rdx then raise Unreachable else ()
-
- val () = printfn R (poff + 1) `"reg is taken by %" ip u %
- val (aff, _) = Array.sub (rinfo, u)
- in
- case aff of
- AfHard _ => raise Unreachable
- | AfSoft affs => assignSoftReg poff affs I u
- | AfUnk => assignFirstReg poff I u
- ;
- setOurReg ()
- end
- end
-
fun assignReg (I as { rinfo, ... }) (vr, _, _) =
let
val (aff, _) = Array.sub (rinfo, vr)
@@ -742,11 +733,10 @@ functor Emit(I: IL) = struct
case aff of
AfUnk => assignFirstReg 0 I vr
| AfSoft affs => assignSoftReg 0 affs I vr
- | AfHard reg => assignHardReg 0 I vr reg
+ | AfHard _ => raise Unreachable
end
- (* Ref is for Rdx *)
- fun getPool () = (Array.array (usedRegNum, NONE), ref NONE)
+ fun getPool () = Array.array (usedRegNum, NONE)
fun changeInActive active newInt oldVr =
let
@@ -756,42 +746,13 @@ functor Emit(I: IL) = struct
active := addToActive newInt a
end
- fun expropriateReg (I as { rinfo, pool = (pool, _), active, ... })
- int reg =
+ fun userIdx pool vr =
let
- val vr = #1 int
-
- val () = if reg = Rdx then raise Unreachable else ()
-
- val regIdx = reg2idx reg
- val u = valOf $ Array.sub (pool, regIdx)
-
- val (uAff, _) = Array.sub (rinfo, u)
- val () =
- case uAff of
- AfHard _ => raise Unreachable
- | _ => ()
-
- val () = putToStack 1 I u
- val () = Array.update (pool, regIdx, SOME vr)
- val () = updReg rinfo vr (VtReg reg)
- in
- changeInActive active int u
- end
-
- fun userIdx (arr, rdxRef) vr =
- let
- val () =
- if !rdxRef = SOME vr then
- raise Unreachable
- else
- ()
-
fun loop idx =
- if idx = Array.length arr then
+ if idx = Array.length pool then
raise Unreachable
else
- case Array.sub (arr, idx) of
+ case Array.sub (pool, idx) of
SOME u =>
if u = vr then
idx
@@ -807,51 +768,25 @@ functor Emit(I: IL) = struct
val spill = List.last (!active)
val vr = #1 int
- val (ourAff, _) = Array.sub (rinfo, vr)
-
- fun isNotHard vr =
- case #1 $ Array.sub (rinfo, vr) of
- AfHard _ => false
- | _ => true
- val () = printfn `"SpilAtInt" %
- val () = printfn R 0
- `"free registers: " Plist preg (freeRegList pool) (", ", true, 0) %
+ val () = dprintf `"SpillAtInt\n" %
+ val () = dprintf R 0
+ `"free registers: " Plist preg (freeRegList pool) (", ", true, 0) `"\n" %
in
- case ourAff of
- AfHard reg => expropriateReg I int reg
- | _ =>
- if #3 spill > #3 int andalso isNotHard (#1 spill) then
- let
- val idx = userIdx pool (#1 spill)
- val () = printfn `"spilling!!!" %
- val reg = idx2reg idx
- in
- setUser pool vr reg;
- updReg rinfo vr (VtReg reg);
- putToStack 1 I (#1 spill);
- changeInActive active int (#1 spill)
- end
- else
- putToStack 0 I vr
- end
-
- fun haveRoomForVR { rinfo, active, pool = (_, rdxRef), ... } vr =
- if length (!active) < usedRegNum then
- true
- else
+ if #3 spill > #3 int then
let
- val (aff, _) = Array.sub (rinfo, vr)
+ val () = dprintf `"spilling!!!\n" %
+ val idx = userIdx pool (#1 spill)
+ val reg = idx2reg idx
in
- case aff of
- AfHard Rdx =>
- if isSome (!rdxRef) then
- raise Unreachable
- else
- true
- | _ => false
+ setUser pool vr reg;
+ updReg rinfo vr (VtReg reg);
+ putToStack 1 I (#1 spill);
+ changeInActive active int (#1 spill)
end
-
+ else
+ putToStack 0 I vr
+ end
fun linearscan rinfo ints stackOff =
let
@@ -863,13 +798,13 @@ functor Emit(I: IL) = struct
fun loop { stackOff, ... } [] = stackOff
| loop (I as { active, ... }) (int :: ints) =
let
- val () = printfn `"\n\ninspectiing interval "
- ip (#1 int) `": (" ip (#2 int) `", " ip (#3 int) `")" %
-
val () = expireOld I int
+ val () = dprintf `"inspecting interval %"
+ ip (#1 int) `": (" ip (#2 int) `", " ip (#3 int) `")\n" %
+
val () =
- if haveRoomForVR I (#1 int) then
+ if length (!active) < usedRegNum then
let
val () = assignReg I int
in
@@ -885,17 +820,6 @@ functor Emit(I: IL) = struct
stackOff = ref stackOff } ints
end
- fun printAllocVar rinfo v =
- let
- val () = printf `"%" I v `": " %
- val (_, vt) = Array.sub (rinfo, v)
- in
- case vt of
- VtStack off => printfn `"stack " I off %
- | VtReg reg => printfn `"reg " A1 preg reg %
- | VtConst _ | VtUnk => raise Unreachable
- end
-
fun pr is8 reg out =
let
fun old s =
@@ -927,16 +851,28 @@ functor Emit(I: IL) = struct
| Rsp => old "rsp"
| Rbp => old "rbp"
end
+
+ fun printAllocVar rinfo v =
+ let
+ val () = dprintf `"%" I v `": " %
+ val (_, vt) = Array.sub (rinfo, v)
+ in
+ case vt of
+ VtStack off => dprintf `"stack " I off `"\n" %
+ | VtReg reg => dprintf `"reg " A1 preg reg `"\n" %
+ | VtConst _ | VtUnk => raise Unreachable
+ end
+
fun printAlloced rinfo toAlloc =
let
- val () = printfn `"\nallocated:\n" %
+ val () = dprintf `"\nallocated:\n\n" %
in
List.app (printAllocVar rinfo) toAlloc
end
fun getUsedRegs rinfo =
let
- val regs = Array.array (usedRegNum + 1, false)
+ val regs = Array.array (usedOverallRegNum, false)
fun loop idx =
if idx = Array.length rinfo then
@@ -946,10 +882,7 @@ functor Emit(I: IL) = struct
val (_, vt) = Array.sub (rinfo, idx)
in
case vt of
- VtReg reg => (
- printfn `"reg: " A2 pr true reg %;
- Array.update (regs, reg2idx reg, true)
- )
+ VtReg reg => Array.update (regs, reg2idx reg, true)
| _ => ();
loop (idx + 1)
end
@@ -1016,30 +949,43 @@ functor Emit(I: IL) = struct
fun printMap map =
let
- val () = printfn `"Register map\n" %
+ val () = dprintf `"Register map\n\n" %
fun printHeader idx =
if idx = callerSavedRegs then
- printf `"\n" %
- else (
- printfp 5 `" " Preg (idx2reg idx) `" " %;
- printHeader (idx + 1)
- )
-
- val () = printf `" " %
+ dprintf `"\n" %
+ else
+ let
+ val reg = sprintf Preg (idx2reg idx) %
+ val reg = if size reg = 3 then reg else " " ^ reg
+ in
+ dprintf `" " `reg `" " %;
+ printHeader (idx + 1)
+ end
+ val () = dprintf `" " %
val () = printHeader 0
fun printRow (idx, row) =
let
- val () = printf Ip 4 idx `": " %
+ val () = dprintf Ip 4 idx `": " %
fun loop idx =
if idx = callerSavedRegs then
- printf `"\n" %
+ dprintf `"\n" %
else (
case Array.sub (row, idx) of
- NONE => printf `" " %
- | SOME vr => printfp 5 `"%" I vr `" " %;
+ NONE => dprintf `" " %
+ | SOME vr =>
+ let
+ val n: string = sprintf I vr %
+ val n =
+ if size n < 3 then
+ implode (List.tabulate (3 - size n, fn _ => #" ")) ^ n
+ else
+ n
+ in
+ dprintf `" " `n `" " %
+ end;
loop (idx + 1)
)
in
@@ -1058,7 +1004,6 @@ functor Emit(I: IL) = struct
case D.get ops idx of
(SOME (I.IrAlloc (v, size, _)), li) =>
let
- val () = printfn `"alloca size: " W size %
val () =
if Word.mod (size, 0w8) <> 0w0 then
raise Unreachable
@@ -1081,7 +1026,7 @@ functor Emit(I: IL) = struct
let
val stackOffset = resolveAlloc ops
val (toAlloc, regInfo) = prepareRegInfo paramNum ops vregs
- val () = printfn `"for alloc: " Plist i toAlloc (", ", true, 0) %
+ val () = dprintf `"for alloc: " Plist i toAlloc (", ", true, 0) `"\n" %
val () = affPrint regInfo
@@ -1091,8 +1036,8 @@ functor Emit(I: IL) = struct
val () = printAlloced regInfo toAlloc
val regsToSave = getRegsToSave regInfo
- val () = printfn
- `"registers to save: " Plist preg regsToSave (", ", true, 0) %
+ val () = dprintf
+ `"registers to save: " Plist preg regsToSave (", ", true, 0) `"\n" %
val regMap = computeMap (D.length ops) intervals regInfo
val () = printMap regMap
@@ -2115,8 +2060,15 @@ functor Emit(I: IL) = struct
fun openFile fname = file := SOME (TextIO.openOut fname)
fun emit fname
- (I.Ctx { globSyms, extSyms, objsZI, objs, strlits, funcInfos, ... }) =
+ (I.Ctx { globSyms, extSyms, objsZI, objs, strlits, funcInfos, ... })
+ debugFileName
+ =
let
+
+ val () =
+ case debugFileName of
+ NONE => ()
+ | SOME fname => debugFile := SOME (TextIO.openOut fname)
val () = openFile fname
val () = List.app (fn gs => fprint `"global " PP.? gs `"\n" %) globSyms
diff --git a/emit.sig b/emit.sig
index 9b0d88d..ecd26f4 100644
--- a/emit.sig
+++ b/emit.sig
@@ -2,5 +2,5 @@ signature EMIT = sig
structure I: IL
- val emit: string -> I.ctx -> unit
+ val emit: string -> I.ctx -> string option -> unit
end
diff --git a/il.fun b/il.fun
index 0e2240c..286cd32 100644
--- a/il.fun
+++ b/il.fun
@@ -105,6 +105,24 @@ functor IL(P: PARSER) = struct
strlits: int list
}
+ val debugFile = ref NONE
+
+ local
+ fun output s =
+ let
+ val outstream = !debugFile
+ in
+ case outstream of
+ NONE => ()
+ | SOME outstream => TextIO.output (outstream, s)
+ end
+
+ val ctx = ((false, makePrintfBase output),
+ fn (_: bool * ((string -> unit) * (unit -> unit))) => ())
+ in
+ fun dprintf g = Fold.fold ctx g
+ end
+
fun updateLctx (Lctx ctx) = fn z =>
let
fun from fname localVars paramNum vregs ops scopes labels =
@@ -164,7 +182,7 @@ functor IL(P: PARSER) = struct
val len = lvlen + paramNum
val vregs = D.create len
- val () = printfn `"local + copies: " I len %
+ val () = dprintf `"local + copies: " I len `"\n" %
fun loop idx =
if idx = len then
@@ -421,7 +439,6 @@ functor IL(P: PARSER) = struct
let
val v = convExpr ctx ea
- val () = printfn `"TYPE: " P.Pctype (P.getT ea) %
val offset = getOffset (P.pointsTo $ P.getT ea)field
in
case v of
@@ -1271,78 +1288,77 @@ functor IL(P: PARSER) = struct
case rt of
RtReg => Printf out `"%" I id %
| RtRem => raise Unreachable
- | RtConst w => printf Pwc (getClass C id) w %
- | RtAddrConst (id, w) => printf `"$" PP.? id Pwc VR8 w %
+ | RtConst w => Printf out Pwc (getClass C id) w %
+ | RtAddrConst (id, w) => Printf out `"$" PP.? id Pwc VR8 w %
end
val Preg = fn z => bind A2 preg z
fun printOpSet ctx reg arg =
let
- val () = printf `"\t" Preg ctx reg `" " Pt ctx reg `" = " %
+ val () = dprintf `"\t" Preg ctx reg `" " Pt ctx reg `" = " %
in
case arg of
- SaVReg reg => printf Preg ctx reg %
- | SaConst w => printf Pwc (getClass ctx reg) w %
- | SaAddr (id, w) => printf PP.? id Pwc VR8 w %
+ SaVReg reg => dprintf Preg ctx reg %
+ | SaConst w => dprintf Pwc (getClass ctx reg) w %
+ | SaAddr (id, w) => dprintf PP.? id Pwc VR8 w %
end
fun printOp ctx (idx, (SOME op', li)) =
let
-
- fun printTail NONE = printf `"\n" %
+ fun printTail NONE = dprintf `"\n" %
| printTail (SOME (startL, endL)) =
case op' of
- IrNopLabel _ => printf `"\n" %
- | _ => printf `" ; (l" I startL `", l" I endL `")\n" %
+ IrNopLabel _ => dprintf `"\n" %
+ | _ => dprintf `" ; (l" I startL `", l" I endL `")\n" %
- val () = printf I idx `":" %
+ val () = dprintf I idx `":" %
val () =
case op' of
IrNopLabel _ => ()
- | _ => printf `"\t" %
+ | _ => dprintf `"\t" %
fun pt (reg1, reg2, reg3) op' =
- printf `"\t" Preg ctx reg1 `" " Pt ctx reg1 `" = "
+ dprintf `"\t" Preg ctx reg1 `" " Pt ctx reg1 `" = "
`op' `" " Preg ctx reg2 `", " Preg ctx reg3 %
fun pe (reg1, reg2, aClass) op' =
- printf `"\t" Preg ctx reg1 `" " Pt ctx reg1 `" = "
+ dprintf `"\t" Preg ctx reg1 `" " Pt ctx reg1 `" = "
`op' `" " Pac aClass `" " Preg ctx reg2 %
- fun pj (r, l) op' = printf `"\t" `op' `" " Preg ctx r `", " Pl l %
+ fun pj (r, l) op' = dprintf `"\t" `op' `" " Preg ctx r `", " Pl l %
- fun printRet NONE = printf `"\tret" %
+ fun printRet NONE = dprintf `"\tret" %
| printRet (SOME reg) =
- printf `"\tret " Pt ctx reg `" " Preg ctx reg %
+ dprintf `"\tret " Pt ctx reg `" " Preg ctx reg %
fun printAlloc (r, size, off) =
let
- val () = printf `"\t" Preg ctx r `" = alloc " W size %
+ val () = dprintf `"\t" Preg ctx r `" = alloc " W size %
in
case off of
- SOME off => printf `" [rbp-" I off `"]" %
+ SOME off => dprintf `" [rbp-" I off `"]" %
| NONE => ()
end
fun printCopy (to, from, size) =
- printf `"\tcopy " Preg ctx to `", .I" I from `", " W size %
+ dprintf `"\tcopy " Preg ctx to `", .I" I from `", " W size %
fun printFcall (ret, f, args) =
let
- val () = printf `"\t" %
+ val () = dprintf `"\t" %
val () =
if ret <> ~1 then
- printf Preg ctx ret `" " Pt ctx ret `" = " %
+ dprintf Preg ctx ret `" " Pt ctx ret `" = " %
else
()
in
- printf `"fcall " Preg ctx f `"" Plist (preg ctx) args (", ", true, 0) %
+ dprintf `"fcall " Preg ctx f `"" Plist (preg ctx) args (", ", true, 0) %
end
fun printLabel (Lctx { labels, ... }) lid =
let
val (labelPos, use) = D.get labels lid
val () = if valOf labelPos <> idx then raise Unreachable else ()
in
- printf `"@" Pl lid `"(" I use `"):" %
+ dprintf `"@" Pl lid `"(" I use `"):" %
end
fun cmpOpStr cmpop =
@@ -1381,14 +1397,14 @@ functor IL(P: PARSER) = struct
| IrExtSign t => pe t "exts"
| IrLoad (r1, r2, ac) =>
- printf `"\t" Preg ctx r1 `" = " Pac ac `" [" Preg ctx r2 `"]" %
+ dprintf `"\t" Preg ctx r1 `" = " Pac ac `" [" Preg ctx r2 `"]" %
| IrStore (r1, r2, ac) =>
- printf `"\t" Pac ac `" [" Preg ctx r1 `"] <- " Preg ctx r2 %
- | IrJmp l => printf `"\tjmp " Pl l %
+ dprintf `"\t" Pac ac `" [" Preg ctx r1 `"] <- " Preg ctx r2 %
+ | IrJmp l => dprintf `"\tjmp " Pl l %
| IrJz p => pj p "jz"
| IrJnz p => pj p "jnz"
| IrNopLabel l => printLabel ctx l
- | IrNop s => printf `"\t; " `s %
+ | IrNop s => dprintf `"\t; " `s %
| IrRet v => printRet v
| IrAlloc p => printAlloc p
| IrCopy t => printCopy t
@@ -1405,18 +1421,18 @@ functor IL(P: PARSER) = struct
let
val c = if class = VR4 then "w4" else "w8"
- val () = printf `"%" Ip 4 idx `" " `c
+ val () = dprintf `"%" Ip 4 idx `" " `c
`": defs = " Plist i defs (", ", true, 0)
`", uses = " Plist i use (", ", true, 0) %
in
case t of
- RtReg => printf `" regular" %
- | RtRem => printf `" removed" %
- | RtConst w => printf `" const " Pwc class w %
+ RtReg => dprintf `" regular" %
+ | RtRem => dprintf `" removed" %
+ | RtConst w => dprintf `" const " Pwc class w %
| RtAddrConst (id, w) =>
- printf `" addr const " PP.? id Pwc class w %
+ dprintf `" addr const " PP.? id Pwc class w %
;
- printf `"\n" %
+ dprintf `"\n" %
end
fun printVars (Lctx { vregs, ... }) =
@@ -1434,10 +1450,7 @@ functor IL(P: PARSER) = struct
fun constAdd vregs ops vid v insId =
let
- val () = printfn `"new constant: %" I vid %
-
val { class, defs, use, ... } = D.get vregs vid
-
val v =
case v of
RtConst w =>
@@ -1453,6 +1466,7 @@ functor IL(P: PARSER) = struct
fun f (SOME _, li) = (NONE, li)
| f (NONE, _) = raise Unreachable
in
+ dprintf `"%" I vid `", " %;
D.update ops f insId
end
@@ -1564,8 +1578,6 @@ functor IL(P: PARSER) = struct
let
val rt = getRegType vregs rs
val ext = if ext = ExtZero then P.extz else P.exts
-
- val () = printfn `"eval EXT" %
in
case rt of
RtConst w => RtConst $ ext w (ac2word aClass)
@@ -1751,9 +1763,11 @@ functor IL(P: PARSER) = struct
fun constPropagate (C as Lctx { vregs, ops, ... }) =
let
+ val () = dprintf `"constants: " %
val worklist = getFirstConstants C
in
- propagate worklist vregs ops
+ propagate worklist vregs ops;
+ dprintf `"\n" %
end
fun changeDest rd ins =
@@ -1791,7 +1805,7 @@ functor IL(P: PARSER) = struct
fun mergeIns (Lctx { vregs, ops, ... }) idx rd rs =
let
- val () = printfn `"removing %" I rs %
+ val () = dprintf `"removing %" I rs `"\n" %
val { class, ... } = D.get vregs rs
val () = D.set vregs rs
@@ -1846,6 +1860,7 @@ functor IL(P: PARSER) = struct
fun removeUnusedLabels (Lctx { ops, labels, ... }) =
let
+ val () = dprintf `"removing labels: " %
fun rem (insId, (op', _)) =
case op' of
SOME (IrNopLabel lid) =>
@@ -1853,7 +1868,7 @@ functor IL(P: PARSER) = struct
val (_, usage) = D.get labels lid
in
if usage = 0 andalso lid <> 0 then (
- printfn `"removing label: " I lid %;
+ dprintf `"L" I lid `", " %;
D.set ops insId (NONE, NONE)
) else
()
@@ -1868,7 +1883,8 @@ functor IL(P: PARSER) = struct
loop (idx + 1)
)
in
- loop 0
+ loop 0;
+ dprintf `"\n" %
end
fun removeUnusedVars (Lctx { fname, vregs, localVars, ... }) =
@@ -1905,23 +1921,28 @@ functor IL(P: PARSER) = struct
loop 0
end
- fun translateFn (F as { localVars, stmt, paramNum, name, ... }) =
+ fun translateFn ({ localVars, stmt, paramNum, name, ... }: P.funcInfo) =
let
- val () = P.printDef (P.Definition F)
+ val () = dprintf `"\n\nfunction " PP.? name `"\n\n" %
+
val ctx = createLocalCtx name localVars paramNum
val () = convStmt ctx stmt
val () = ctxPutOp ctx (IrNopLabel 0)
- val () = printVars ctx
val () = printIns ctx
+ (*
+ val () = printVars ctx
+ *)
- val () = printf `"\nconstant propagation\n\n" %
+ val () = dprintf `"\nconstant propagation\n\n" %
val () = constPropagate ctx
+ (*
val () = printVars ctx
val () = printIns ctx
+ *)
- val () = printf `"\nmisc il optimizations\n\n" %
+ val () = dprintf `"\nmisc il optimizations\n\n" %
val () = removeUnusedLabels ctx
val () = removeUnusedVars ctx
@@ -1930,8 +1951,10 @@ functor IL(P: PARSER) = struct
val () = printVars ctx
val () = printIns ctx
- val () = printf `"\nvariables\n\n" %
+ (*
+ val () = dprintf `"\nvariables\n\n" %
val () = printVars ctx
+ *)
val Lctx { vregs, ops, labels, ... } = ctx
in
@@ -1939,23 +1962,16 @@ functor IL(P: PARSER) = struct
paramNum, vregs, ops, labels = D.copy labels (fn (v, _) => v) }
end
- fun createCtx ({ ext, glob, objsZI, objs, funcs, strlits }) =
+ fun createCtx ({ ext, glob, objsZI, objs, funcs, strlits }) debugFileName =
let
+ val () =
+ case debugFileName of
+ NONE => ()
+ | SOME fname => debugFile := SOME (TextIO.openOut fname)
+
val fis = List.map (fn func => translateFn func) funcs
in
Ctx { objs, objsZI, extSyms = ext, globSyms = glob,
funcInfos = fis, strlits }
end
-
- (*
- fun updateCtx (Ctx ctx) = fn z =>
- let
- fun from objs objsZI extSyms globSyms funcInfos strlits =
- { objs, objsZI, extSyms, globSyms, funcs, strlits }
- fun to f { objs, objsZI, extSyms, globSyms, funcs, strlits } =
- f objs objsZI extSyms globSyms funcs strlits
- in
- FRU.makeUpdate6 (from, from, to) ctx (fn (a, f) => z (a, Ctx o f))
- end
- *)
end
diff --git a/il.sig b/il.sig
index 4136222..4705c1b 100644
--- a/il.sig
+++ b/il.sig
@@ -92,5 +92,5 @@ signature IL = sig
strlits: int list
}
- val createCtx: P.progInfo -> ctx
+ val createCtx: P.progInfo -> string option -> ctx
end
diff --git a/parser.fun b/parser.fun
index 0d2c774..6ee35ce 100644
--- a/parser.fun
+++ b/parser.fun
@@ -720,17 +720,45 @@ functor Parser(structure Tree: TREE; structure P: PPC;
| (union_t { fields, ... }) => fields
| _ => raise Unreachable
- fun createCtx fname incDirs = Ctx {
- aggrTypeNames = Tree.empty,
- localScopes = [],
- funcRetType = NONE,
- globalSyms = Tree.empty,
- tokenBuf = (P.create { fname, incDirs, debugMode = false }, []),
- loopLevel = 0,
- paramNum = NONE,
- defs = [],
- strlits = []
- }
+ val debugFile = ref NONE
+
+ local
+ fun output s =
+ let
+ val outstream = !debugFile
+ in
+ case outstream of
+ NONE => ()
+ | SOME outstream => TextIO.output (outstream, s)
+ end
+
+ val ctx = ((false, makePrintfBase output),
+ fn (_: bool * ((string -> unit) * (unit -> unit))) => ())
+ in
+ fun dprintf g = Fold.fold ctx g
+ end
+
+ fun createCtx fname incDirs debug =
+ let
+ val () =
+ if debug then
+ debugFile := SOME (TextIO.openOut (fname ^ ".p"))
+ else
+ ()
+ in
+ Ctx {
+ aggrTypeNames = Tree.empty,
+ localScopes = [],
+ funcRetType = NONE,
+ globalSyms = Tree.empty,
+ tokenBuf =
+ (P.create { fname = fname ^ ".c", incDirs, debugMode = false }, []),
+ loopLevel = 0,
+ paramNum = NONE,
+ defs = [],
+ strlits = []
+ }
+ end
fun loopWrapper ctx f =
let
@@ -3055,7 +3083,7 @@ functor Parser(structure Tree: TREE; structure P: PPC;
| f (SOME (GsTypedef _)) =
P.error pos `"symbol is already typedef'ed" %
- val () = printf `(class2str class) `" decl "
+ val () = dprintf `(class2str class) `" decl "
`(link2str linkage) `" " P.?id `": " Pctype t `"\n" %
val ((), tree) = lookup2 (#globalSyms ctx) id f
@@ -3905,7 +3933,7 @@ functor Parser(structure Tree: TREE; structure P: PPC;
function_t (ret, _, v) => (ret, v)
| _ => raise Unreachable
in
- printf P.?name `" " Plist printParam params (", ", true, 2)
+ dprintf P.?name `" " Plist printParam params (", ", true, 2)
`(if variadic then " variadic" else "")
`" -> " Pctype ret `"\n" %
end
@@ -3920,7 +3948,7 @@ functor Parser(structure Tree: TREE; structure P: PPC;
`" = " A2 printIni 0 ini `"\n" %
end
in
- printf Plist pobj objs ("", false, 2) %
+ dprintf Plist pobj objs ("", false, 2) %
end
| printDef (Definition (D as { stmt, localVars, ... })) =
let
@@ -3929,8 +3957,8 @@ functor Parser(structure Tree: TREE; structure P: PPC;
`(if onStack then "& " else "") Pctype t `"\n" %
in
printFuncHeader D;
- printf Pstmt 0 stmt %;
- Vector.appi (fn (i, var) => printf A2 pLocalVar i var %) localVars
+ dprintf Pstmt 0 stmt %;
+ Vector.appi (fn (i, var) => dprintf A2 pLocalVar i var %) localVars
end
type decl = P.tkPos * declClass * ctype * linkage
@@ -4005,10 +4033,16 @@ functor Parser(structure Tree: TREE; structure P: PPC;
val (toplev: toplev, ctx) = parseDeclaration ctx
in
case toplev of
- ObjDefs objDefList => (true, ctxAddDef ctx (Objects objDefList))
+ ObjDefs objDefList =>
+ let
+ val () = printDef (Objects objDefList)
+ in
+ (true, ctxAddDef ctx (Objects objDefList))
+ end
| FuncDef (id, body) =>
let
val (def, ctx) = ctxWithLayer ctx body (parseFuncDefinition id)
+ val () = printDef def
in
(true, ctxAddDef ctx def)
end
diff --git a/parser.sig b/parser.sig
index 38e1877..0577d36 100644
--- a/parser.sig
+++ b/parser.sig
@@ -145,7 +145,7 @@ signature PARSER = sig
(* Objects are in reverse order *)
datatype def = Objects of objDef list | Definition of funcInfo
- val createCtx: string -> string list -> ctx
+ val createCtx: string -> string list -> bool -> ctx
val parseDef: ctx -> bool * ctx
val printDef: def -> unit