Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Diff of /sml/branches/SMLNJ/src/compiler/CodeGen/x86/x86CG.sml
ViewVC logotype

Diff of /sml/branches/SMLNJ/src/compiler/CodeGen/x86/x86CG.sml

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 428, Wed Sep 8 09:47:00 1999 UTC revision 429, Wed Sep 8 09:47:00 1999 UTC
# Line 1  Line 1 
1  structure X86CG = struct  (*
2    structure I = X86Instr   * X86 specific backend
3    structure C = X86Cells   *)
4    structure R = X86CpsRegs  structure X86CG =
5      MachineGen
6      ( structure I          = X86Instr
7    structure F = X86FlowGraph    structure F = X86FlowGraph
8    structure Asm = X86AsmEmitter      structure R          = X86CpsRegs
   structure MLTree = X86MLTree  
   structure B = MLTree.BNames  
   structure MachSpec = X86Spec  
   structure Ctrl = Control.MLRISC  
9    structure CG = Control.CG    structure CG = Control.CG
10    
11    structure P = X86Props(X86Instr)      structure MachSpec   = X86Spec
12        structure PseudoOps  = X86PseudoOps
13        structure CpsRegs    = X86CpsRegs
14        structure InsnProps  = X86Props(X86Instr)
15        structure Asm        = X86AsmEmitter
16    
17    structure FreqProps = FreqProps(P)      val stack = I.Region.stack
18        val esp   = I.C.esp
19    
20    structure X86Spill = X86Spill(structure Instr=I structure Asm=X86AsmEmitter)      fun error msg = MLRiscErrorMsg.error("X86CG",msg)
21    
22    structure PrintFlowGraph=      structure MLTreeComp=
23      PrintClusterFn(structure Flowgraph=X86FlowGraph         X86(structure X86Instr=X86Instr
24                     structure Asm = X86AsmEmitter)             structure X86MLTree=X86MLTree
25               val tempMem=I.Displace{base=esp, disp=I.Immed 304, mem=stack}
26              )
27    
28    structure X86Jumps =    structure X86Jumps =
29      X86Jumps(structure Instr=X86Instr      X86Jumps(structure Instr=X86Instr
# Line 29  Line 34 
34    structure BackPatch =    structure BackPatch =
35      BackPatch(structure Jumps=X86Jumps      BackPatch(structure Jumps=X86Jumps
36                structure Emitter=X86MCEmitter                structure Emitter=X86MCEmitter
37                structure Props=P                   structure Props=InsnProps
38                structure Flowgraph=X86FlowGraph                structure Flowgraph=X86FlowGraph
39                structure Asm=X86AsmEmitter                structure Asm=X86AsmEmitter
40                structure CodeString=CodeString)                structure CodeString=CodeString)
41    
42    fun error msg = ErrorMsg.impossible ("X86CG." ^ msg)      structure PrintFlowGraph=
43           PrintClusterFn(structure Flowgraph=X86FlowGraph
44                          structure Asm = X86AsmEmitter)
45    
46        structure X86Spill = X86Spill(structure Instr=I structure Asm=Asm)
47    
48    val toInt32 = Int32.fromInt    val toInt32 = Int32.fromInt
49    fun cacheOffset r = I.Immed(toInt32(X86Runtime.vregStart + (r-8)*4))    fun cacheOffset r = I.Immed(toInt32(X86Runtime.vregStart + (r-8)*4))
50    
   val stack = X86Instr.Region.stack  
   val MLTree.REG(_,stackptr) = X86CpsRegs.stackptr  
   
51    structure X86RewritePseudo=    structure X86RewritePseudo=
52      X86RewritePseudo(structure Instr=X86Instr      X86RewritePseudo(structure Instr=X86Instr
53                       structure Flowgraph=X86FlowGraph                       structure Flowgraph=X86FlowGraph
54                       structure Shuffle=X86Shuffle                       structure Shuffle=X86Shuffle
55                       fun ea r = I.Displace{base=C.esp, disp=cacheOffset r,                          fun ea r = I.Displace{base=esp, disp=cacheOffset r,
56                                             mem=I.Region.stack})                                                mem=stack}
57                           )
58    
59    
60    val intSpillCnt = Ctrl.getInt "ra-int-spills"      val intSpillCnt = MLRiscControl.getCounter "ra-int-spills"
61    val floatSpillCnt = Ctrl.getInt "ra-float-spills"      val floatSpillCnt = MLRiscControl.getCounter "ra-float-spills"
62    val intReloadCnt = Ctrl.getInt "ra-int-reloads"      val intReloadCnt = MLRiscControl.getCounter "ra-int-reloads"
63    val floatReloadCnt = Ctrl.getInt "ra-float-reloads"      val floatReloadCnt = MLRiscControl.getCounter "ra-float-reloads"
64    val x86CfgDebugFlg = Ctrl.getFlag "x86-cfg-debug"      val x86CfgDebugFlg = MLRiscControl.getFlag "x86-cfg-debug"
65    
66    structure RegAllocation : sig      structure RA =
      val ra : X86FlowGraph.cluster -> X86FlowGraph.cluster  
     end =  
67    struct    struct
68          structure F = F
69    
70     (* create integer and floating point register allocators *)     (* create integer and floating point register allocators *)
71      structure X86Ra =      structure X86Ra =
72         X86RegAlloc(structure P = P           X86RegAlloc(structure P = InsnProps
73                     structure I = X86Instr                     structure I = X86Instr
74                     structure F = X86FlowGraph                     structure F = X86FlowGraph
75                     structure Asm = X86AsmEmitter)                     structure Asm = X86AsmEmitter)
# Line 71  Line 79 
79                            val first=32)                            val first=32)
80    
81      structure FloatRaUser : RA_USER_PARAMS = struct      structure FloatRaUser : RA_USER_PARAMS = struct
82        structure I = X86Instr          structure I = I
83        structure B = B          structure B = F.B
84    
85        val nFreeRegs = length R.availF        val nFreeRegs = length R.availF
86        val dedicated = R.dedicatedF        val dedicated = R.dedicatedF
87        fun copyInstr((rds, rss), I.FCOPY{tmp, ...}) =          fun copyInstr((rds as [_], rss as [_]), _) =
88                I.FCOPY{dst=rds, src=rss, tmp=NONE}
89              | copyInstr((rds, rss), I.FCOPY{tmp, ...}) =
90          I.FCOPY{dst=rds, src=rss, tmp=tmp}          I.FCOPY{dst=rds, src=rss, tmp=tmp}
91    
92        val getreg = FR.getreg        val getreg = FR.getreg
# Line 84  Line 94 
94    
95       (* register allocation for floating point registers *)       (* register allocation for floating point registers *)
96        fun spill{instr, reg, regmap, id} = let        fun spill{instr, reg, regmap, id} = let
97          val slot = I.Displace{base=stackptr, disp=getFregLoc reg,            (* val _ = floatSpillCnt := !floatSpillCnt + 1 *)
98                                mem=I.Region.stack}            val slot = I.Displace{base=esp, disp=getFregLoc reg, mem=stack}
99          fun spillInstr(r) = [I.FLD(I.FDirect(r)), I.FSTP(slot)]          fun spillInstr(r) = [I.FLD(I.FDirect(r)), I.FSTP(slot)]
100        in        in
101          case instr          case instr
# Line 94  Line 104 
104             in             in
105               case tmp               case tmp
106               of SOME(I.Direct r) =>               of SOME(I.Direct r) =>
107                  if r=reg then let                    if regmap r=reg then let
108                      val slot = I.Displace{base=stackptr, disp=getFregLoc reg,                        val slot = I.Displace{base=esp, disp=getFregLoc reg,
109                                            mem=I.Region.stack}                                              mem=stack}
110                      val fcopy = I.FCOPY{dst=dst, src=src, tmp=SOME slot}                      val fcopy = I.FCOPY{dst=dst, src=src, tmp=SOME slot}
111                    in  {code=[],  proh=[], instr= SOME fcopy}                    in  {code=[],  proh=[], instr= SOME fcopy}
112                    end                    end
# Line 109  Line 119 
119        end        end
120    
121        fun reload{instr, reg, regmap, id} = let        fun reload{instr, reg, regmap, id} = let
122          val slot = I.Displace{base=stackptr, disp=getFregLoc reg,            (* val _ = floatReloadCnt := !floatReloadCnt + 1 *)
123                                mem=I.Region.stack}            val slot = I.Displace{base=esp, disp=getFregLoc reg, mem=stack}
124          fun reloadInstr(r, rest) = I.FLD(slot) :: I.FSTP(I.FDirect r) :: rest          fun reloadInstr(r, rest) = I.FLD(slot) :: I.FSTP(I.FDirect r) :: rest
125        in        in
126          case instr          case instr
# Line 136  Line 146 
146                              val first=0)                              val first=0)
147    
148      structure IntRa32User : RA_USER_PARAMS = struct      structure IntRa32User : RA_USER_PARAMS = struct
149        structure I = X86Instr          structure I = I
150        structure B = B          structure B = F.B
151    
152        val nFreeRegs = length (availR32)        val nFreeRegs = length (availR32)
153        val dedicated = X86CpsRegs.dedicatedR        val dedicated = X86CpsRegs.dedicatedR
154        fun copyInstr((rds, rss), I.COPY{tmp, ...}) =          fun copyInstr((rds as [_], rss as [_]), _) =
155                I.COPY{dst=rds, src=rss, tmp=NONE}
156              | copyInstr((rds, rss), I.COPY{tmp, ...}) =
157          I.COPY{dst=rds, src=rss, tmp=tmp}          I.COPY{dst=rds, src=rss, tmp=tmp}
158    
159        (* avoid the physical registers when possible. *)        (* avoid the physical registers when possible. *)
# Line 166  Line 178 
178        val getRegLoc = X86StackSpills.getRegLoc        val getRegLoc = X86StackSpills.getRegLoc
179    
180        fun spill{instr, reg, regmap, id} = let        fun spill{instr, reg, regmap, id} = let
181          val slot = I.Displace{base=stackptr, disp=getRegLoc reg,            (* val _ = intSpillCnt := !intSpillCnt + 1 *)
182                                mem=I.Region.stack}            val slot = I.Displace{base=esp, disp=getRegLoc reg, mem=stack}
183          fun spillInstr(r) =          fun spillInstr(r) =
184            [I.MOVE{mvOp=I.MOVL, src=I.Direct r, dst=slot}]            [I.MOVE{mvOp=I.MOVL, src=I.Direct r, dst=slot}]
185        in        in
# Line 177  Line 189 
189             in             in
190               case tmp               case tmp
191               of SOME(I.Direct r) =>               of SOME(I.Direct r) =>
192                   if r=reg then                     if regmap r=reg then
193                     {code=[], proh=[],                     {code=[], proh=[],
194                      instr=                      instr=
195                       SOME(I.COPY                       SOME(I.COPY
196                            {dst=dst, src=src,                            {dst=dst, src=src,
197                             tmp=SOME(I.Displace{base=stackptr, disp=getRegLoc r,                               tmp=SOME(I.Displace{base=esp, disp=getRegLoc r,
198                                                 mem=I.Region.stack})})}                                                   mem=stack})})}
199                   else                   else
200                     spillCpy(dst, src)                     spillCpy(dst, src)
201                | _ => spillCpy(dst, src)                | _ => spillCpy(dst, src)
# Line 192  Line 204 
204        end        end
205    
206        fun reload{instr, reg, regmap, id} = let        fun reload{instr, reg, regmap, id} = let
207          val slot = I.Displace{base=stackptr, disp=getRegLoc reg,            (* val _ = intReloadCnt := !intReloadCnt + 1 *)
208                                mem=I.Region.stack}            val slot = I.Displace{base=esp, disp=getRegLoc reg, mem=stack}
209          fun reloadInstr(r, rest) =          fun reloadInstr(r, rest) =
210            I.MOVE{mvOp=I.MOVL, src=slot, dst=I.Direct r}::rest            I.MOVE{mvOp=I.MOVL, src=slot, dst=I.Direct r}::rest
211        in        in
# Line 207  Line 219 
219    
220      structure IntRA32 = X86Ra.IntRa(structure RaUser= IntRa32User)      structure IntRA32 = X86Ra.IntRa(structure RaUser= IntRa32User)
221    
222      val spillSlotTbl : int Intmap.intmap option ref = ref NONE        fun noSpillSlotTbl _ = error "No spillSlotTbl"
223    
224          val spillSlotTbl : (int -> int) ref = ref noSpillSlotTbl
225    
226      structure GR8 = GetReg(val nRegs=8 val available=X86CpsRegs.availR      structure GR8 = GetReg(val nRegs=8 val available=X86CpsRegs.availR
227                             val first=0)                             val first=0)
228    
229      structure IntRa8User : RA_USER_PARAMS = struct      structure IntRa8User : RA_USER_PARAMS = struct
230        structure I = X86Instr          structure I = I
231        structure B = B          structure B = F.B
232    
233        val nFreeRegs = length X86CpsRegs.availR        val nFreeRegs = length X86CpsRegs.availR
234        val dedicated = R.dedicatedR        val dedicated = R.dedicatedR
235        fun copyInstr((rds, rss), I.COPY{tmp, ...}) =          fun copyInstr((rds as [_], rss as [_]), _) =
236                    I.COPY{dst=rds, src=rss, tmp=NONE}
237              | copyInstr((rds, rss), I.COPY{tmp, ...}) =
238              I.COPY{dst=rds, src=rss, tmp=tmp}              I.COPY{dst=rds, src=rss, tmp=tmp}
         | copyInstr((rds, rss), instr) =  
             let val Asm.S.STREAM{emit,...} = Asm.makeStream()  
             in  emit (fn r => r) instr;  
                 error "copyInstr"  
             end  
239    
240        val getreg = GR8.getreg        val getreg = GR8.getreg
241    
242        fun getRegLoc reg = let        fun getRegLoc reg = let
243          val recommended = Intmap.map (Option.valOf (!spillSlotTbl)) reg            val recommended = ! spillSlotTbl reg
244        in        in
245          if recommended < 32 then cacheOffset recommended          if recommended < 32 then cacheOffset recommended
246          else error ("getRegLoc:RA8 " ^ Int.toString recommended ^ "\n")          else error ("getRegLoc:RA8 " ^ Int.toString recommended ^ "\n")
# Line 237  Line 248 
248    
249       (* register allocation for general purpose registers *)       (* register allocation for general purpose registers *)
250        fun spill{instr, reg, regmap, id} = let        fun spill{instr, reg, regmap, id} = let
251          val slot = I.Displace{base=stackptr, disp=getRegLoc reg,            (* val _ = intSpillCnt := !intSpillCnt + 1 *)
252                                mem=I.Region.stack}            val slot = I.Displace{base=esp, disp=getRegLoc reg, mem=stack}
253          fun spillInstr(r) =          fun spillInstr(r) =
254            [I.MOVE{mvOp=I.MOVL, src=I.Direct r, dst=slot}]            [I.MOVE{mvOp=I.MOVL, src=I.Direct r, dst=slot}]
255        in        in
256          case instr          case instr
257          of I.COPY{tmp, dst, src, ...} => let          of I.COPY{tmp, dst, src, ...} => let
258              fun spillCpy([rd], [rs]) = {code=spillInstr(rs), proh=[], instr=NONE}                fun spillCpy([rd], [rs]) = {code=spillInstr(rs), proh=[],
259                                              instr=NONE}
260             in             in
261               case tmp               case tmp
262               of SOME(I.Direct r) =>               of SOME(I.Direct r) =>
263                   if r=reg then                     if regmap r=reg then
264                     {code=[], proh=[],                     {code=[], proh=[],
265                      instr=                      instr=
266                       SOME(I.COPY                       SOME(I.COPY
267                         {dst=dst, src=src,                         {dst=dst, src=src,
268                          tmp=SOME(I.Displace{base=stackptr, disp=getRegLoc r,                            tmp=SOME(I.Displace{base=esp, disp=getRegLoc r,
269                                              mem=I.Region.stack})})}                                                mem=stack})})}
270                   else                   else
271                     spillCpy(dst, src)                     spillCpy(dst, src)
272                | _ => spillCpy(dst, src)                | _ => spillCpy(dst, src)
# Line 265  Line 277 
277           {code=[instr], proh=[reg], instr=NONE})           {code=[instr], proh=[reg], instr=NONE})
278    
279        fun reload{instr, reg, regmap, id} = let        fun reload{instr, reg, regmap, id} = let
280          val slot = I.Displace{base=stackptr, disp=getRegLoc reg,            (* val _ = intReloadCnt := !intReloadCnt + 1 *)
281                                mem=I.Region.stack}            val slot = I.Displace{base=esp, disp=getRegLoc reg, mem=stack}
282          fun reloadInstr(r, rest) =          fun reloadInstr(r, rest) =
283            I.MOVE{mvOp=I.MOVL, src=slot, dst=I.Direct r}::rest            I.MOVE{mvOp=I.MOVL, src=slot, dst=I.Direct r}::rest
284        in        in
# Line 286  Line 298 
298        (* X86StackSpills is esential;        (* X86StackSpills is esential;
299         * the rest is just to ensure repeatability between compilation runs.         * the rest is just to ensure repeatability between compilation runs.
300         *)         *)
301        (X86StackSpills.init(); GR32.reset(); FR.reset(); GR8.reset())          (spillSlotTbl := noSpillSlotTbl;
302             X86StackSpills.init(); GR32.reset(); FR.reset(); GR8.reset())
303    
304      fun ra(cluster as F.CLUSTER{regmap, ...}) = let      fun ra(cluster as F.CLUSTER{regmap, ...}) = let
305        fun rmPseudoPhysical(rmap, 32) = ()       (* Cells parameter *)          fun rmPseudoPhysical(rmap, n) =
306          | rmPseudoPhysical(rmap, n) =          let val rmv = Intmap.rmv rmap
307             (Intmap.rmv rmap n; rmPseudoPhysical(rmap, n+1))              fun loop 32 = ()
308                  | loop n  = (rmv n; loop(n+1))
309        fun cloneRegmap regmap = let          in  loop n end
310          val new = Intmap.new(32, X86Cells.Cells)  
311        in app (Intmap.add new) (Intmap.intMapToList regmap); new          fun cloneRegmap regmap = Intmap.copy regmap
       end  
312    
313        fun setRegMap rmap        fun setRegMap rmap
314            (F.CLUSTER{blocks, entry, exit, blkCounter, annotations, ...}) =            (F.CLUSTER{blocks, entry, exit, blkCounter, annotations, ...}) =
# Line 310  Line 322 
322        fun intra32 cluster = let        fun intra32 cluster = let
323          val ra = IntRA32.ra IntRA32.REGISTER_ALLOCATION []          val ra = IntRA32.ra IntRA32.REGISTER_ALLOCATION []
324          val cluster' as F.CLUSTER{regmap, ...} = ra cluster          val cluster' as F.CLUSTER{regmap, ...} = ra cluster
325        in spillSlotTbl := SOME regmap; cluster'          in spillSlotTbl := I.C.lookup regmap; cluster'
326        end        end
327    
328        fun insertPseudoPhysical(F.CLUSTER{regmap, ...}) = let        fun insertPseudoPhysical(F.CLUSTER{regmap, ...}) = let
329              val addIt = Intmap.add regmap
330          fun add(32) = ()          fun add(32) = ()
331            | add(n) = (Intmap.add regmap (n, n); add(n+1))              | add(n) = (addIt (n, n); add(n+1))
332        in add(8)        in add(8)
333        end        end
334    
335        fun preference r = let        fun preference r = let
336          val pref = Intmap.map (Option.valOf (!spillSlotTbl)) r            val pref = ! spillSlotTbl r
337        in if pref >= 0 andalso pref < 8 then SOME pref else NONE        in if pref >= 0 andalso pref < 8 then SOME pref else NONE
338        end handle _ => NONE        end handle _ => NONE
339    
# Line 341  Line 354 
354        val cluster = intra32 cluster        val cluster = intra32 cluster
355        val _ = printGraph "\t---After register allocation K=32---\n" cluster        val _ = printGraph "\t---After register allocation K=32---\n" cluster
356    
357        val (n,m) = X86RewritePseudo.rewrite 32 cluster          val (n,m) = X86RewritePseudo.rewrite 32 (I.C.lookup regmap) cluster
358    
359        val cluster = setRegMap regmap cluster        val cluster = setRegMap regmap cluster
360        val _ =   rmPseudoPhysical(regmap, 8)        val _ =   rmPseudoPhysical(regmap, 8)
361        fun fromto(n,m) = if n>m then [] else n::fromto(n+1,m)          val cluster = intra8 [(n,m)] (* preference *) cluster
       val cluster = intra8 (fromto(n,m)) (* preference *) cluster  
362        val _ = printGraph "\t---After register allocation K=8---\n" cluster        val _ = printGraph "\t---After register allocation K=8---\n" cluster
363    
364        val _ = insertPseudoPhysical cluster        val _ = insertPseudoPhysical cluster
365        val cluster = floatRa cluster        val cluster = floatRa cluster
366        val _ = printGraph "\t---After floating register allocation---\n" cluster          val _ = printGraph "\t---After floating register allocation---\n"
367                        cluster
368      in      in
369        (*        (*
370         spillInit();         spillInit();
# Line 359  Line 372 
372         *)         *)
373        cluster        cluster
374      end      end
   end (* RegAllocation *)  
375    
376    val optimizerHook : (F.cluster -> F.cluster) option ref = ref NONE        fun cp _ = error "copy propagation"
377        end (* RegAllocation *)
378    
379    (* primitives for generation of X86 instruction flowgraphs *)    )
   structure FlowGraphGen =  
      ClusterGen(structure Flowgraph = X86FlowGraph  
                 structure InsnProps = P  
                 structure MLTree = X86MLTree  
                 structure Stream = X86Stream  
                 val optimize = optimizerHook  
                 val output = BackPatch.bbsched o RegAllocation.ra)  
   
   (* compilation of CPS to MLRISC *)  
   structure MLTreeGen =  
      MLRiscGen(structure MachineSpec=MachSpec  
                structure MLTreeComp=  
                   X86(structure Stream =X86Stream  
                       structure X86Instr=I  
                       structure X86MLTree=X86MLTree  
                       val tempMem=I.Displace{base=stackptr, disp=I.Immed 304,  
                                              mem=I.Region.stack})  
                structure Cells=X86Cells  
                structure C=X86CpsRegs  
                structure PseudoOp=X86PseudoOps  
                structure CpsTreeify=CpsTreeify  
                structure Flowgen=FlowGraphGen)  
   
   fun copyProp _ = error "copyProp: not defined"  
   val codegen = MLTreeGen.codegen  
   val finish = BackPatch.finish  
 end  
380    

Legend:
Removed from v.428  
changed lines
  Added in v.429

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0