Add new LLVM code generator to GHC. (Version 2)
[ghc-hetmet.git] / compiler / nativeGen / AsmCodeGen.lhs
1 -- -----------------------------------------------------------------------------
2 --
3 -- (c) The University of Glasgow 1993-2004
4 -- 
5 -- This is the top-level module in the native code generator.
6 --
7 -- -----------------------------------------------------------------------------
8
9 \begin{code}
10 {-# OPTIONS -w #-}
11 -- The above warning supression flag is a temporary kludge.
12 -- While working on this module you are encouraged to remove it and fix
13 -- any warnings in the module. See
14 --     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
15 -- for details
16
17 module AsmCodeGen ( nativeCodeGen ) where
18
19 #include "HsVersions.h"
20 #include "nativeGen/NCG.h"
21
22
23 #if   alpha_TARGET_ARCH
24 import Alpha.CodeGen
25 import Alpha.Regs
26 import Alpha.RegInfo
27 import Alpha.Instr
28
29 #elif i386_TARGET_ARCH || x86_64_TARGET_ARCH
30 import X86.CodeGen
31 import X86.Regs
32 import X86.RegInfo
33 import X86.Instr
34 import X86.Ppr
35
36 #elif sparc_TARGET_ARCH
37 import SPARC.CodeGen
38 import SPARC.Regs
39 import SPARC.Instr
40 import SPARC.Ppr
41 import SPARC.ShortcutJump
42
43 #elif powerpc_TARGET_ARCH
44 import PPC.CodeGen
45 import PPC.Cond
46 import PPC.Regs
47 import PPC.RegInfo
48 import PPC.Instr
49 import PPC.Ppr
50
51 #else
52 #error "AsmCodeGen: unknown architecture"
53
54 #endif
55
56 import RegAlloc.Liveness
57 import qualified RegAlloc.Linear.Main           as Linear
58
59 import qualified GraphColor                     as Color
60 import qualified RegAlloc.Graph.Main            as Color
61 import qualified RegAlloc.Graph.Stats           as Color
62 import qualified RegAlloc.Graph.Coalesce        as Color
63 import qualified RegAlloc.Graph.TrivColorable   as Color
64
65 import qualified SPARC.CodeGen.Expand           as SPARC
66
67 import TargetReg
68 import Platform
69 import Instruction
70 import PIC
71 import Reg
72 import RegClass
73 import NCGMonad
74
75 import BlockId
76 import CgUtils          ( fixStgRegisters )
77 import Cmm
78 import CmmOpt           ( cmmMiniInline, cmmMachOpFold )
79 import PprCmm
80 import CLabel
81 import State
82
83 import UniqFM
84 import Unique           ( Unique, getUnique )
85 import UniqSupply
86 import DynFlags
87 #if powerpc_TARGET_ARCH
88 import StaticFlags      ( opt_Static, opt_PIC )
89 #endif
90 import Util
91 import Config           ( cProjectVersion )
92 import Module
93
94 import Digraph
95 import qualified Pretty
96 import BufWrite
97 import Outputable
98 import FastString
99 import UniqSet
100 import ErrUtils
101
102 -- DEBUGGING ONLY
103 --import OrdList
104
105 import Data.List
106 import Data.Int
107 import Data.Word
108 import Data.Bits
109 import Data.Maybe
110 import GHC.Exts
111 import Control.Monad
112 import System.IO
113
114 {-
115 The native-code generator has machine-independent and
116 machine-dependent modules.
117
118 This module ("AsmCodeGen") is the top-level machine-independent
119 module.  Before entering machine-dependent land, we do some
120 machine-independent optimisations (defined below) on the
121 'CmmStmts's.
122
123 We convert to the machine-specific 'Instr' datatype with
124 'cmmCodeGen', assuming an infinite supply of registers.  We then use
125 a machine-independent register allocator ('regAlloc') to rejoin
126 reality.  Obviously, 'regAlloc' has machine-specific helper
127 functions (see about "RegAllocInfo" below).
128
129 Finally, we order the basic blocks of the function so as to minimise
130 the number of jumps between blocks, by utilising fallthrough wherever
131 possible.
132
133 The machine-dependent bits break down as follows:
134
135   * ["MachRegs"]  Everything about the target platform's machine
136     registers (and immediate operands, and addresses, which tend to
137     intermingle/interact with registers).
138
139   * ["MachInstrs"]  Includes the 'Instr' datatype (possibly should
140     have a module of its own), plus a miscellany of other things
141     (e.g., 'targetDoubleSize', 'smStablePtrTable', ...)
142
143   * ["MachCodeGen"]  is where 'Cmm' stuff turns into
144     machine instructions.
145
146   * ["PprMach"] 'pprInstr' turns an 'Instr' into text (well, really
147     a 'Doc').
148
149   * ["RegAllocInfo"] In the register allocator, we manipulate
150     'MRegsState's, which are 'BitSet's, one bit per machine register.
151     When we want to say something about a specific machine register
152     (e.g., ``it gets clobbered by this instruction''), we set/unset
153     its bit.  Obviously, we do this 'BitSet' thing for efficiency
154     reasons.
155
156     The 'RegAllocInfo' module collects together the machine-specific
157     info needed to do register allocation.
158
159    * ["RegisterAlloc"] The (machine-independent) register allocator.
160 -}
161
162 -- -----------------------------------------------------------------------------
163 -- Top-level of the native codegen
164
165 --------------------
166 nativeCodeGen :: DynFlags -> Handle -> UniqSupply -> [RawCmm] -> IO ()
167 nativeCodeGen dflags h us cmms
168  = do
169         let split_cmms  = concat $ map add_split cmms
170
171         -- BufHandle is a performance hack.  We could hide it inside
172         -- Pretty if it weren't for the fact that we do lots of little
173         -- printDocs here (in order to do codegen in constant space).
174         bufh <- newBufHandle h
175         (imports, prof) <- cmmNativeGens dflags bufh us split_cmms [] [] 0
176         bFlush bufh
177
178         let (native, colorStats, linearStats)
179                 = unzip3 prof
180
181         -- dump native code
182         dumpIfSet_dyn dflags
183                 Opt_D_dump_asm "Asm code"
184                 (vcat $ map (docToSDoc . pprNatCmmTop) $ concat native)
185
186         -- dump global NCG stats for graph coloring allocator
187         (case concat $ catMaybes colorStats of
188           []    -> return ()
189           stats -> do   
190                 -- build the global register conflict graph
191                 let graphGlobal 
192                         = foldl Color.union Color.initGraph
193                         $ [ Color.raGraph stat
194                                 | stat@Color.RegAllocStatsStart{} <- stats]
195            
196                 dumpSDoc dflags Opt_D_dump_asm_stats "NCG stats"
197                         $ Color.pprStats stats graphGlobal
198
199                 dumpIfSet_dyn dflags
200                         Opt_D_dump_asm_conflicts "Register conflict graph"
201                         $ Color.dotGraph 
202                                 targetRegDotColor 
203                                 (Color.trivColorable 
204                                         targetVirtualRegSqueeze 
205                                         targetRealRegSqueeze)
206                         $ graphGlobal)
207
208
209         -- dump global NCG stats for linear allocator
210         (case concat $ catMaybes linearStats of
211                 []      -> return ()
212                 stats   -> dumpSDoc dflags Opt_D_dump_asm_stats "NCG stats"
213                                 $ Linear.pprStats (concat native) stats)
214
215         -- write out the imports
216         Pretty.printDoc Pretty.LeftMode h
217                 $ makeImportsDoc dflags (concat imports)
218
219         return  ()
220
221  where  add_split (Cmm tops)
222                 | dopt Opt_SplitObjs dflags = split_marker : tops
223                 | otherwise                 = tops
224
225         split_marker = CmmProc [] mkSplitMarkerLabel [] (ListGraph [])
226
227
228 -- | Do native code generation on all these cmms.
229 --
230 cmmNativeGens dflags h us [] impAcc profAcc count
231         = return (reverse impAcc, reverse profAcc)
232
233 cmmNativeGens dflags h us (cmm : cmms) impAcc profAcc count
234  = do
235         (us', native, imports, colorStats, linearStats)
236                 <- cmmNativeGen dflags us cmm count
237
238         Pretty.bufLeftRender h
239                 $ {-# SCC "pprNativeCode" #-} Pretty.vcat $ map pprNatCmmTop native
240
241            -- carefully evaluate this strictly.  Binding it with 'let'
242            -- and then using 'seq' doesn't work, because the let
243            -- apparently gets inlined first.
244         lsPprNative <- return $!
245                 if  dopt Opt_D_dump_asm       dflags
246                  || dopt Opt_D_dump_asm_stats dflags
247                         then native
248                         else []
249
250         count' <- return $! count + 1;
251
252         -- force evaulation all this stuff to avoid space leaks
253         seqString (showSDoc $ vcat $ map ppr imports) `seq` return ()
254
255         cmmNativeGens dflags h us' cmms
256                         (imports : impAcc)
257                         ((lsPprNative, colorStats, linearStats) : profAcc)
258                         count'
259
260  where  seqString []            = ()
261         seqString (x:xs)        = x `seq` seqString xs `seq` ()
262
263
264 -- | Complete native code generation phase for a single top-level chunk of Cmm.
265 --      Dumping the output of each stage along the way.
266 --      Global conflict graph and NGC stats
267 cmmNativeGen 
268         :: DynFlags
269         -> UniqSupply
270         -> RawCmmTop                                    -- ^ the cmm to generate code for
271         -> Int                                          -- ^ sequence number of this top thing
272         -> IO   ( UniqSupply
273                 , [NatCmmTop Instr]                     -- native code
274                 , [CLabel]                              -- things imported by this cmm
275                 , Maybe [Color.RegAllocStats Instr]     -- stats for the coloring register allocator
276                 , Maybe [Linear.RegAllocStats])         -- stats for the linear register allocators
277
278 cmmNativeGen dflags us cmm count
279  = do
280
281         -- rewrite assignments to global regs
282         let fixed_cmm =
283                 {-# SCC "fixStgRegisters" #-}
284                 fixStgRegisters cmm
285
286         -- cmm to cmm optimisations
287         let (opt_cmm, imports) =
288                 {-# SCC "cmmToCmm" #-}
289                 cmmToCmm dflags fixed_cmm
290
291         dumpIfSet_dyn dflags
292                 Opt_D_dump_opt_cmm "Optimised Cmm"
293                 (pprCmm $ Cmm [opt_cmm])
294
295         -- generate native code from cmm
296         let ((native, lastMinuteImports), usGen) =
297                 {-# SCC "genMachCode" #-}
298                 initUs us $ genMachCode dflags opt_cmm
299
300         dumpIfSet_dyn dflags
301                 Opt_D_dump_asm_native "Native code"
302                 (vcat $ map (docToSDoc . pprNatCmmTop) native)
303
304         -- tag instructions with register liveness information
305         let (withLiveness, usLive) =
306                 {-# SCC "regLiveness" #-}
307                 initUs usGen $ mapUs regLiveness native
308
309         dumpIfSet_dyn dflags
310                 Opt_D_dump_asm_liveness "Liveness annotations added"
311                 (vcat $ map ppr withLiveness)
312                 
313         -- allocate registers
314         (alloced, usAlloc, ppr_raStatsColor, ppr_raStatsLinear) <-
315          if ( dopt Opt_RegsGraph dflags
316            || dopt Opt_RegsIterative dflags)
317           then do
318                 -- the regs usable for allocation
319                 let (alloc_regs :: UniqFM (UniqSet RealReg))
320                         = foldr (\r -> plusUFM_C unionUniqSets
321                                         $ unitUFM (targetClassOfRealReg r) (unitUniqSet r))
322                                 emptyUFM
323                         $ allocatableRegs
324
325                 -- do the graph coloring register allocation
326                 let ((alloced, regAllocStats), usAlloc)
327                         = {-# SCC "RegAlloc" #-}
328                           initUs usLive
329                           $ Color.regAlloc
330                                 dflags
331                                 alloc_regs
332                                 (mkUniqSet [0..maxSpillSlots])
333                                 withLiveness
334
335                 -- dump out what happened during register allocation
336                 dumpIfSet_dyn dflags
337                         Opt_D_dump_asm_regalloc "Registers allocated"
338                         (vcat $ map (docToSDoc . pprNatCmmTop) alloced)
339
340                 dumpIfSet_dyn dflags
341                         Opt_D_dump_asm_regalloc_stages "Build/spill stages"
342                         (vcat   $ map (\(stage, stats)
343                                         -> text "# --------------------------"
344                                         $$ text "#  cmm " <> int count <> text " Stage " <> int stage
345                                         $$ ppr stats)
346                                 $ zip [0..] regAllocStats)
347
348                 let mPprStats =
349                         if dopt Opt_D_dump_asm_stats dflags
350                          then Just regAllocStats else Nothing
351
352                 -- force evaluation of the Maybe to avoid space leak
353                 mPprStats `seq` return ()
354
355                 return  ( alloced, usAlloc
356                         , mPprStats
357                         , Nothing)
358
359           else do
360                 -- do linear register allocation
361                 let ((alloced, regAllocStats), usAlloc) 
362                         = {-# SCC "RegAlloc" #-}
363                           initUs usLive
364                           $ liftM unzip
365                           $ mapUs Linear.regAlloc withLiveness
366
367                 dumpIfSet_dyn dflags
368                         Opt_D_dump_asm_regalloc "Registers allocated"
369                         (vcat $ map (docToSDoc . pprNatCmmTop) alloced)
370
371                 let mPprStats =
372                         if dopt Opt_D_dump_asm_stats dflags
373                          then Just (catMaybes regAllocStats) else Nothing
374
375                 -- force evaluation of the Maybe to avoid space leak
376                 mPprStats `seq` return ()
377
378                 return  ( alloced, usAlloc
379                         , Nothing
380                         , mPprStats)
381
382         ---- shortcut branches
383         let shorted     =
384                 {-# SCC "shortcutBranches" #-}
385                 shortcutBranches dflags alloced
386
387         ---- sequence blocks
388         let sequenced   =
389                 {-# SCC "sequenceBlocks" #-}
390                 map sequenceTop shorted
391
392         ---- x86fp_kludge
393         let kludged =
394 #if i386_TARGET_ARCH
395                 {-# SCC "x86fp_kludge" #-}
396                 map x86fp_kludge sequenced
397 #else
398                 sequenced
399 #endif
400
401         ---- expansion of SPARC synthetic instrs
402 #if sparc_TARGET_ARCH
403         let expanded = 
404                 {-# SCC "sparc_expand" #-}
405                 map SPARC.expandTop kludged
406
407         dumpIfSet_dyn dflags
408                 Opt_D_dump_asm_expanded "Synthetic instructions expanded"
409                 (vcat $ map (docToSDoc . pprNatCmmTop) expanded)
410 #else
411         let expanded = 
412                 kludged
413 #endif
414
415         return  ( usAlloc
416                 , expanded
417                 , lastMinuteImports ++ imports
418                 , ppr_raStatsColor
419                 , ppr_raStatsLinear)
420
421
422 #if i386_TARGET_ARCH
423 x86fp_kludge :: NatCmmTop Instr -> NatCmmTop Instr
424 x86fp_kludge top@(CmmData _ _) = top
425 x86fp_kludge top@(CmmProc info lbl params (ListGraph code)) = 
426         CmmProc info lbl params (ListGraph $ i386_insert_ffrees code)
427 #endif
428
429
430 -- | Build a doc for all the imports.
431 --
432 makeImportsDoc :: DynFlags -> [CLabel] -> Pretty.Doc
433 makeImportsDoc dflags imports
434  = dyld_stubs imports
435
436 #if HAVE_SUBSECTIONS_VIA_SYMBOLS
437                 -- On recent versions of Darwin, the linker supports
438                 -- dead-stripping of code and data on a per-symbol basis.
439                 -- There's a hack to make this work in PprMach.pprNatCmmTop.
440             Pretty.$$ Pretty.text ".subsections_via_symbols"
441 #endif
442 #if HAVE_GNU_NONEXEC_STACK
443                 -- On recent GNU ELF systems one can mark an object file
444                 -- as not requiring an executable stack. If all objects
445                 -- linked into a program have this note then the program
446                 -- will not use an executable stack, which is good for
447                 -- security. GHC generated code does not need an executable
448                 -- stack so add the note in:
449             Pretty.$$ Pretty.text ".section .note.GNU-stack,\"\",@progbits"
450 #endif
451 #if !defined(darwin_TARGET_OS)
452                 -- And just because every other compiler does, lets stick in
453                 -- an identifier directive: .ident "GHC x.y.z"
454             Pretty.$$ let compilerIdent = Pretty.text "GHC" Pretty.<+>
455                                           Pretty.text cProjectVersion
456                        in Pretty.text ".ident" Pretty.<+>
457                           Pretty.doubleQuotes compilerIdent
458 #endif
459
460  where
461         -- Generate "symbol stubs" for all external symbols that might
462         -- come from a dynamic library.
463         dyld_stubs :: [CLabel] -> Pretty.Doc
464 {-      dyld_stubs imps = Pretty.vcat $ map pprDyldSymbolStub $
465                                     map head $ group $ sort imps-}
466
467         arch    = platformArch  $ targetPlatform dflags
468         os      = platformOS    $ targetPlatform dflags
469         
470         -- (Hack) sometimes two Labels pretty-print the same, but have
471         -- different uniques; so we compare their text versions...
472         dyld_stubs imps
473                 | needImportedSymbols arch os
474                 = Pretty.vcat $
475                         (pprGotDeclaration arch os :) $
476                         map ( pprImportedSymbol arch os . fst . head) $
477                         groupBy (\(_,a) (_,b) -> a == b) $
478                         sortBy (\(_,a) (_,b) -> compare a b) $
479                         map doPpr $
480                         imps
481                 | otherwise
482                 = Pretty.empty
483
484         doPpr lbl = (lbl, Pretty.render $ pprCLabel lbl astyle)
485         astyle = mkCodeStyle AsmStyle
486
487
488 -- -----------------------------------------------------------------------------
489 -- Sequencing the basic blocks
490
491 -- Cmm BasicBlocks are self-contained entities: they always end in a
492 -- jump, either non-local or to another basic block in the same proc.
493 -- In this phase, we attempt to place the basic blocks in a sequence
494 -- such that as many of the local jumps as possible turn into
495 -- fallthroughs.
496
497 sequenceTop 
498         :: NatCmmTop Instr
499         -> NatCmmTop Instr
500
501 sequenceTop top@(CmmData _ _) = top
502 sequenceTop (CmmProc info lbl params (ListGraph blocks)) = 
503   CmmProc info lbl params (ListGraph $ makeFarBranches $ sequenceBlocks blocks)
504
505 -- The algorithm is very simple (and stupid): we make a graph out of
506 -- the blocks where there is an edge from one block to another iff the
507 -- first block ends by jumping to the second.  Then we topologically
508 -- sort this graph.  Then traverse the list: for each block, we first
509 -- output the block, then if it has an out edge, we move the
510 -- destination of the out edge to the front of the list, and continue.
511
512 -- FYI, the classic layout for basic blocks uses postorder DFS; this
513 -- algorithm is implemented in cmm/ZipCfg.hs (NR 6 Sep 2007).
514
515 sequenceBlocks 
516         :: Instruction instr
517         => [NatBasicBlock instr] 
518         -> [NatBasicBlock instr]
519
520 sequenceBlocks [] = []
521 sequenceBlocks (entry:blocks) = 
522   seqBlocks (mkNode entry : reverse (flattenSCCs (sccBlocks blocks)))
523   -- the first block is the entry point ==> it must remain at the start.
524
525
526 sccBlocks 
527         :: Instruction instr
528         => [NatBasicBlock instr] 
529         -> [SCC ( NatBasicBlock instr
530                 , Unique
531                 , [Unique])]
532
533 sccBlocks blocks = stronglyConnCompFromEdgedVerticesR (map mkNode blocks)
534
535 -- we're only interested in the last instruction of
536 -- the block, and only if it has a single destination.
537 getOutEdges 
538         :: Instruction instr
539         => [instr] -> [Unique]
540
541 getOutEdges instrs 
542         = case jumpDestsOfInstr (last instrs) of
543                 [one] -> [getUnique one]
544                 _many -> []
545
546 mkNode block@(BasicBlock id instrs) = (block, getUnique id, getOutEdges instrs)
547
548 seqBlocks [] = []
549 seqBlocks ((block,_,[]) : rest)
550   = block : seqBlocks rest
551 seqBlocks ((block@(BasicBlock id instrs),_,[next]) : rest)
552   | can_fallthrough = BasicBlock id (init instrs) : seqBlocks rest'
553   | otherwise       = block : seqBlocks rest'
554   where
555         (can_fallthrough, rest') = reorder next [] rest
556           -- TODO: we should do a better job for cycles; try to maximise the
557           -- fallthroughs within a loop.
558 seqBlocks _ = panic "AsmCodegen:seqBlocks"
559
560 reorder id accum [] = (False, reverse accum)
561 reorder id accum (b@(block,id',out) : rest)
562   | id == id'  = (True, (block,id,out) : reverse accum ++ rest)
563   | otherwise  = reorder id (b:accum) rest
564
565
566 -- -----------------------------------------------------------------------------
567 -- Making far branches
568
569 -- Conditional branches on PowerPC are limited to +-32KB; if our Procs get too
570 -- big, we have to work around this limitation.
571
572 makeFarBranches 
573         :: [NatBasicBlock Instr] 
574         -> [NatBasicBlock Instr]
575
576 #if powerpc_TARGET_ARCH
577 makeFarBranches blocks
578     | last blockAddresses < nearLimit = blocks
579     | otherwise = zipWith handleBlock blockAddresses blocks
580     where
581         blockAddresses = scanl (+) 0 $ map blockLen blocks
582         blockLen (BasicBlock _ instrs) = length instrs
583         
584         handleBlock addr (BasicBlock id instrs)
585                 = BasicBlock id (zipWith makeFar [addr..] instrs)
586         
587         makeFar addr (BCC ALWAYS tgt) = BCC ALWAYS tgt
588         makeFar addr (BCC cond tgt)
589             | abs (addr - targetAddr) >= nearLimit
590             = BCCFAR cond tgt
591             | otherwise
592             = BCC cond tgt
593             where Just targetAddr = lookupUFM blockAddressMap tgt
594         makeFar addr other            = other
595         
596         nearLimit = 7000 -- 8192 instructions are allowed; let's keep some
597                          -- distance, as we have a few pseudo-insns that are
598                          -- pretty-printed as multiple instructions,
599                          -- and it's just not worth the effort to calculate
600                          -- things exactly
601         
602         blockAddressMap = listToUFM $ zip (map blockId blocks) blockAddresses
603 #else
604 makeFarBranches = id
605 #endif
606
607 -- -----------------------------------------------------------------------------
608 -- Shortcut branches
609
610 shortcutBranches 
611         :: DynFlags 
612         -> [NatCmmTop Instr] 
613         -> [NatCmmTop Instr]
614
615 shortcutBranches dflags tops
616   | optLevel dflags < 1 = tops    -- only with -O or higher
617   | otherwise           = map (apply_mapping mapping) tops'
618   where
619     (tops', mappings) = mapAndUnzip build_mapping tops
620     mapping = foldr plusUFM emptyUFM mappings
621
622 build_mapping top@(CmmData _ _) = (top, emptyUFM)
623 build_mapping (CmmProc info lbl params (ListGraph []))
624   = (CmmProc info lbl params (ListGraph []), emptyUFM)
625 build_mapping (CmmProc info lbl params (ListGraph (head:blocks)))
626   = (CmmProc info lbl params (ListGraph (head:others)), mapping)
627         -- drop the shorted blocks, but don't ever drop the first one,
628         -- because it is pointed to by a global label.
629   where
630     -- find all the blocks that just consist of a jump that can be
631     -- shorted.
632     -- Don't completely eliminate loops here -- that can leave a dangling jump!
633     (_, shortcut_blocks, others) = foldl split (emptyBlockSet, [], []) blocks
634     split (s, shortcut_blocks, others) b@(BasicBlock id [insn])
635         | Just (DestBlockId dest) <- canShortcut insn,
636           (elemBlockSet dest s) || dest == id -- loop checks
637         = (s, shortcut_blocks, b : others)
638     split (s, shortcut_blocks, others) (BasicBlock id [insn])
639         | Just dest <- canShortcut insn
640         = (extendBlockSet s id, (id,dest) : shortcut_blocks, others)
641     split (s, shortcut_blocks, others) other = (s, shortcut_blocks, other : others)
642
643
644     -- build a mapping from BlockId to JumpDest for shorting branches
645     mapping = foldl add emptyUFM shortcut_blocks
646     add ufm (id,dest) = addToUFM ufm id dest
647     
648 apply_mapping ufm (CmmData sec statics) 
649   = CmmData sec (map (shortcutStatic (lookupUFM ufm)) statics)
650   -- we need to get the jump tables, so apply the mapping to the entries
651   -- of a CmmData too.
652 apply_mapping ufm (CmmProc info lbl params (ListGraph blocks))
653   = CmmProc info lbl params (ListGraph $ map short_bb blocks)
654   where
655     short_bb (BasicBlock id insns) = BasicBlock id $! map short_insn insns
656     short_insn i = shortcutJump (lookupUFM ufm) i
657                  -- shortcutJump should apply the mapping repeatedly,
658                  -- just in case we can short multiple branches.
659
660 -- -----------------------------------------------------------------------------
661 -- Instruction selection
662
663 -- Native code instruction selection for a chunk of stix code.  For
664 -- this part of the computation, we switch from the UniqSM monad to
665 -- the NatM monad.  The latter carries not only a Unique, but also an
666 -- Int denoting the current C stack pointer offset in the generated
667 -- code; this is needed for creating correct spill offsets on
668 -- architectures which don't offer, or for which it would be
669 -- prohibitively expensive to employ, a frame pointer register.  Viz,
670 -- x86.
671
672 -- The offset is measured in bytes, and indicates the difference
673 -- between the current (simulated) C stack-ptr and the value it was at
674 -- the beginning of the block.  For stacks which grow down, this value
675 -- should be either zero or negative.
676
677 -- Switching between the two monads whilst carrying along the same
678 -- Unique supply breaks abstraction.  Is that bad?
679
680 genMachCode 
681         :: DynFlags 
682         -> RawCmmTop 
683         -> UniqSM 
684                 ( [NatCmmTop Instr]
685                 , [CLabel])
686
687 genMachCode dflags cmm_top
688   = do  { initial_us <- getUs
689         ; let initial_st           = mkNatM_State initial_us 0 dflags
690               (new_tops, final_st) = initNat initial_st (cmmTopCodeGen dflags cmm_top)
691               final_delta          = natm_delta final_st
692               final_imports        = natm_imports final_st
693         ; if   final_delta == 0
694           then return (new_tops, final_imports)
695           else pprPanic "genMachCode: nonzero final delta" (int final_delta)
696     }
697
698
699 -- -----------------------------------------------------------------------------
700 -- Generic Cmm optimiser
701
702 {-
703 Here we do:
704
705   (a) Constant folding
706   (b) Simple inlining: a temporary which is assigned to and then
707       used, once, can be shorted.
708   (c) Position independent code and dynamic linking
709         (i)  introduce the appropriate indirections
710              and position independent refs
711         (ii) compile a list of imported symbols
712
713 Ideas for other things we could do (ToDo):
714
715   - shortcut jumps-to-jumps
716   - eliminate dead code blocks
717   - simple CSE: if an expr is assigned to a temp, then replace later occs of
718     that expr with the temp, until the expr is no longer valid (can push through
719     temp assignments, and certain assigns to mem...)
720 -}
721
722 cmmToCmm :: DynFlags -> RawCmmTop -> (RawCmmTop, [CLabel])
723 cmmToCmm _ top@(CmmData _ _) = (top, [])
724 cmmToCmm dflags (CmmProc info lbl params (ListGraph blocks)) = runCmmOpt dflags $ do
725   blocks' <- mapM cmmBlockConFold (cmmMiniInline blocks)
726   return $ CmmProc info lbl params (ListGraph blocks')
727
728 newtype CmmOptM a = CmmOptM (([CLabel], DynFlags) -> (# a, [CLabel] #))
729
730 instance Monad CmmOptM where
731   return x = CmmOptM $ \(imports, _) -> (# x,imports #)
732   (CmmOptM f) >>= g =
733     CmmOptM $ \(imports, dflags) ->
734                 case f (imports, dflags) of
735                   (# x, imports' #) ->
736                     case g x of
737                       CmmOptM g' -> g' (imports', dflags)
738
739 addImportCmmOpt :: CLabel -> CmmOptM ()
740 addImportCmmOpt lbl = CmmOptM $ \(imports, dflags) -> (# (), lbl:imports #)
741
742 getDynFlagsCmmOpt :: CmmOptM DynFlags
743 getDynFlagsCmmOpt = CmmOptM $ \(imports, dflags) -> (# dflags, imports #)
744
745 runCmmOpt :: DynFlags -> CmmOptM a -> (a, [CLabel])
746 runCmmOpt dflags (CmmOptM f) = case f ([], dflags) of
747                         (# result, imports #) -> (result, imports)
748
749 cmmBlockConFold :: CmmBasicBlock -> CmmOptM CmmBasicBlock
750 cmmBlockConFold (BasicBlock id stmts) = do
751   stmts' <- mapM cmmStmtConFold stmts
752   return $ BasicBlock id stmts'
753
754 cmmStmtConFold stmt
755    = case stmt of
756         CmmAssign reg src
757            -> do src' <- cmmExprConFold DataReference src
758                  return $ case src' of
759                    CmmReg reg' | reg == reg' -> CmmNop
760                    new_src -> CmmAssign reg new_src
761
762         CmmStore addr src
763            -> do addr' <- cmmExprConFold DataReference addr
764                  src'  <- cmmExprConFold DataReference src
765                  return $ CmmStore addr' src'
766
767         CmmJump addr regs
768            -> do addr' <- cmmExprConFold JumpReference addr
769                  return $ CmmJump addr' regs
770
771         CmmCall target regs args srt returns
772            -> do target' <- case target of
773                               CmmCallee e conv -> do
774                                 e' <- cmmExprConFold CallReference e
775                                 return $ CmmCallee e' conv
776                               other -> return other
777                  args' <- mapM (\(CmmHinted arg hint) -> do
778                                   arg' <- cmmExprConFold DataReference arg
779                                   return (CmmHinted arg' hint)) args
780                  return $ CmmCall target' regs args' srt returns
781
782         CmmCondBranch test dest
783            -> do test' <- cmmExprConFold DataReference test
784                  return $ case test' of
785                    CmmLit (CmmInt 0 _) -> 
786                      CmmComment (mkFastString ("deleted: " ++ 
787                                         showSDoc (pprStmt stmt)))
788
789                    CmmLit (CmmInt n _) -> CmmBranch dest
790                    other -> CmmCondBranch test' dest
791
792         CmmSwitch expr ids
793            -> do expr' <- cmmExprConFold DataReference expr
794                  return $ CmmSwitch expr' ids
795
796         other
797            -> return other
798
799
800 cmmExprConFold referenceKind expr
801    = case expr of
802         CmmLoad addr rep
803            -> do addr' <- cmmExprConFold DataReference addr
804                  return $ CmmLoad addr' rep
805
806         CmmMachOp mop args
807            -- For MachOps, we first optimize the children, and then we try 
808            -- our hand at some constant-folding.
809            -> do args' <- mapM (cmmExprConFold DataReference) args
810                  return $ cmmMachOpFold mop args'
811
812         CmmLit (CmmLabel lbl)
813            -> do
814                 dflags <- getDynFlagsCmmOpt
815                 cmmMakeDynamicReference dflags addImportCmmOpt referenceKind lbl
816         CmmLit (CmmLabelOff lbl off)
817            -> do
818                  dflags <- getDynFlagsCmmOpt
819                  dynRef <- cmmMakeDynamicReference dflags addImportCmmOpt referenceKind lbl
820                  return $ cmmMachOpFold (MO_Add wordWidth) [
821                      dynRef,
822                      (CmmLit $ CmmInt (fromIntegral off) wordWidth)
823                    ]
824
825 #if powerpc_TARGET_ARCH
826            -- On powerpc (non-PIC), it's easier to jump directly to a label than
827            -- to use the register table, so we replace these registers
828            -- with the corresponding labels:
829         CmmReg (CmmGlobal EagerBlackholeInfo)
830           | not opt_PIC
831           -> cmmExprConFold referenceKind $
832              CmmLit (CmmLabel (mkCmmCodeLabel rtsPackageId (fsLit "__stg_EAGER_BLACKHOLE_info")))
833         CmmReg (CmmGlobal GCEnter1)
834           | not opt_PIC
835           -> cmmExprConFold referenceKind $
836              CmmLit (CmmLabel (mkCmmCodeLabel rtsPackageId (fsLit "__stg_gc_enter_1"))) 
837         CmmReg (CmmGlobal GCFun)
838           | not opt_PIC
839           -> cmmExprConFold referenceKind $
840              CmmLit (CmmLabel (mkCmmCodeLabel rtsPackageId (fsLit "__stg_gc_fun")))
841 #endif
842
843         other
844            -> return other
845
846 \end{code}
847