module GHC.CmmToAsm
( nativeCodeGen
, cmmNativeGen
, NcgImpl(..)
)
where
import GHC.Prelude hiding (head)
import qualified GHC.CmmToAsm.X86 as X86
import qualified GHC.CmmToAsm.PPC as PPC
import qualified GHC.CmmToAsm.AArch64 as AArch64
import qualified GHC.CmmToAsm.Wasm as Wasm32
import qualified GHC.CmmToAsm.RV64 as RV64
import GHC.CmmToAsm.Reg.Liveness
import qualified GHC.CmmToAsm.Reg.Linear as Linear
import qualified GHC.Data.Graph.Color as Color
import qualified GHC.CmmToAsm.Reg.Graph as Color
import qualified GHC.CmmToAsm.Reg.Graph.Stats as Color
import qualified GHC.CmmToAsm.Reg.Graph.TrivColorable as Color
import GHC.Utils.Asm
import GHC.CmmToAsm.Reg.Target
import GHC.Platform
import GHC.CmmToAsm.BlockLayout as BlockLayout
import GHC.Settings.Config
import GHC.CmmToAsm.Instr
import GHC.CmmToAsm.PIC
import GHC.Platform.Reg
import GHC.Platform.Reg.Class (RegClass)
import GHC.CmmToAsm.Monad
import GHC.CmmToAsm.CFG
import GHC.CmmToAsm.Dwarf
import GHC.CmmToAsm.Config
import GHC.CmmToAsm.Types
import GHC.Cmm.DebugBlock
import GHC.Cmm.BlockId
import GHC.StgToCmm.CgUtils ( fixStgRegisters )
import GHC.Cmm
import GHC.Cmm.Dataflow.Label
import GHC.Cmm.GenericOpt
import GHC.Cmm.CLabel
import GHC.Types.Unique.FM
import GHC.Types.Unique.DSM
import GHC.Driver.DynFlags
import GHC.Driver.Ppr
import GHC.Utils.Misc
import GHC.Utils.Logger
import GHC.Utils.BufHandle
import GHC.Utils.Outputable as Outputable
import GHC.Utils.Panic
import GHC.Utils.Error
import GHC.Utils.Exception (evaluate)
import GHC.Utils.Constants (debugIsOn)
import GHC.Data.FastString
import GHC.Types.Unique.Set
import GHC.Unit
import GHC.StgToCmm.CgUtils (CgStream)
import GHC.Data.Stream (liftIO)
import qualified GHC.Data.Stream as Stream
import GHC.Settings
import Data.List (sortBy)
import Data.List.NonEmpty (groupAllWith, head)
import Data.Maybe
import Data.Ord ( comparing )
import Control.Monad
import System.IO
import System.Directory ( getCurrentDirectory )
nativeCodeGen :: forall a . Logger -> ToolSettings -> NCGConfig -> ModLocation -> Handle
-> CgStream RawCmmGroup a
-> UniqDSMT IO a
nativeCodeGen :: forall a.
Logger
-> ToolSettings
-> NCGConfig
-> ModLocation
-> Handle
-> CgStream RawCmmGroup a
-> UniqDSMT IO a
nativeCodeGen Logger
logger ToolSettings
ts NCGConfig
config ModLocation
modLoc Handle
h CgStream RawCmmGroup a
cmms
= let platform :: Platform
platform = NCGConfig -> Platform
ncgPlatform NCGConfig
config
nCG' :: ( OutputableP Platform statics, Outputable jumpDest, Instruction instr)
=> NcgImpl statics instr jumpDest -> UniqDSMT IO a
nCG' :: forall statics jumpDest instr.
(OutputableP Platform statics, Outputable jumpDest,
Instruction instr) =>
NcgImpl statics instr jumpDest -> UniqDSMT IO a
nCG' NcgImpl statics instr jumpDest
ncgImpl = Logger
-> NCGConfig
-> ModLocation
-> NcgImpl statics instr jumpDest
-> Handle
-> CgStream RawCmmGroup a
-> UniqDSMT IO a
forall statics jumpDest instr a.
(OutputableP Platform statics, Outputable jumpDest,
Instruction instr) =>
Logger
-> NCGConfig
-> ModLocation
-> NcgImpl statics instr jumpDest
-> Handle
-> CgStream RawCmmGroup a
-> UniqDSMT IO a
nativeCodeGen' Logger
logger NCGConfig
config ModLocation
modLoc NcgImpl statics instr jumpDest
ncgImpl Handle
h CgStream RawCmmGroup a
cmms
in case Platform -> Arch
platformArch Platform
platform of
Arch
ArchX86 -> NcgImpl (Alignment, RawCmmStatics) Instr JumpDest -> UniqDSMT IO a
forall statics jumpDest instr.
(OutputableP Platform statics, Outputable jumpDest,
Instruction instr) =>
NcgImpl statics instr jumpDest -> UniqDSMT IO a
nCG' (NCGConfig -> NcgImpl (Alignment, RawCmmStatics) Instr JumpDest
X86.ncgX86 NCGConfig
config)
Arch
ArchX86_64 -> NcgImpl (Alignment, RawCmmStatics) Instr JumpDest -> UniqDSMT IO a
forall statics jumpDest instr.
(OutputableP Platform statics, Outputable jumpDest,
Instruction instr) =>
NcgImpl statics instr jumpDest -> UniqDSMT IO a
nCG' (NCGConfig -> NcgImpl (Alignment, RawCmmStatics) Instr JumpDest
X86.ncgX86_64 NCGConfig
config)
Arch
ArchPPC -> NcgImpl RawCmmStatics Instr JumpDest -> UniqDSMT IO a
forall statics jumpDest instr.
(OutputableP Platform statics, Outputable jumpDest,
Instruction instr) =>
NcgImpl statics instr jumpDest -> UniqDSMT IO a
nCG' (NCGConfig -> NcgImpl RawCmmStatics Instr JumpDest
PPC.ncgPPC NCGConfig
config)
ArchPPC_64 PPC_64ABI
_ -> NcgImpl RawCmmStatics Instr JumpDest -> UniqDSMT IO a
forall statics jumpDest instr.
(OutputableP Platform statics, Outputable jumpDest,
Instruction instr) =>
NcgImpl statics instr jumpDest -> UniqDSMT IO a
nCG' (NCGConfig -> NcgImpl RawCmmStatics Instr JumpDest
PPC.ncgPPC NCGConfig
config)
Arch
ArchS390X -> String -> UniqDSMT IO a
forall a. HasCallStack => String -> a
panic String
"nativeCodeGen: No NCG for S390X"
ArchARM {} -> String -> UniqDSMT IO a
forall a. HasCallStack => String -> a
panic String
"nativeCodeGen: No NCG for ARM"
Arch
ArchAArch64 -> NcgImpl RawCmmStatics Instr JumpDest -> UniqDSMT IO a
forall statics jumpDest instr.
(OutputableP Platform statics, Outputable jumpDest,
Instruction instr) =>
NcgImpl statics instr jumpDest -> UniqDSMT IO a
nCG' (NCGConfig -> NcgImpl RawCmmStatics Instr JumpDest
AArch64.ncgAArch64 NCGConfig
config)
Arch
ArchAlpha -> String -> UniqDSMT IO a
forall a. HasCallStack => String -> a
panic String
"nativeCodeGen: No NCG for Alpha"
Arch
ArchMipseb -> String -> UniqDSMT IO a
forall a. HasCallStack => String -> a
panic String
"nativeCodeGen: No NCG for mipseb"
Arch
ArchMipsel -> String -> UniqDSMT IO a
forall a. HasCallStack => String -> a
panic String
"nativeCodeGen: No NCG for mipsel"
Arch
ArchRISCV64 -> NcgImpl RawCmmStatics Instr JumpDest -> UniqDSMT IO a
forall statics jumpDest instr.
(OutputableP Platform statics, Outputable jumpDest,
Instruction instr) =>
NcgImpl statics instr jumpDest -> UniqDSMT IO a
nCG' (NCGConfig -> NcgImpl RawCmmStatics Instr JumpDest
RV64.ncgRV64 NCGConfig
config)
Arch
ArchLoongArch64->String -> UniqDSMT IO a
forall a. HasCallStack => String -> a
panic String
"nativeCodeGen: No NCG for LoongArch64"
Arch
ArchUnknown -> String -> UniqDSMT IO a
forall a. HasCallStack => String -> a
panic String
"nativeCodeGen: No NCG for unknown arch"
Arch
ArchJavaScript-> String -> UniqDSMT IO a
forall a. HasCallStack => String -> a
panic String
"nativeCodeGen: No NCG for JavaScript"
Arch
ArchWasm32 -> NCGConfig
-> Logger
-> Platform
-> ToolSettings
-> ModLocation
-> Handle
-> CgStream RawCmmGroup a
-> UniqDSMT IO a
forall a.
NCGConfig
-> Logger
-> Platform
-> ToolSettings
-> ModLocation
-> Handle
-> CgStream RawCmmGroup a
-> UniqDSMT IO a
Wasm32.ncgWasm NCGConfig
config Logger
logger Platform
platform ToolSettings
ts ModLocation
modLoc Handle
h CgStream RawCmmGroup a
cmms
data NativeGenAcc statics instr
= NGS { forall statics instr. NativeGenAcc statics instr -> [[CLabel]]
ngs_imports :: ![[CLabel]]
, forall statics instr.
NativeGenAcc statics instr -> [[NatCmmDecl statics instr]]
ngs_natives :: ![[NatCmmDecl statics instr]]
, forall statics instr.
NativeGenAcc statics instr -> [[RegAllocStats statics instr]]
ngs_colorStats :: ![[Color.RegAllocStats statics instr]]
, forall statics instr.
NativeGenAcc statics instr -> [[RegAllocStats]]
ngs_linearStats :: ![[Linear.RegAllocStats]]
, forall statics instr. NativeGenAcc statics instr -> [Label]
ngs_labels :: ![Label]
, forall statics instr. NativeGenAcc statics instr -> [DebugBlock]
ngs_debug :: ![DebugBlock]
, forall statics instr. NativeGenAcc statics instr -> DwarfFiles
ngs_dwarfFiles :: !DwarfFiles
, forall statics instr.
NativeGenAcc statics instr -> LabelMap [UnwindPoint]
ngs_unwinds :: !(LabelMap [UnwindPoint])
}
nativeCodeGen' :: (OutputableP Platform statics, Outputable jumpDest, Instruction instr)
=> Logger
-> NCGConfig
-> ModLocation
-> NcgImpl statics instr jumpDest
-> Handle
-> CgStream RawCmmGroup a
-> UniqDSMT IO a
nativeCodeGen' :: forall statics jumpDest instr a.
(OutputableP Platform statics, Outputable jumpDest,
Instruction instr) =>
Logger
-> NCGConfig
-> ModLocation
-> NcgImpl statics instr jumpDest
-> Handle
-> CgStream RawCmmGroup a
-> UniqDSMT IO a
nativeCodeGen' Logger
logger NCGConfig
config ModLocation
modLoc NcgImpl statics instr jumpDest
ncgImpl Handle
h CgStream RawCmmGroup a
cmms
= do
bufh <- IO BufHandle -> UniqDSMT IO BufHandle
forall a. IO a -> UniqDSMT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO BufHandle -> UniqDSMT IO BufHandle)
-> IO BufHandle -> UniqDSMT IO BufHandle
forall a b. (a -> b) -> a -> b
$ Handle -> IO BufHandle
newBufHandle Handle
h
let ngs0 = [[CLabel]]
-> [[NatCmmDecl statics instr]]
-> [[RegAllocStats statics instr]]
-> [[RegAllocStats]]
-> [Label]
-> [DebugBlock]
-> DwarfFiles
-> LabelMap [UnwindPoint]
-> NativeGenAcc statics instr
forall statics instr.
[[CLabel]]
-> [[NatCmmDecl statics instr]]
-> [[RegAllocStats statics instr]]
-> [[RegAllocStats]]
-> [Label]
-> [DebugBlock]
-> DwarfFiles
-> LabelMap [UnwindPoint]
-> NativeGenAcc statics instr
NGS [] [] [] [] [] [] DwarfFiles
forall {k} (key :: k) elt. UniqFM key elt
emptyUFM LabelMap [UnwindPoint]
forall v. LabelMap v
mapEmpty
(ngs, a) <- cmmNativeGenStream logger config modLoc ncgImpl bufh cmms ngs0
_ <- finishNativeGen logger config modLoc bufh ngs
return a
finishNativeGen :: Instruction instr
=> Logger
-> NCGConfig
-> ModLocation
-> BufHandle
-> NativeGenAcc statics instr
-> UniqDSMT IO ()
finishNativeGen :: forall instr statics.
Instruction instr =>
Logger
-> NCGConfig
-> ModLocation
-> BufHandle
-> NativeGenAcc statics instr
-> UniqDSMT IO ()
finishNativeGen Logger
logger NCGConfig
config ModLocation
modLoc BufHandle
bufh NativeGenAcc statics instr
ngs
= Logger -> SDoc -> (() -> ()) -> UniqDSMT IO () -> UniqDSMT IO ()
forall (m :: * -> *) a.
MonadIO m =>
Logger -> SDoc -> (a -> ()) -> m a -> m a
withTimingSilent Logger
logger (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"NCG") (() -> () -> ()
forall a b. a -> b -> b
`seq` ()) (UniqDSMT IO () -> UniqDSMT IO ())
-> UniqDSMT IO () -> UniqDSMT IO ()
forall a b. (a -> b) -> a -> b
$ do
if Bool -> Bool
not (NCGConfig -> Bool
ncgDwarfEnabled NCGConfig
config)
then () -> UniqDSMT IO ()
forall a. a -> UniqDSMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
else (DUniqSupply -> IO ((), DUniqSupply)) -> UniqDSMT IO ()
forall a. (DUniqSupply -> IO (a, DUniqSupply)) -> UniqDSMT IO a
withDUS ((DUniqSupply -> IO ((), DUniqSupply)) -> UniqDSMT IO ())
-> (DUniqSupply -> IO ((), DUniqSupply)) -> UniqDSMT IO ()
forall a b. (a -> b) -> a -> b
$ \DUniqSupply
us -> do
compPath <- IO String
getCurrentDirectory
let (dwarf_h, us') = dwarfGen compPath config modLoc us (ngs_debug ngs)
(dwarf_s, _) = dwarfGen compPath config modLoc us (ngs_debug ngs)
emitNativeCode logger config bufh dwarf_h dwarf_s
return ((), us')
IO () -> UniqDSMT IO ()
forall a. IO a -> UniqDSMT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> UniqDSMT IO ()) -> IO () -> UniqDSMT IO ()
forall a b. (a -> b) -> a -> b
$ do
let stats :: [RegAllocStats statics instr]
stats = [[RegAllocStats statics instr]] -> [RegAllocStats statics instr]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (NativeGenAcc statics instr -> [[RegAllocStats statics instr]]
forall statics instr.
NativeGenAcc statics instr -> [[RegAllocStats statics instr]]
ngs_colorStats NativeGenAcc statics instr
ngs)
platform :: Platform
platform = NCGConfig -> Platform
ncgPlatform NCGConfig
config
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([RegAllocStats statics instr] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [RegAllocStats statics instr]
stats) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let graphGlobal :: Graph VirtualReg RegClass RealReg
graphGlobal
= (Graph VirtualReg RegClass RealReg
-> Graph VirtualReg RegClass RealReg
-> Graph VirtualReg RegClass RealReg)
-> Graph VirtualReg RegClass RealReg
-> [Graph VirtualReg RegClass RealReg]
-> Graph VirtualReg RegClass RealReg
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Graph VirtualReg RegClass RealReg
-> Graph VirtualReg RegClass RealReg
-> Graph VirtualReg RegClass RealReg
forall k cls color.
Graph k cls color -> Graph k cls color -> Graph k cls color
Color.union Graph VirtualReg RegClass RealReg
forall k cls color. Graph k cls color
Color.initGraph
([Graph VirtualReg RegClass RealReg]
-> Graph VirtualReg RegClass RealReg)
-> [Graph VirtualReg RegClass RealReg]
-> Graph VirtualReg RegClass RealReg
forall a b. (a -> b) -> a -> b
$ [ RegAllocStats statics instr -> Graph VirtualReg RegClass RealReg
forall statics instr.
RegAllocStats statics instr -> Graph VirtualReg RegClass RealReg
Color.raGraph RegAllocStats statics instr
stat
| stat :: RegAllocStats statics instr
stat@Color.RegAllocStatsStart{} <- [RegAllocStats statics instr]
stats]
SDoc -> IO ()
dump_stats ([RegAllocStats statics instr]
-> Graph VirtualReg RegClass RealReg -> SDoc
forall statics instr.
[RegAllocStats statics instr]
-> Graph VirtualReg RegClass RealReg -> SDoc
Color.pprStats [RegAllocStats statics instr]
stats Graph VirtualReg RegClass RealReg
graphGlobal)
Logger -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
putDumpFileMaybe Logger
logger
DumpFlag
Opt_D_dump_asm_conflicts String
"Register conflict graph"
DumpFormat
FormatText
(SDoc -> IO ()) -> SDoc -> IO ()
forall a b. (a -> b) -> a -> b
$ (RealReg -> SDoc)
-> Triv VirtualReg RegClass RealReg
-> Graph VirtualReg RegClass RealReg
-> SDoc
forall k cls color.
(Uniquable k, Outputable k, Outputable cls, Outputable color) =>
(color -> SDoc) -> Triv k cls color -> Graph k cls color -> SDoc
Color.dotGraph
(Platform -> RealReg -> SDoc
targetRegDotColor Platform
platform)
(Platform
-> (RegClass -> VirtualReg -> Int)
-> (RegClass -> RealReg -> Int)
-> Triv VirtualReg RegClass RealReg
Color.trivColorable Platform
platform
(Platform -> RegClass -> VirtualReg -> Int
targetVirtualRegSqueeze Platform
platform)
(Platform -> RegClass -> RealReg -> Int
targetRealRegSqueeze Platform
platform))
(Graph VirtualReg RegClass RealReg -> SDoc)
-> Graph VirtualReg RegClass RealReg -> SDoc
forall a b. (a -> b) -> a -> b
$ Graph VirtualReg RegClass RealReg
graphGlobal
let linearStats :: [RegAllocStats]
linearStats = [[RegAllocStats]] -> [RegAllocStats]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (NativeGenAcc statics instr -> [[RegAllocStats]]
forall statics instr.
NativeGenAcc statics instr -> [[RegAllocStats]]
ngs_linearStats NativeGenAcc statics instr
ngs)
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([RegAllocStats] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [RegAllocStats]
linearStats) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
SDoc -> IO ()
dump_stats (Platform -> [NatCmmDecl statics instr] -> [RegAllocStats] -> SDoc
forall instr statics.
Instruction instr =>
Platform -> [NatCmmDecl statics instr] -> [RegAllocStats] -> SDoc
Linear.pprStats Platform
platform ([[NatCmmDecl statics instr]] -> [NatCmmDecl statics instr]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (NativeGenAcc statics instr -> [[NatCmmDecl statics instr]]
forall statics instr.
NativeGenAcc statics instr -> [[NatCmmDecl statics instr]]
ngs_natives NativeGenAcc statics instr
ngs)) [RegAllocStats]
linearStats)
let ctx :: SDocContext
ctx = NCGConfig -> SDocContext
ncgAsmContext NCGConfig
config
BufHandle -> SDocContext -> HDoc -> IO ()
bPutHDoc BufHandle
bufh SDocContext
ctx (HDoc -> IO ()) -> HDoc -> IO ()
forall a b. (a -> b) -> a -> b
$ NCGConfig -> [CLabel] -> HDoc
makeImportsDoc NCGConfig
config ([[CLabel]] -> [CLabel]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (NativeGenAcc statics instr -> [[CLabel]]
forall statics instr. NativeGenAcc statics instr -> [[CLabel]]
ngs_imports NativeGenAcc statics instr
ngs))
BufHandle -> IO ()
bFlush BufHandle
bufh
() -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
where
dump_stats :: SDoc -> IO ()
dump_stats = Logger
-> PprStyle -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
logDumpFile Logger
logger (NamePprCtx -> PprStyle
mkDumpStyle NamePprCtx
alwaysQualify)
DumpFlag
Opt_D_dump_asm_stats String
"NCG stats"
DumpFormat
FormatText
cmmNativeGenStream :: forall statics jumpDest instr a . (OutputableP Platform statics, Outputable jumpDest, Instruction instr)
=> Logger
-> NCGConfig
-> ModLocation
-> NcgImpl statics instr jumpDest
-> BufHandle
-> CgStream RawCmmGroup a
-> NativeGenAcc statics instr
-> UniqDSMT IO (NativeGenAcc statics instr, a)
cmmNativeGenStream :: forall statics jumpDest instr a.
(OutputableP Platform statics, Outputable jumpDest,
Instruction instr) =>
Logger
-> NCGConfig
-> ModLocation
-> NcgImpl statics instr jumpDest
-> BufHandle
-> CgStream RawCmmGroup a
-> NativeGenAcc statics instr
-> UniqDSMT IO (NativeGenAcc statics instr, a)
cmmNativeGenStream Logger
logger NCGConfig
config ModLocation
modLoc NcgImpl statics instr jumpDest
ncgImpl BufHandle
h CgStream RawCmmGroup a
cmm_stream NativeGenAcc statics instr
ngs
= StreamS (UniqDSMT IO) RawCmmGroup a
-> NativeGenAcc statics instr
-> UniqDSMT IO (NativeGenAcc statics instr, a)
loop (CgStream RawCmmGroup a -> StreamS (UniqDSMT IO) RawCmmGroup a
forall (m :: * -> *) r' r.
Applicative m =>
Stream m r' r -> StreamS m r' r
Stream.runStream CgStream RawCmmGroup a
cmm_stream) NativeGenAcc statics instr
ngs
where
ncglabel :: SDoc
ncglabel = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"NCG"
loop :: Stream.StreamS (UniqDSMT IO) RawCmmGroup a
-> NativeGenAcc statics instr
-> UniqDSMT IO (NativeGenAcc statics instr, a)
loop :: StreamS (UniqDSMT IO) RawCmmGroup a
-> NativeGenAcc statics instr
-> UniqDSMT IO (NativeGenAcc statics instr, a)
loop StreamS (UniqDSMT IO) RawCmmGroup a
s NativeGenAcc statics instr
ngs =
case StreamS (UniqDSMT IO) RawCmmGroup a
s of
Stream.Done a
a ->
(NativeGenAcc statics instr, a)
-> UniqDSMT IO (NativeGenAcc statics instr, a)
forall a. a -> UniqDSMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (NativeGenAcc statics instr
ngs { ngs_imports = reverse $ ngs_imports ngs
, ngs_natives = reverse $ ngs_natives ngs
, ngs_colorStats = reverse $ ngs_colorStats ngs
, ngs_linearStats = reverse $ ngs_linearStats ngs
},
a
a)
Stream.Effect UniqDSMT IO (StreamS (UniqDSMT IO) RawCmmGroup a)
m -> UniqDSMT IO (StreamS (UniqDSMT IO) RawCmmGroup a)
m UniqDSMT IO (StreamS (UniqDSMT IO) RawCmmGroup a)
-> (StreamS (UniqDSMT IO) RawCmmGroup a
-> UniqDSMT IO (NativeGenAcc statics instr, a))
-> UniqDSMT IO (NativeGenAcc statics instr, a)
forall a b. UniqDSMT IO a -> (a -> UniqDSMT IO b) -> UniqDSMT IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \StreamS (UniqDSMT IO) RawCmmGroup a
cmm_stream' -> StreamS (UniqDSMT IO) RawCmmGroup a
-> NativeGenAcc statics instr
-> UniqDSMT IO (NativeGenAcc statics instr, a)
loop StreamS (UniqDSMT IO) RawCmmGroup a
cmm_stream' NativeGenAcc statics instr
ngs
Stream.Yield RawCmmGroup
cmms StreamS (UniqDSMT IO) RawCmmGroup a
cmm_stream' -> do
ngs'' <-
Logger
-> SDoc
-> (NativeGenAcc statics instr -> ())
-> UniqDSMT IO (NativeGenAcc statics instr)
-> UniqDSMT IO (NativeGenAcc statics instr)
forall (m :: * -> *) a.
MonadIO m =>
Logger -> SDoc -> (a -> ()) -> m a -> m a
withTimingSilent Logger
logger SDoc
ncglabel (NativeGenAcc statics instr -> () -> ()
forall a b. a -> b -> b
`seq` ()) (UniqDSMT IO (NativeGenAcc statics instr)
-> UniqDSMT IO (NativeGenAcc statics instr))
-> UniqDSMT IO (NativeGenAcc statics instr)
-> UniqDSMT IO (NativeGenAcc statics instr)
forall a b. (a -> b) -> a -> b
$ do
let !ndbgs :: [DebugBlock]
ndbgs | NCGConfig -> Bool
ncgDwarfEnabled NCGConfig
config = ModLocation -> RawCmmGroup -> [DebugBlock]
cmmDebugGen ModLocation
modLoc RawCmmGroup
cmms
| Bool
otherwise = []
dbgMap :: LabelMap DebugBlock
dbgMap = [DebugBlock] -> LabelMap DebugBlock
debugToMap [DebugBlock]
ndbgs
ngs' <- (DUniqSupply -> IO (NativeGenAcc statics instr, DUniqSupply))
-> UniqDSMT IO (NativeGenAcc statics instr)
forall a. (DUniqSupply -> IO (a, DUniqSupply)) -> UniqDSMT IO a
withDUS ((DUniqSupply -> IO (NativeGenAcc statics instr, DUniqSupply))
-> UniqDSMT IO (NativeGenAcc statics instr))
-> (DUniqSupply -> IO (NativeGenAcc statics instr, DUniqSupply))
-> UniqDSMT IO (NativeGenAcc statics instr)
forall a b. (a -> b) -> a -> b
$ Logger
-> NCGConfig
-> NcgImpl statics instr jumpDest
-> BufHandle
-> LabelMap DebugBlock
-> RawCmmGroup
-> NativeGenAcc statics instr
-> Int
-> DUniqSupply
-> IO (NativeGenAcc statics instr, DUniqSupply)
forall statics instr jumpDest.
(OutputableP Platform statics, Outputable jumpDest,
Instruction instr) =>
Logger
-> NCGConfig
-> NcgImpl statics instr jumpDest
-> BufHandle
-> LabelMap DebugBlock
-> RawCmmGroup
-> NativeGenAcc statics instr
-> Int
-> DUniqSupply
-> IO (NativeGenAcc statics instr, DUniqSupply)
cmmNativeGens Logger
logger NCGConfig
config NcgImpl statics instr jumpDest
ncgImpl BufHandle
h
LabelMap DebugBlock
dbgMap RawCmmGroup
cmms NativeGenAcc statics instr
ngs Int
0
let !ldbgs = [Label] -> LabelMap [UnwindPoint] -> [DebugBlock] -> [DebugBlock]
cmmDebugLink (NativeGenAcc statics instr -> [Label]
forall statics instr. NativeGenAcc statics instr -> [Label]
ngs_labels NativeGenAcc statics instr
ngs') (NativeGenAcc statics instr -> LabelMap [UnwindPoint]
forall statics instr.
NativeGenAcc statics instr -> LabelMap [UnwindPoint]
ngs_unwinds NativeGenAcc statics instr
ngs') [DebugBlock]
ndbgs
platform = NCGConfig -> Platform
ncgPlatform NCGConfig
config
unless (null ldbgs) $ liftIO $
putDumpFileMaybe logger Opt_D_dump_debug "Debug Infos" FormatText
(vcat $ map (pdoc platform) ldbgs)
let ngs'' = NativeGenAcc statics instr
ngs' { ngs_debug = ngs_debug ngs' ++ ldbgs, ngs_labels = [] }
return ngs''
loop cmm_stream' ngs''
cmmNativeGens :: forall statics instr jumpDest.
(OutputableP Platform statics, Outputable jumpDest, Instruction instr)
=> Logger
-> NCGConfig
-> NcgImpl statics instr jumpDest
-> BufHandle
-> LabelMap DebugBlock
-> [RawCmmDecl]
-> NativeGenAcc statics instr
-> Int
-> DUniqSupply
-> IO (NativeGenAcc statics instr, DUniqSupply)
cmmNativeGens :: forall statics instr jumpDest.
(OutputableP Platform statics, Outputable jumpDest,
Instruction instr) =>
Logger
-> NCGConfig
-> NcgImpl statics instr jumpDest
-> BufHandle
-> LabelMap DebugBlock
-> RawCmmGroup
-> NativeGenAcc statics instr
-> Int
-> DUniqSupply
-> IO (NativeGenAcc statics instr, DUniqSupply)
cmmNativeGens Logger
logger NCGConfig
config NcgImpl statics instr jumpDest
ncgImpl BufHandle
h LabelMap DebugBlock
dbgMap = RawCmmGroup
-> NativeGenAcc statics instr
-> Int
-> DUniqSupply
-> IO (NativeGenAcc statics instr, DUniqSupply)
go
where
go :: [RawCmmDecl]
-> NativeGenAcc statics instr -> Int -> DUniqSupply
-> IO (NativeGenAcc statics instr, DUniqSupply)
go :: RawCmmGroup
-> NativeGenAcc statics instr
-> Int
-> DUniqSupply
-> IO (NativeGenAcc statics instr, DUniqSupply)
go [] NativeGenAcc statics instr
ngs !Int
_ !DUniqSupply
us =
(NativeGenAcc statics instr, DUniqSupply)
-> IO (NativeGenAcc statics instr, DUniqSupply)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (NativeGenAcc statics instr
ngs, DUniqSupply
us)
go (RawCmmDecl
cmm : RawCmmGroup
cmms) NativeGenAcc statics instr
ngs Int
count DUniqSupply
us = do
let fileIds :: DwarfFiles
fileIds = NativeGenAcc statics instr -> DwarfFiles
forall statics instr. NativeGenAcc statics instr -> DwarfFiles
ngs_dwarfFiles NativeGenAcc statics instr
ngs
(us', fileIds', native, imports, colorStats, linearStats, unwinds, mcfg)
<- {-# SCC "cmmNativeGen" #-}
Logger
-> NcgImpl statics instr jumpDest
-> DUniqSupply
-> DwarfFiles
-> LabelMap DebugBlock
-> RawCmmDecl
-> Int
-> IO
(DUniqSupply, DwarfFiles, [NatCmmDecl statics instr], [CLabel],
Maybe [RegAllocStats statics instr], Maybe [RegAllocStats],
LabelMap [UnwindPoint], Maybe CFG)
forall statics instr jumpDest.
(Instruction instr, OutputableP Platform statics,
Outputable jumpDest) =>
Logger
-> NcgImpl statics instr jumpDest
-> DUniqSupply
-> DwarfFiles
-> LabelMap DebugBlock
-> RawCmmDecl
-> Int
-> IO
(DUniqSupply, DwarfFiles, [NatCmmDecl statics instr], [CLabel],
Maybe [RegAllocStats statics instr], Maybe [RegAllocStats],
LabelMap [UnwindPoint], Maybe CFG)
cmmNativeGen Logger
logger NcgImpl statics instr jumpDest
ncgImpl DUniqSupply
us DwarfFiles
fileIds LabelMap DebugBlock
dbgMap
RawCmmDecl
cmm Int
count
let newFileIds = ((FastString, Int) -> (FastString, Int) -> Ordering)
-> [(FastString, Int)] -> [(FastString, Int)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((FastString, Int) -> Int)
-> (FastString, Int) -> (FastString, Int) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (FastString, Int) -> Int
forall a b. (a, b) -> b
snd) ([(FastString, Int)] -> [(FastString, Int)])
-> [(FastString, Int)] -> [(FastString, Int)]
forall a b. (a -> b) -> a -> b
$
DwarfFiles -> [(FastString, Int)]
forall {k} (key :: k) elt. UniqFM key elt -> [elt]
nonDetEltsUFM (DwarfFiles -> [(FastString, Int)])
-> DwarfFiles -> [(FastString, Int)]
forall a b. (a -> b) -> a -> b
$ DwarfFiles
fileIds' DwarfFiles -> DwarfFiles -> DwarfFiles
forall {k} (key :: k) elt1 elt2.
UniqFM key elt1 -> UniqFM key elt2 -> UniqFM key elt1
`minusUFM` DwarfFiles
fileIds
pprDecl (FastString
f,Int
n) = Line b -> b
forall doc. IsDoc doc => Line doc -> doc
line (Line b -> b) -> Line b -> b
forall a b. (a -> b) -> a -> b
$ String -> Line b
forall doc. IsLine doc => String -> doc
text String
"\t.file " Line b -> Line b -> Line b
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> Line b
forall doc. IsLine doc => Int -> doc
int Int
n Line b -> Line b -> Line b
forall doc. IsLine doc => doc -> doc -> doc
<+>
String -> Line b
forall doc. IsLine doc => String -> doc
pprFilePathString (FastString -> String
unpackFS FastString
f)
emitNativeCode logger config h
(vcat $
map pprDecl newFileIds ++
map (pprNatCmmDeclH ncgImpl) native)
(vcat $
map pprDecl newFileIds ++
map (pprNatCmmDeclS ncgImpl) native)
let platform = NCGConfig -> Platform
ncgPlatform NCGConfig
config
{-# SCC "seqString" #-} evaluate $ seqList (showSDocUnsafe $ vcat $ map (pprAsmLabel platform) imports) ()
let !labels' = if NCGConfig -> Bool
ncgDwarfEnabled NCGConfig
config
then (Label -> Bool)
-> (instr -> Bool) -> [NatCmmDecl statics instr] -> [Label]
forall i d g.
(Label -> Bool)
-> (i -> Bool) -> GenCmmGroup d g (ListGraph i) -> [Label]
cmmDebugLabels Label -> Bool
is_valid_label instr -> Bool
forall instr. Instruction instr => instr -> Bool
isMetaInstr [NatCmmDecl statics instr]
native else []
is_valid_label
| Just CFG
cfg <- Maybe CFG
mcfg = CFG -> Label -> Bool
hasNode CFG
cfg
| Bool
otherwise = Bool -> Label -> Bool
forall a b. a -> b -> a
const Bool
True
!natives' = if Logger -> DumpFlag -> Bool
logHasDumpFlag Logger
logger DumpFlag
Opt_D_dump_asm_stats
then [NatCmmDecl statics instr]
native [NatCmmDecl statics instr]
-> [[NatCmmDecl statics instr]] -> [[NatCmmDecl statics instr]]
forall a. a -> [a] -> [a]
: NativeGenAcc statics instr -> [[NatCmmDecl statics instr]]
forall statics instr.
NativeGenAcc statics instr -> [[NatCmmDecl statics instr]]
ngs_natives NativeGenAcc statics instr
ngs else []
mCon = ([a] -> [a]) -> (a -> [a] -> [a]) -> Maybe a -> [a] -> [a]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [a] -> [a]
forall a. a -> a
id (:)
ngs' = NativeGenAcc statics instr
ngs{ ngs_imports = imports : ngs_imports ngs
, ngs_natives = natives'
, ngs_colorStats = colorStats `mCon` ngs_colorStats ngs
, ngs_linearStats = linearStats `mCon` ngs_linearStats ngs
, ngs_labels = ngs_labels ngs ++ labels'
, ngs_dwarfFiles = fileIds'
, ngs_unwinds = ngs_unwinds ngs `mapUnion` unwinds
}
go cmms ngs' (count + 1) us'
emitNativeCode :: Logger -> NCGConfig -> BufHandle -> HDoc -> SDoc -> IO ()
emitNativeCode :: Logger -> NCGConfig -> BufHandle -> HDoc -> SDoc -> IO ()
emitNativeCode Logger
logger NCGConfig
config BufHandle
h HDoc
hdoc SDoc
sdoc = do
let ctx :: SDocContext
ctx = NCGConfig -> SDocContext
ncgAsmContext NCGConfig
config
{-# SCC "pprNativeCode" #-} BufHandle -> SDocContext -> HDoc -> IO ()
bPutHDoc BufHandle
h SDocContext
ctx HDoc
hdoc
Logger -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
putDumpFileMaybe Logger
logger
DumpFlag
Opt_D_dump_asm String
"Asm code" DumpFormat
FormatASM
SDoc
sdoc
cmmNativeGen
:: forall statics instr jumpDest. (Instruction instr, OutputableP Platform statics, Outputable jumpDest)
=> Logger
-> NcgImpl statics instr jumpDest
-> DUniqSupply
-> DwarfFiles
-> LabelMap DebugBlock
-> RawCmmDecl
-> Int
-> IO ( DUniqSupply
, DwarfFiles
, [NatCmmDecl statics instr]
, [CLabel]
, Maybe [Color.RegAllocStats statics instr]
, Maybe [Linear.RegAllocStats]
, LabelMap [UnwindPoint]
, Maybe CFG
)
cmmNativeGen :: forall statics instr jumpDest.
(Instruction instr, OutputableP Platform statics,
Outputable jumpDest) =>
Logger
-> NcgImpl statics instr jumpDest
-> DUniqSupply
-> DwarfFiles
-> LabelMap DebugBlock
-> RawCmmDecl
-> Int
-> IO
(DUniqSupply, DwarfFiles, [NatCmmDecl statics instr], [CLabel],
Maybe [RegAllocStats statics instr], Maybe [RegAllocStats],
LabelMap [UnwindPoint], Maybe CFG)
cmmNativeGen Logger
logger NcgImpl statics instr jumpDest
ncgImpl DUniqSupply
us DwarfFiles
fileIds LabelMap DebugBlock
dbgMap RawCmmDecl
cmm Int
count
= do
let config :: NCGConfig
config = NcgImpl statics instr jumpDest -> NCGConfig
forall statics instr jumpDest.
NcgImpl statics instr jumpDest -> NCGConfig
ncgConfig NcgImpl statics instr jumpDest
ncgImpl
let platform :: Platform
platform = NCGConfig -> Platform
ncgPlatform NCGConfig
config
let weights :: Weights
weights = NCGConfig -> Weights
ncgCfgWeights NCGConfig
config
let proc_name :: SDoc
proc_name = case RawCmmDecl
cmm of
(CmmProc LabelMap RawCmmStatics
_ CLabel
entry_label [GlobalRegUse]
_ CmmGraph
_) -> Platform -> CLabel -> SDoc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
entry_label
RawCmmDecl
_ -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"DataChunk"
let fixed_cmm :: RawCmmDecl
fixed_cmm =
{-# SCC "fixStgRegisters" #-}
Platform -> RawCmmDecl -> RawCmmDecl
fixStgRegisters Platform
platform RawCmmDecl
cmm
let (RawCmmDecl
opt_cmm, [CLabel]
imports) =
{-# SCC "cmmToCmm" #-}
NCGConfig -> RawCmmDecl -> (RawCmmDecl, [CLabel])
cmmToCmm NCGConfig
config RawCmmDecl
fixed_cmm
Logger -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
putDumpFileMaybe Logger
logger
DumpFlag
Opt_D_dump_opt_cmm String
"Optimised Cmm" DumpFormat
FormatCMM
(Platform -> RawCmmGroup -> SDoc
forall d info g.
(OutputableP Platform d, OutputableP Platform info,
OutputableP Platform g) =>
Platform -> GenCmmGroup d info g -> SDoc
pprCmmGroup Platform
platform [RawCmmDecl
opt_cmm])
let cmmCfg :: CFG
cmmCfg = {-# SCC "getCFG" #-}
Platform -> Weights -> RawCmmDecl -> CFG
getCfgProc Platform
platform Weights
weights RawCmmDecl
opt_cmm
let (([NatCmmDecl statics instr]
native, [CLabel]
lastMinuteImports, DwarfFiles
fileIds', CFG
nativeCfgWeights), DUniqSupply
usGen) =
{-# SCC "genMachCode" #-}
DUniqSupply
-> UniqDSM ([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG)
-> (([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG),
DUniqSupply)
forall a. DUniqSupply -> UniqDSM a -> (a, DUniqSupply)
runUniqueDSM DUniqSupply
us (UniqDSM ([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG)
-> (([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG),
DUniqSupply))
-> UniqDSM ([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG)
-> (([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG),
DUniqSupply)
forall a b. (a -> b) -> a -> b
$ NCGConfig
-> (RawCmmDecl -> NatM [NatCmmDecl statics instr])
-> DwarfFiles
-> LabelMap DebugBlock
-> RawCmmDecl
-> CFG
-> UniqDSM ([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG)
forall statics instr.
NCGConfig
-> (RawCmmDecl -> NatM [NatCmmDecl statics instr])
-> DwarfFiles
-> LabelMap DebugBlock
-> RawCmmDecl
-> CFG
-> UniqDSM ([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG)
genMachCode NCGConfig
config
(NcgImpl statics instr jumpDest
-> RawCmmDecl -> NatM [NatCmmDecl statics instr]
forall statics instr jumpDest.
NcgImpl statics instr jumpDest
-> RawCmmDecl -> NatM [NatCmmDecl statics instr]
cmmTopCodeGen NcgImpl statics instr jumpDest
ncgImpl)
DwarfFiles
fileIds LabelMap DebugBlock
dbgMap RawCmmDecl
opt_cmm CFG
cmmCfg
Logger -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
putDumpFileMaybe Logger
logger
DumpFlag
Opt_D_dump_asm_native String
"Native code" DumpFormat
FormatASM
([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (NatCmmDecl statics instr -> SDoc)
-> [NatCmmDecl statics instr] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (NcgImpl statics instr jumpDest -> NatCmmDecl statics instr -> SDoc
forall statics instr jumpDest.
NcgImpl statics instr jumpDest -> NatCmmDecl statics instr -> SDoc
pprNatCmmDeclS NcgImpl statics instr jumpDest
ncgImpl) [NatCmmDecl statics instr]
native)
Logger -> Maybe CFG -> String -> SDoc -> IO ()
maybeDumpCfg Logger
logger (CFG -> Maybe CFG
forall a. a -> Maybe a
Just CFG
nativeCfgWeights) String
"CFG Weights - Native" SDoc
proc_name
let livenessCfg :: Maybe CFG
livenessCfg = if NCGConfig -> Bool
ncgEnableDeadCodeElimination NCGConfig
config
then CFG -> Maybe CFG
forall a. a -> Maybe a
Just CFG
nativeCfgWeights
else Maybe CFG
forall a. Maybe a
Nothing
let ([LiveCmmDecl statics instr]
withLiveness, DUniqSupply
usLive) =
{-# SCC "regLiveness" #-}
DUniqSupply
-> UniqDSM [LiveCmmDecl statics instr]
-> ([LiveCmmDecl statics instr], DUniqSupply)
forall a. DUniqSupply -> UniqDSM a -> (a, DUniqSupply)
runUniqueDSM DUniqSupply
usGen
(UniqDSM [LiveCmmDecl statics instr]
-> ([LiveCmmDecl statics instr], DUniqSupply))
-> UniqDSM [LiveCmmDecl statics instr]
-> ([LiveCmmDecl statics instr], DUniqSupply)
forall a b. (a -> b) -> a -> b
$ (NatCmmDecl statics instr -> UniqDSM (LiveCmmDecl statics instr))
-> [NatCmmDecl statics instr]
-> UniqDSM [LiveCmmDecl statics instr]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Maybe CFG
-> Platform
-> NatCmmDecl statics instr
-> UniqDSM (LiveCmmDecl statics instr)
forall instr statics.
Instruction instr =>
Maybe CFG
-> Platform
-> NatCmmDecl statics instr
-> UniqDSM (LiveCmmDecl statics instr)
cmmTopLiveness Maybe CFG
livenessCfg Platform
platform) [NatCmmDecl statics instr]
native
Logger -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
putDumpFileMaybe Logger
logger
DumpFlag
Opt_D_dump_asm_liveness String
"Liveness annotations added"
DumpFormat
FormatCMM
([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (LiveCmmDecl statics instr -> SDoc)
-> [LiveCmmDecl statics instr] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (Platform -> LiveCmmDecl statics instr -> SDoc
forall statics instr.
(OutputableP Platform statics, Instruction instr) =>
Platform -> LiveCmmDecl statics instr -> SDoc
pprLiveCmmDecl Platform
platform) [LiveCmmDecl statics instr]
withLiveness)
(alloced, usAlloc, ppr_raStatsColor, ppr_raStatsLinear, raStats, stack_updt_blks) <-
if ( NCGConfig -> Bool
ncgRegsGraph NCGConfig
config Bool -> Bool -> Bool
|| NCGConfig -> Bool
ncgRegsIterative NCGConfig
config )
then do
let UniqFM RegClass (UniqSet RealReg)
alloc_regs :: UniqFM RegClass (UniqSet RealReg)
= (RealReg
-> UniqFM RegClass (UniqSet RealReg)
-> UniqFM RegClass (UniqSet RealReg))
-> UniqFM RegClass (UniqSet RealReg)
-> [RealReg]
-> UniqFM RegClass (UniqSet RealReg)
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\RealReg
r -> (UniqSet RealReg -> UniqSet RealReg -> UniqSet RealReg)
-> UniqFM RegClass (UniqSet RealReg)
-> UniqFM RegClass (UniqSet RealReg)
-> UniqFM RegClass (UniqSet RealReg)
forall {k} elt (key :: k).
(elt -> elt -> elt)
-> UniqFM key elt -> UniqFM key elt -> UniqFM key elt
plusUFM_C UniqSet RealReg -> UniqSet RealReg -> UniqSet RealReg
forall a. UniqSet a -> UniqSet a -> UniqSet a
unionUniqSets
(UniqFM RegClass (UniqSet RealReg)
-> UniqFM RegClass (UniqSet RealReg)
-> UniqFM RegClass (UniqSet RealReg))
-> UniqFM RegClass (UniqSet RealReg)
-> UniqFM RegClass (UniqSet RealReg)
-> UniqFM RegClass (UniqSet RealReg)
forall a b. (a -> b) -> a -> b
$ RegClass -> UniqSet RealReg -> UniqFM RegClass (UniqSet RealReg)
forall key elt. Uniquable key => key -> elt -> UniqFM key elt
unitUFM (Platform -> RealReg -> RegClass
targetClassOfRealReg Platform
platform RealReg
r) (RealReg -> UniqSet RealReg
forall a. Uniquable a => a -> UniqSet a
unitUniqSet RealReg
r))
UniqFM RegClass (UniqSet RealReg)
forall {k} (key :: k) elt. UniqFM key elt
emptyUFM
([RealReg] -> UniqFM RegClass (UniqSet RealReg))
-> [RealReg] -> UniqFM RegClass (UniqSet RealReg)
forall a b. (a -> b) -> a -> b
$ NcgImpl statics instr jumpDest -> [RealReg]
forall statics instr jumpDest.
NcgImpl statics instr jumpDest -> [RealReg]
allocatableRegs NcgImpl statics instr jumpDest
ncgImpl
let (([NatCmmDecl statics instr]
alloced, Maybe Int
maybe_more_stack, [RegAllocStats statics instr]
regAllocStats), DUniqSupply
usAlloc)
= {-# SCC "RegAlloc-color" #-}
DUniqSupply
-> UniqDSM
([NatCmmDecl statics instr], Maybe Int,
[RegAllocStats statics instr])
-> (([NatCmmDecl statics instr], Maybe Int,
[RegAllocStats statics instr]),
DUniqSupply)
forall a. DUniqSupply -> UniqDSM a -> (a, DUniqSupply)
runUniqueDSM DUniqSupply
usLive
(UniqDSM
([NatCmmDecl statics instr], Maybe Int,
[RegAllocStats statics instr])
-> (([NatCmmDecl statics instr], Maybe Int,
[RegAllocStats statics instr]),
DUniqSupply))
-> UniqDSM
([NatCmmDecl statics instr], Maybe Int,
[RegAllocStats statics instr])
-> (([NatCmmDecl statics instr], Maybe Int,
[RegAllocStats statics instr]),
DUniqSupply)
forall a b. (a -> b) -> a -> b
$ NCGConfig
-> UniqFM RegClass (UniqSet RealReg)
-> UniqSet Int
-> Int
-> [LiveCmmDecl statics instr]
-> Maybe CFG
-> UniqDSM
([NatCmmDecl statics instr], Maybe Int,
[RegAllocStats statics instr])
forall statics instr.
(OutputableP Platform statics, Instruction instr) =>
NCGConfig
-> UniqFM RegClass (UniqSet RealReg)
-> UniqSet Int
-> Int
-> [LiveCmmDecl statics instr]
-> Maybe CFG
-> UniqDSM
([NatCmmDecl statics instr], Maybe Int,
[RegAllocStats statics instr])
Color.regAlloc
NCGConfig
config
UniqFM RegClass (UniqSet RealReg)
alloc_regs
([Int] -> UniqSet Int
forall a. Uniquable a => [a] -> UniqSet a
mkUniqSet [Int
0 .. NcgImpl statics instr jumpDest -> Int
forall statics instr jumpDest.
NcgImpl statics instr jumpDest -> Int
maxSpillSlots NcgImpl statics instr jumpDest
ncgImpl])
(NcgImpl statics instr jumpDest -> Int
forall statics instr jumpDest.
NcgImpl statics instr jumpDest -> Int
maxSpillSlots NcgImpl statics instr jumpDest
ncgImpl)
[LiveCmmDecl statics instr]
withLiveness
Maybe CFG
livenessCfg
let (([NatCmmDecl statics instr]
alloced', [(Label, Label)]
stack_updt_blks), DUniqSupply
usAlloc')
= DUniqSupply
-> UniqDSM ([NatCmmDecl statics instr], [(Label, Label)])
-> (([NatCmmDecl statics instr], [(Label, Label)]), DUniqSupply)
forall a. DUniqSupply -> UniqDSM a -> (a, DUniqSupply)
runUniqueDSM DUniqSupply
usAlloc (UniqDSM ([NatCmmDecl statics instr], [(Label, Label)])
-> (([NatCmmDecl statics instr], [(Label, Label)]), DUniqSupply))
-> UniqDSM ([NatCmmDecl statics instr], [(Label, Label)])
-> (([NatCmmDecl statics instr], [(Label, Label)]), DUniqSupply)
forall a b. (a -> b) -> a -> b
$
case Maybe Int
maybe_more_stack of
Maybe Int
Nothing -> ([NatCmmDecl statics instr], [(Label, Label)])
-> UniqDSM ([NatCmmDecl statics instr], [(Label, Label)])
forall a. a -> UniqDSM a
forall (m :: * -> *) a. Monad m => a -> m a
return ([NatCmmDecl statics instr]
alloced, [])
Just Int
amount -> do
(alloced',stack_updt_blks) <- [(NatCmmDecl statics instr, [(Label, Label)])]
-> ([NatCmmDecl statics instr], [[(Label, Label)]])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(NatCmmDecl statics instr, [(Label, Label)])]
-> ([NatCmmDecl statics instr], [[(Label, Label)]]))
-> UniqDSM [(NatCmmDecl statics instr, [(Label, Label)])]
-> UniqDSM ([NatCmmDecl statics instr], [[(Label, Label)]])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
((NatCmmDecl statics instr
-> UniqDSM (NatCmmDecl statics instr, [(Label, Label)]))
-> [NatCmmDecl statics instr]
-> UniqDSM [(NatCmmDecl statics instr, [(Label, Label)])]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM ((NcgImpl statics instr jumpDest
-> Int
-> NatCmmDecl statics instr
-> UniqDSM (NatCmmDecl statics instr, [(Label, Label)])
forall statics instr jumpDest.
NcgImpl statics instr jumpDest
-> Int
-> NatCmmDecl statics instr
-> UniqDSM (NatCmmDecl statics instr, [(Label, Label)])
ncgAllocMoreStack NcgImpl statics instr jumpDest
ncgImpl) Int
amount) [NatCmmDecl statics instr]
alloced)
return (alloced', concat stack_updt_blks )
Logger -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
putDumpFileMaybe Logger
logger
DumpFlag
Opt_D_dump_asm_regalloc String
"Registers allocated"
DumpFormat
FormatCMM
([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (NatCmmDecl statics instr -> SDoc)
-> [NatCmmDecl statics instr] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (NcgImpl statics instr jumpDest -> NatCmmDecl statics instr -> SDoc
forall statics instr jumpDest.
NcgImpl statics instr jumpDest -> NatCmmDecl statics instr -> SDoc
pprNatCmmDeclS NcgImpl statics instr jumpDest
ncgImpl) [NatCmmDecl statics instr]
alloced)
Logger -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
putDumpFileMaybe Logger
logger
DumpFlag
Opt_D_dump_asm_regalloc_stages String
"Build/spill stages"
DumpFormat
FormatText
([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ ((Int, RegAllocStats statics instr) -> SDoc)
-> [(Int, RegAllocStats statics instr)] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (\(Int
stage, RegAllocStats statics instr
stats)
-> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"# --------------------------"
SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"# cmm " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int Int
count SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
" Stage " SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int Int
stage
SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ RegAllocStats statics SDoc -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((instr -> SDoc)
-> RegAllocStats statics instr -> RegAllocStats statics SDoc
forall a b.
(a -> b) -> RegAllocStats statics a -> RegAllocStats statics b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Platform -> instr -> SDoc
forall instr. Instruction instr => Platform -> instr -> SDoc
pprInstr Platform
platform) RegAllocStats statics instr
stats))
([(Int, RegAllocStats statics instr)] -> [SDoc])
-> [(Int, RegAllocStats statics instr)] -> [SDoc]
forall a b. (a -> b) -> a -> b
$ [Int]
-> [RegAllocStats statics instr]
-> [(Int, RegAllocStats statics instr)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] [RegAllocStats statics instr]
regAllocStats)
let mPprStats :: Maybe [RegAllocStats statics instr]
mPprStats =
if Logger -> DumpFlag -> Bool
logHasDumpFlag Logger
logger DumpFlag
Opt_D_dump_asm_stats
then [RegAllocStats statics instr]
-> Maybe [RegAllocStats statics instr]
forall a. a -> Maybe a
Just [RegAllocStats statics instr]
regAllocStats else Maybe [RegAllocStats statics instr]
forall a. Maybe a
Nothing
Maybe [RegAllocStats statics instr]
mPprStats Maybe [RegAllocStats statics instr] -> IO () -> IO ()
forall a b. a -> b -> b
`seq` () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
([NatCmmDecl statics instr], DUniqSupply,
Maybe [RegAllocStats statics instr], Maybe [RegAllocStats],
[RegAllocStats], [(Label, Label)])
-> IO
([NatCmmDecl statics instr], DUniqSupply,
Maybe [RegAllocStats statics instr], Maybe [RegAllocStats],
[RegAllocStats], [(Label, Label)])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ( [NatCmmDecl statics instr]
alloced', DUniqSupply
usAlloc'
, Maybe [RegAllocStats statics instr]
mPprStats
, Maybe [RegAllocStats]
forall a. Maybe a
Nothing
, [], [(Label, Label)]
stack_updt_blks)
else do
let reg_alloc :: LiveCmmDecl statics instr
-> UniqDSM
(NatCmmDecl statics instr, Maybe RegAllocStats, [(Label, Label)])
reg_alloc LiveCmmDecl statics instr
proc = do
(alloced, maybe_more_stack, ra_stats) <-
NCGConfig
-> LiveCmmDecl statics instr
-> UniqDSM
(NatCmmDecl statics instr, Maybe Int, Maybe RegAllocStats)
forall instr statics.
Instruction instr =>
NCGConfig
-> LiveCmmDecl statics instr
-> UniqDSM
(NatCmmDecl statics instr, Maybe Int, Maybe RegAllocStats)
Linear.regAlloc NCGConfig
config LiveCmmDecl statics instr
proc
case maybe_more_stack of
Maybe Int
Nothing -> (NatCmmDecl statics instr, Maybe RegAllocStats, [(Label, Label)])
-> UniqDSM
(NatCmmDecl statics instr, Maybe RegAllocStats, [(Label, Label)])
forall a. a -> UniqDSM a
forall (m :: * -> *) a. Monad m => a -> m a
return ( NatCmmDecl statics instr
alloced, Maybe RegAllocStats
ra_stats, [] )
Just Int
amount -> do
(alloced',stack_updt_blks) <-
NcgImpl statics instr jumpDest
-> Int
-> NatCmmDecl statics instr
-> UniqDSM (NatCmmDecl statics instr, [(Label, Label)])
forall statics instr jumpDest.
NcgImpl statics instr jumpDest
-> Int
-> NatCmmDecl statics instr
-> UniqDSM (NatCmmDecl statics instr, [(Label, Label)])
ncgAllocMoreStack NcgImpl statics instr jumpDest
ncgImpl Int
amount NatCmmDecl statics instr
alloced
return (alloced', ra_stats, stack_updt_blks )
let (([NatCmmDecl statics instr]
alloced, [Maybe RegAllocStats]
regAllocStats, [[(Label, Label)]]
stack_updt_blks), DUniqSupply
usAlloc)
= {-# SCC "RegAlloc-linear" #-}
DUniqSupply
-> UniqDSM
([NatCmmDecl statics instr], [Maybe RegAllocStats],
[[(Label, Label)]])
-> (([NatCmmDecl statics instr], [Maybe RegAllocStats],
[[(Label, Label)]]),
DUniqSupply)
forall a. DUniqSupply -> UniqDSM a -> (a, DUniqSupply)
runUniqueDSM DUniqSupply
usLive
(UniqDSM
([NatCmmDecl statics instr], [Maybe RegAllocStats],
[[(Label, Label)]])
-> (([NatCmmDecl statics instr], [Maybe RegAllocStats],
[[(Label, Label)]]),
DUniqSupply))
-> UniqDSM
([NatCmmDecl statics instr], [Maybe RegAllocStats],
[[(Label, Label)]])
-> (([NatCmmDecl statics instr], [Maybe RegAllocStats],
[[(Label, Label)]]),
DUniqSupply)
forall a b. (a -> b) -> a -> b
$ ([(NatCmmDecl statics instr, Maybe RegAllocStats,
[(Label, Label)])]
-> ([NatCmmDecl statics instr], [Maybe RegAllocStats],
[[(Label, Label)]]))
-> UniqDSM
[(NatCmmDecl statics instr, Maybe RegAllocStats, [(Label, Label)])]
-> UniqDSM
([NatCmmDecl statics instr], [Maybe RegAllocStats],
[[(Label, Label)]])
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM [(NatCmmDecl statics instr, Maybe RegAllocStats, [(Label, Label)])]
-> ([NatCmmDecl statics instr], [Maybe RegAllocStats],
[[(Label, Label)]])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3
(UniqDSM
[(NatCmmDecl statics instr, Maybe RegAllocStats, [(Label, Label)])]
-> UniqDSM
([NatCmmDecl statics instr], [Maybe RegAllocStats],
[[(Label, Label)]]))
-> UniqDSM
[(NatCmmDecl statics instr, Maybe RegAllocStats, [(Label, Label)])]
-> UniqDSM
([NatCmmDecl statics instr], [Maybe RegAllocStats],
[[(Label, Label)]])
forall a b. (a -> b) -> a -> b
$ (LiveCmmDecl statics instr
-> UniqDSM
(NatCmmDecl statics instr, Maybe RegAllocStats, [(Label, Label)]))
-> [LiveCmmDecl statics instr]
-> UniqDSM
[(NatCmmDecl statics instr, Maybe RegAllocStats, [(Label, Label)])]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM LiveCmmDecl statics instr
-> UniqDSM
(NatCmmDecl statics instr, Maybe RegAllocStats, [(Label, Label)])
reg_alloc [LiveCmmDecl statics instr]
withLiveness
Logger -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
putDumpFileMaybe Logger
logger
DumpFlag
Opt_D_dump_asm_regalloc String
"Registers allocated"
DumpFormat
FormatCMM
([SDoc] -> SDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (NatCmmDecl statics instr -> SDoc)
-> [NatCmmDecl statics instr] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (NcgImpl statics instr jumpDest -> NatCmmDecl statics instr -> SDoc
forall statics instr jumpDest.
NcgImpl statics instr jumpDest -> NatCmmDecl statics instr -> SDoc
pprNatCmmDeclS NcgImpl statics instr jumpDest
ncgImpl) [NatCmmDecl statics instr]
alloced)
let mPprStats :: Maybe [RegAllocStats]
mPprStats =
if Logger -> DumpFlag -> Bool
logHasDumpFlag Logger
logger DumpFlag
Opt_D_dump_asm_stats
then [RegAllocStats] -> Maybe [RegAllocStats]
forall a. a -> Maybe a
Just ([Maybe RegAllocStats] -> [RegAllocStats]
forall a. [Maybe a] -> [a]
catMaybes [Maybe RegAllocStats]
regAllocStats) else Maybe [RegAllocStats]
forall a. Maybe a
Nothing
Maybe [RegAllocStats]
mPprStats Maybe [RegAllocStats] -> IO () -> IO ()
forall a b. a -> b -> b
`seq` () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
([NatCmmDecl statics instr], DUniqSupply,
Maybe [RegAllocStats statics instr], Maybe [RegAllocStats],
[RegAllocStats], [(Label, Label)])
-> IO
([NatCmmDecl statics instr], DUniqSupply,
Maybe [RegAllocStats statics instr], Maybe [RegAllocStats],
[RegAllocStats], [(Label, Label)])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ( [NatCmmDecl statics instr]
alloced, DUniqSupply
usAlloc
, Maybe [RegAllocStats statics instr]
forall a. Maybe a
Nothing
, Maybe [RegAllocStats]
mPprStats, ([Maybe RegAllocStats] -> [RegAllocStats]
forall a. [Maybe a] -> [a]
catMaybes [Maybe RegAllocStats]
regAllocStats)
, [[(Label, Label)]] -> [(Label, Label)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[(Label, Label)]]
stack_updt_blks )
let cfgRegAllocUpdates :: [(BlockId,BlockId,BlockId)]
cfgRegAllocUpdates = ((RegAllocStats -> [(Label, Label, Label)])
-> [RegAllocStats] -> [(Label, Label, Label)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap RegAllocStats -> [(Label, Label, Label)]
Linear.ra_fixupList [RegAllocStats]
raStats)
let cfgWithFixupBlks =
(\CFG
cfg -> Weights -> CFG -> [(Label, Label, Label)] -> CFG
addNodesBetween Weights
weights CFG
cfg [(Label, Label, Label)]
cfgRegAllocUpdates) (CFG -> CFG) -> Maybe CFG -> Maybe CFG
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe CFG
livenessCfg
let postRegCFG =
(CFG -> [(Label, Label)] -> CFG)
-> Maybe (CFG -> [(Label, Label)] -> CFG)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((CFG -> (Label, Label) -> CFG) -> CFG -> [(Label, Label)] -> CFG
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\CFG
m (Label
from,Label
to) -> Weights -> Label -> Label -> CFG -> CFG
addImmediateSuccessor Weights
weights Label
from Label
to CFG
m ))
Maybe (CFG -> [(Label, Label)] -> CFG)
-> Maybe CFG -> Maybe ([(Label, Label)] -> CFG)
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe CFG
cfgWithFixupBlks
Maybe ([(Label, Label)] -> CFG)
-> Maybe [(Label, Label)] -> Maybe CFG
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [(Label, Label)] -> Maybe [(Label, Label)]
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [(Label, Label)]
stack_updt_blks
let tabled =
{-# SCC "generateJumpTables" #-}
NcgImpl statics instr jumpDest
-> [NatCmmDecl statics instr] -> [NatCmmDecl statics instr]
forall statics instr jumpDest.
NcgImpl statics instr jumpDest
-> [NatCmmDecl statics instr] -> [NatCmmDecl statics instr]
generateJumpTables NcgImpl statics instr jumpDest
ncgImpl [NatCmmDecl statics instr]
alloced
when (not $ null nativeCfgWeights) $ putDumpFileMaybe logger
Opt_D_dump_cfg_weights "CFG Update information"
FormatText
( text "stack:" <+> ppr stack_updt_blks $$
text "linearAlloc:" <+> ppr cfgRegAllocUpdates )
let (shorted, postShortCFG) =
{-# SCC "shortcutBranches" #-}
shortcutBranches config ncgImpl tabled postRegCFG
let optimizedCFG :: Maybe CFG
optimizedCFG =
Bool -> Weights -> RawCmmDecl -> CFG -> CFG
optimizeCFG (NCGConfig -> Bool
ncgCmmStaticPred NCGConfig
config) Weights
weights RawCmmDecl
cmm (CFG -> CFG) -> Maybe CFG -> Maybe CFG
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
<$!> Maybe CFG
postShortCFG
maybeDumpCfg logger optimizedCFG "CFG Weights - Final" proc_name
let getBlks (CmmProc h
_info CLabel
_lbl [GlobalRegUse]
_live (ListGraph [GenBasicBlock i]
blocks)) = [GenBasicBlock i]
blocks
getBlks GenCmmDecl d h (ListGraph i)
_ = []
when ( ncgEnableDeadCodeElimination config &&
(ncgAsmLinting config || debugIsOn )) $ do
let blocks = (NatCmmDecl statics instr -> [GenBasicBlock instr])
-> [NatCmmDecl statics instr] -> [GenBasicBlock instr]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap NatCmmDecl statics instr -> [GenBasicBlock instr]
forall {d} {h} {i}.
GenCmmDecl d h (ListGraph i) -> [GenBasicBlock i]
getBlks [NatCmmDecl statics instr]
shorted
let labels = [Label] -> LabelSet
setFromList ([Label] -> LabelSet) -> [Label] -> LabelSet
forall a b. (a -> b) -> a -> b
$ (GenBasicBlock instr -> Label) -> [GenBasicBlock instr] -> [Label]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap GenBasicBlock instr -> Label
forall i. GenBasicBlock i -> Label
blockId [GenBasicBlock instr]
blocks :: LabelSet
let cfg = Maybe CFG -> CFG
forall a. HasCallStack => Maybe a -> a
fromJust Maybe CFG
optimizedCFG
return $! seq (sanityCheckCfg cfg labels $
text "cfg not in lockstep") ()
let (sequenced, us_seq) =
{-# SCC "sequenceBlocks" #-}
runUniqueDSM usAlloc $ mapM (BlockLayout.sequenceTop
ncgImpl optimizedCFG)
shorted
massert (checkLayout shorted sequenced)
let branchOpt :: [NatCmmDecl statics instr]
branchOpt =
{-# SCC "invertCondBranches" #-}
(NatCmmDecl statics instr -> NatCmmDecl statics instr)
-> [NatCmmDecl statics instr] -> [NatCmmDecl statics instr]
forall a b. (a -> b) -> [a] -> [b]
map NatCmmDecl statics instr -> NatCmmDecl statics instr
invert [NatCmmDecl statics instr]
sequenced
where
invertConds :: LabelMap RawCmmStatics -> [NatBasicBlock instr]
-> [NatBasicBlock instr]
invertConds :: LabelMap RawCmmStatics
-> [GenBasicBlock instr] -> [GenBasicBlock instr]
invertConds = NcgImpl statics instr jumpDest
-> Maybe CFG
-> LabelMap RawCmmStatics
-> [GenBasicBlock instr]
-> [GenBasicBlock instr]
forall statics instr jumpDest.
NcgImpl statics instr jumpDest
-> Maybe CFG
-> LabelMap RawCmmStatics
-> [NatBasicBlock instr]
-> [NatBasicBlock instr]
invertCondBranches NcgImpl statics instr jumpDest
ncgImpl Maybe CFG
optimizedCFG
invert :: NatCmmDecl statics instr -> NatCmmDecl statics instr
invert top :: NatCmmDecl statics instr
top@CmmData {} = NatCmmDecl statics instr
top
invert (CmmProc LabelMap RawCmmStatics
info CLabel
lbl [GlobalRegUse]
live (ListGraph [GenBasicBlock instr]
blocks)) =
LabelMap RawCmmStatics
-> CLabel
-> [GlobalRegUse]
-> ListGraph instr
-> NatCmmDecl statics instr
forall d h g.
h -> CLabel -> [GlobalRegUse] -> g -> GenCmmDecl d h g
CmmProc LabelMap RawCmmStatics
info CLabel
lbl [GlobalRegUse]
live ([GenBasicBlock instr] -> ListGraph instr
forall i. [GenBasicBlock i] -> ListGraph i
ListGraph ([GenBasicBlock instr] -> ListGraph instr)
-> [GenBasicBlock instr] -> ListGraph instr
forall a b. (a -> b) -> a -> b
$ LabelMap RawCmmStatics
-> [GenBasicBlock instr] -> [GenBasicBlock instr]
invertConds LabelMap RawCmmStatics
info [GenBasicBlock instr]
blocks)
let unwinds :: BlockMap [UnwindPoint]
unwinds =
{-# SCC "unwindingInfo" #-}
(LabelMap [UnwindPoint]
-> NatCmmDecl statics instr -> LabelMap [UnwindPoint])
-> LabelMap [UnwindPoint]
-> [NatCmmDecl statics instr]
-> LabelMap [UnwindPoint]
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' LabelMap [UnwindPoint]
-> NatCmmDecl statics instr -> LabelMap [UnwindPoint]
addUnwind LabelMap [UnwindPoint]
forall v. LabelMap v
mapEmpty [NatCmmDecl statics instr]
branchOpt
where
addUnwind :: LabelMap [UnwindPoint]
-> NatCmmDecl statics instr -> LabelMap [UnwindPoint]
addUnwind LabelMap [UnwindPoint]
acc NatCmmDecl statics instr
proc =
LabelMap [UnwindPoint]
acc LabelMap [UnwindPoint]
-> LabelMap [UnwindPoint] -> LabelMap [UnwindPoint]
forall v. LabelMap v -> LabelMap v -> LabelMap v
`mapUnion` NCGConfig
-> NcgImpl statics instr jumpDest
-> NatCmmDecl statics instr
-> LabelMap [UnwindPoint]
forall instr statics jumpDest.
Instruction instr =>
NCGConfig
-> NcgImpl statics instr jumpDest
-> NatCmmDecl statics instr
-> LabelMap [UnwindPoint]
computeUnwinding NCGConfig
config NcgImpl statics instr jumpDest
ncgImpl NatCmmDecl statics instr
proc
return ( us_seq
, fileIds'
, branchOpt
, lastMinuteImports ++ imports
, ppr_raStatsColor
, ppr_raStatsLinear
, unwinds
, optimizedCFG
)
maybeDumpCfg :: Logger -> Maybe CFG -> String -> SDoc -> IO ()
maybeDumpCfg :: Logger -> Maybe CFG -> String -> SDoc -> IO ()
maybeDumpCfg Logger
_logger Maybe CFG
Nothing String
_ SDoc
_ = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
maybeDumpCfg Logger
logger (Just CFG
cfg) String
msg SDoc
proc_name
| CFG -> Bool
forall a. LabelMap a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null CFG
cfg = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise
= Logger -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
putDumpFileMaybe Logger
logger
DumpFlag
Opt_D_dump_cfg_weights String
msg
DumpFormat
FormatText
(SDoc
proc_name SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
':' SDoc -> SDoc -> SDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$ CFG -> SDoc
pprEdgeWeights CFG
cfg)
checkLayout :: [NatCmmDecl statics instr] -> [NatCmmDecl statics instr]
-> Bool
checkLayout :: forall statics instr.
[NatCmmDecl statics instr] -> [NatCmmDecl statics instr] -> Bool
checkLayout [NatCmmDecl statics instr]
procsUnsequenced [NatCmmDecl statics instr]
procsSequenced =
Bool -> SDoc -> Bool -> Bool
forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr (LabelSet -> Bool
setNull LabelSet
diff) (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Block sequencing dropped blocks:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> LabelSet -> SDoc
forall a. Outputable a => a -> SDoc
ppr LabelSet
diff)
Bool
True
where
blocks1 :: LabelSet
blocks1 = (LabelSet -> LabelSet -> LabelSet)
-> LabelSet -> [LabelSet] -> LabelSet
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (LabelSet -> LabelSet -> LabelSet
setUnion) LabelSet
setEmpty ([LabelSet] -> LabelSet) -> [LabelSet] -> LabelSet
forall a b. (a -> b) -> a -> b
$
(NatCmmDecl statics instr -> LabelSet)
-> [NatCmmDecl statics instr] -> [LabelSet]
forall a b. (a -> b) -> [a] -> [b]
map NatCmmDecl statics instr -> LabelSet
forall {d} {h} {i}. GenCmmDecl d h (ListGraph i) -> LabelSet
getBlockIds [NatCmmDecl statics instr]
procsUnsequenced :: LabelSet
blocks2 :: LabelSet
blocks2 = (LabelSet -> LabelSet -> LabelSet)
-> LabelSet -> [LabelSet] -> LabelSet
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (LabelSet -> LabelSet -> LabelSet
setUnion) LabelSet
setEmpty ([LabelSet] -> LabelSet) -> [LabelSet] -> LabelSet
forall a b. (a -> b) -> a -> b
$
(NatCmmDecl statics instr -> LabelSet)
-> [NatCmmDecl statics instr] -> [LabelSet]
forall a b. (a -> b) -> [a] -> [b]
map NatCmmDecl statics instr -> LabelSet
forall {d} {h} {i}. GenCmmDecl d h (ListGraph i) -> LabelSet
getBlockIds [NatCmmDecl statics instr]
procsSequenced
diff :: LabelSet
diff = LabelSet -> LabelSet -> LabelSet
setDifference LabelSet
blocks1 LabelSet
blocks2
getBlockIds :: GenCmmDecl d h (ListGraph i) -> LabelSet
getBlockIds (CmmData Section
_ d
_) = LabelSet
setEmpty
getBlockIds (CmmProc h
_ CLabel
_ [GlobalRegUse]
_ (ListGraph [GenBasicBlock i]
blocks)) =
[Label] -> LabelSet
setFromList ([Label] -> LabelSet) -> [Label] -> LabelSet
forall a b. (a -> b) -> a -> b
$ (GenBasicBlock i -> Label) -> [GenBasicBlock i] -> [Label]
forall a b. (a -> b) -> [a] -> [b]
map GenBasicBlock i -> Label
forall i. GenBasicBlock i -> Label
blockId [GenBasicBlock i]
blocks
computeUnwinding :: Instruction instr
=> NCGConfig
-> NcgImpl statics instr jumpDest
-> NatCmmDecl statics instr
-> LabelMap [UnwindPoint]
computeUnwinding :: forall instr statics jumpDest.
Instruction instr =>
NCGConfig
-> NcgImpl statics instr jumpDest
-> NatCmmDecl statics instr
-> LabelMap [UnwindPoint]
computeUnwinding NCGConfig
config NcgImpl statics instr jumpDest
_ NatCmmDecl statics instr
_
| Bool -> Bool
not (NCGConfig -> Bool
ncgComputeUnwinding NCGConfig
config) = LabelMap [UnwindPoint]
forall v. LabelMap v
mapEmpty
computeUnwinding NCGConfig
_ NcgImpl statics instr jumpDest
_ (CmmData Section
_ statics
_) = LabelMap [UnwindPoint]
forall v. LabelMap v
mapEmpty
computeUnwinding NCGConfig
_ NcgImpl statics instr jumpDest
ncgImpl (CmmProc LabelMap RawCmmStatics
_ CLabel
_ [GlobalRegUse]
_ (ListGraph [GenBasicBlock instr]
blks)) =
[(Label, [UnwindPoint])] -> LabelMap [UnwindPoint]
forall v. [(Label, v)] -> LabelMap v
mapFromList [ (Label
blk_lbl, NcgImpl statics instr jumpDest -> [instr] -> [UnwindPoint]
forall statics instr jumpDest.
NcgImpl statics instr jumpDest -> [instr] -> [UnwindPoint]
extractUnwindPoints NcgImpl statics instr jumpDest
ncgImpl [instr]
instrs)
| BasicBlock Label
blk_lbl [instr]
instrs <- [GenBasicBlock instr]
blks ]
makeImportsDoc :: NCGConfig -> [CLabel] -> HDoc
makeImportsDoc :: NCGConfig -> [CLabel] -> HDoc
makeImportsDoc NCGConfig
config [CLabel]
imports
= [CLabel] -> HDoc
dyld_stubs [CLabel]
imports
HDoc -> HDoc -> HDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$
(if Platform -> Bool
platformHasSubsectionsViaSymbols Platform
platform
then Line HDoc -> HDoc
forall doc. IsDoc doc => Line doc -> doc
line (Line HDoc -> HDoc) -> Line HDoc -> HDoc
forall a b. (a -> b) -> a -> b
$ String -> Line HDoc
forall doc. IsLine doc => String -> doc
text String
".subsections_via_symbols"
else HDoc
forall doc. IsOutput doc => doc
Outputable.empty)
HDoc -> HDoc -> HDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$
(if Platform -> Bool
platformHasGnuNonexecStack Platform
platform
then Line HDoc -> HDoc
forall doc. IsDoc doc => Line doc -> doc
line (Line HDoc -> HDoc) -> Line HDoc -> HDoc
forall a b. (a -> b) -> a -> b
$ String -> HLine
forall doc. IsLine doc => String -> doc
text String
".section .note.GNU-stack,\"\"," Line HDoc -> Line HDoc -> Line HDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Platform -> String -> HLine
forall doc. IsLine doc => Platform -> String -> doc
sectionType Platform
platform String
"progbits"
else HDoc
forall doc. IsOutput doc => doc
Outputable.empty)
HDoc -> HDoc -> HDoc
forall doc. IsDoc doc => doc -> doc -> doc
$$
(if Platform -> Bool
platformHasIdentDirective Platform
platform
then let compilerIdent :: HLine
compilerIdent = String -> HLine
forall doc. IsLine doc => String -> doc
text String
"GHC" HLine -> HLine -> HLine
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> HLine
forall doc. IsLine doc => String -> doc
text String
cProjectVersion
in Line HDoc -> HDoc
forall doc. IsDoc doc => Line doc -> doc
line (Line HDoc -> HDoc) -> Line HDoc -> HDoc
forall a b. (a -> b) -> a -> b
$ String -> HLine
forall doc. IsLine doc => String -> doc
text String
".ident" Line HDoc -> Line HDoc -> Line HDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> HLine -> HLine
forall doc. IsLine doc => doc -> doc
doubleQuotes HLine
compilerIdent
else HDoc
forall doc. IsOutput doc => doc
Outputable.empty)
where
platform :: Platform
platform = NCGConfig -> Platform
ncgPlatform NCGConfig
config
dyld_stubs :: [CLabel] -> HDoc
dyld_stubs :: [CLabel] -> HDoc
dyld_stubs [CLabel]
imps
| NCGConfig -> Bool
needImportedSymbols NCGConfig
config
= [HDoc] -> HDoc
forall doc. IsDoc doc => [doc] -> doc
vcat ([HDoc] -> HDoc) -> [HDoc] -> HDoc
forall a b. (a -> b) -> a -> b
$
(NCGConfig -> HDoc
pprGotDeclaration NCGConfig
config HDoc -> [HDoc] -> [HDoc]
forall a. a -> [a] -> [a]
:) ([HDoc] -> [HDoc]) -> [HDoc] -> [HDoc]
forall a b. (a -> b) -> a -> b
$
(NonEmpty (CLabel, String) -> HDoc)
-> [NonEmpty (CLabel, String)] -> [HDoc]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (NCGConfig -> CLabel -> HDoc
pprImportedSymbol NCGConfig
config (CLabel -> HDoc)
-> (NonEmpty (CLabel, String) -> CLabel)
-> NonEmpty (CLabel, String)
-> HDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CLabel, String) -> CLabel
forall a b. (a, b) -> a
fst ((CLabel, String) -> CLabel)
-> (NonEmpty (CLabel, String) -> (CLabel, String))
-> NonEmpty (CLabel, String)
-> CLabel
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (CLabel, String) -> (CLabel, String)
forall a. NonEmpty a -> a
head) ([NonEmpty (CLabel, String)] -> [HDoc])
-> [NonEmpty (CLabel, String)] -> [HDoc]
forall a b. (a -> b) -> a -> b
$
((CLabel, String) -> String)
-> [(CLabel, String)] -> [NonEmpty (CLabel, String)]
forall b a. Ord b => (a -> b) -> [a] -> [NonEmpty a]
groupAllWith (CLabel, String) -> String
forall a b. (a, b) -> b
snd ([(CLabel, String)] -> [NonEmpty (CLabel, String)])
-> [(CLabel, String)] -> [NonEmpty (CLabel, String)]
forall a b. (a -> b) -> a -> b
$
(CLabel -> (CLabel, String)) -> [CLabel] -> [(CLabel, String)]
forall a b. (a -> b) -> [a] -> [b]
map CLabel -> (CLabel, String)
doPpr ([CLabel] -> [(CLabel, String)]) -> [CLabel] -> [(CLabel, String)]
forall a b. (a -> b) -> a -> b
$
[CLabel]
imps
| Bool
otherwise
= HDoc
forall doc. IsOutput doc => doc
Outputable.empty
doPpr :: CLabel -> (CLabel, String)
doPpr CLabel
lbl = (CLabel
lbl, SDocContext -> SDoc -> String
showSDocOneLine
(NCGConfig -> SDocContext
ncgAsmContext NCGConfig
config)
(Platform -> CLabel -> SDoc
forall doc. IsLine doc => Platform -> CLabel -> doc
pprAsmLabel Platform
platform CLabel
lbl))
generateJumpTables
:: NcgImpl statics instr jumpDest
-> [NatCmmDecl statics instr] -> [NatCmmDecl statics instr]
generateJumpTables :: forall statics instr jumpDest.
NcgImpl statics instr jumpDest
-> [NatCmmDecl statics instr] -> [NatCmmDecl statics instr]
generateJumpTables NcgImpl statics instr jumpDest
ncgImpl [NatCmmDecl statics instr]
xs = (NatCmmDecl statics instr -> [NatCmmDecl statics instr])
-> [NatCmmDecl statics instr] -> [NatCmmDecl statics instr]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap NatCmmDecl statics instr -> [NatCmmDecl statics instr]
f [NatCmmDecl statics instr]
xs
where f :: NatCmmDecl statics instr -> [NatCmmDecl statics instr]
f p :: NatCmmDecl statics instr
p@(CmmProc LabelMap RawCmmStatics
_ CLabel
_ [GlobalRegUse]
_ (ListGraph [GenBasicBlock instr]
xs)) = NatCmmDecl statics instr
p NatCmmDecl statics instr
-> [NatCmmDecl statics instr] -> [NatCmmDecl statics instr]
forall a. a -> [a] -> [a]
: (GenBasicBlock instr -> [NatCmmDecl statics instr])
-> [GenBasicBlock instr] -> [NatCmmDecl statics instr]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap GenBasicBlock instr -> [NatCmmDecl statics instr]
g [GenBasicBlock instr]
xs
f NatCmmDecl statics instr
p = [NatCmmDecl statics instr
p]
g :: GenBasicBlock instr -> [NatCmmDecl statics instr]
g (BasicBlock Label
_ [instr]
xs) = (instr -> Maybe (NatCmmDecl statics instr))
-> [instr] -> [NatCmmDecl statics instr]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (NcgImpl statics instr jumpDest
-> instr -> Maybe (NatCmmDecl statics instr)
forall statics instr jumpDest.
NcgImpl statics instr jumpDest
-> instr -> Maybe (NatCmmDecl statics instr)
generateJumpTableForInstr NcgImpl statics instr jumpDest
ncgImpl) [instr]
xs
shortcutBranches
:: forall statics instr jumpDest. (Outputable jumpDest)
=> NCGConfig
-> NcgImpl statics instr jumpDest
-> [NatCmmDecl statics instr]
-> Maybe CFG
-> ([NatCmmDecl statics instr],Maybe CFG)
shortcutBranches :: forall statics instr jumpDest.
Outputable jumpDest =>
NCGConfig
-> NcgImpl statics instr jumpDest
-> [NatCmmDecl statics instr]
-> Maybe CFG
-> ([NatCmmDecl statics instr], Maybe CFG)
shortcutBranches NCGConfig
config NcgImpl statics instr jumpDest
ncgImpl [NatCmmDecl statics instr]
tops Maybe CFG
weights
| NCGConfig -> Bool
ncgEnableShortcutting NCGConfig
config
, Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ OS -> Bool
osMachOTarget (OS -> Bool) -> OS -> Bool
forall a b. (a -> b) -> a -> b
$ Platform -> OS
platformOS (Platform -> OS) -> Platform -> OS
forall a b. (a -> b) -> a -> b
$ NCGConfig -> Platform
ncgPlatform NCGConfig
config
= ( (NatCmmDecl statics instr -> NatCmmDecl statics instr)
-> [NatCmmDecl statics instr] -> [NatCmmDecl statics instr]
forall a b. (a -> b) -> [a] -> [b]
map (NcgImpl statics instr jumpDest
-> LabelMap jumpDest
-> NatCmmDecl statics instr
-> NatCmmDecl statics instr
forall statics instr jumpDest h.
NcgImpl statics instr jumpDest
-> LabelMap jumpDest
-> GenCmmDecl statics h (ListGraph instr)
-> GenCmmDecl statics h (ListGraph instr)
apply_mapping NcgImpl statics instr jumpDest
ncgImpl LabelMap jumpDest
mapping) [NatCmmDecl statics instr]
tops'
, LabelMap (Maybe Label) -> CFG -> CFG
shortcutWeightMap LabelMap (Maybe Label)
mappingBid (CFG -> CFG) -> Maybe CFG -> Maybe CFG
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
<$!> Maybe CFG
weights )
| Bool
otherwise
= ([NatCmmDecl statics instr]
tops, Maybe CFG
weights)
where
([NatCmmDecl statics instr]
tops', [LabelMap jumpDest]
mappings) = (NatCmmDecl statics instr
-> (NatCmmDecl statics instr, LabelMap jumpDest))
-> [NatCmmDecl statics instr]
-> ([NatCmmDecl statics instr], [LabelMap jumpDest])
forall a b c. (a -> (b, c)) -> [a] -> ([b], [c])
mapAndUnzip (NcgImpl statics instr jumpDest
-> NatCmmDecl statics instr
-> (NatCmmDecl statics instr, LabelMap jumpDest)
forall instr t d statics jumpDest.
NcgImpl statics instr jumpDest
-> GenCmmDecl d (LabelMap t) (ListGraph instr)
-> (GenCmmDecl d (LabelMap t) (ListGraph instr), LabelMap jumpDest)
build_mapping NcgImpl statics instr jumpDest
ncgImpl) [NatCmmDecl statics instr]
tops
mapping :: LabelMap jumpDest
mapping = [LabelMap jumpDest] -> LabelMap jumpDest
forall a. [LabelMap a] -> LabelMap a
mapUnions [LabelMap jumpDest]
mappings :: LabelMap jumpDest
mappingBid :: LabelMap (Maybe Label)
mappingBid = (jumpDest -> Maybe Label)
-> LabelMap jumpDest -> LabelMap (Maybe Label)
forall a b. (a -> b) -> LabelMap a -> LabelMap b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (NcgImpl statics instr jumpDest -> jumpDest -> Maybe Label
forall statics instr jumpDest.
NcgImpl statics instr jumpDest -> jumpDest -> Maybe Label
getJumpDestBlockId NcgImpl statics instr jumpDest
ncgImpl) LabelMap jumpDest
mapping
build_mapping :: forall instr t d statics jumpDest.
NcgImpl statics instr jumpDest
-> GenCmmDecl d (LabelMap t) (ListGraph instr)
-> (GenCmmDecl d (LabelMap t) (ListGraph instr)
,LabelMap jumpDest)
build_mapping :: forall instr t d statics jumpDest.
NcgImpl statics instr jumpDest
-> GenCmmDecl d (LabelMap t) (ListGraph instr)
-> (GenCmmDecl d (LabelMap t) (ListGraph instr), LabelMap jumpDest)
build_mapping NcgImpl statics instr jumpDest
_ top :: GenCmmDecl d (LabelMap t) (ListGraph instr)
top@(CmmData Section
_ d
_) = (GenCmmDecl d (LabelMap t) (ListGraph instr)
top, LabelMap jumpDest
forall v. LabelMap v
mapEmpty)
build_mapping NcgImpl statics instr jumpDest
_ (CmmProc LabelMap t
info CLabel
lbl [GlobalRegUse]
live (ListGraph []))
= (LabelMap t
-> CLabel
-> [GlobalRegUse]
-> ListGraph instr
-> GenCmmDecl d (LabelMap t) (ListGraph instr)
forall d h g.
h -> CLabel -> [GlobalRegUse] -> g -> GenCmmDecl d h g
CmmProc LabelMap t
info CLabel
lbl [GlobalRegUse]
live ([GenBasicBlock instr] -> ListGraph instr
forall i. [GenBasicBlock i] -> ListGraph i
ListGraph []), LabelMap jumpDest
forall v. LabelMap v
mapEmpty)
build_mapping NcgImpl statics instr jumpDest
ncgImpl (CmmProc LabelMap t
info CLabel
lbl [GlobalRegUse]
live (ListGraph (GenBasicBlock instr
head:[GenBasicBlock instr]
blocks)))
= (LabelMap t
-> CLabel
-> [GlobalRegUse]
-> ListGraph instr
-> GenCmmDecl d (LabelMap t) (ListGraph instr)
forall d h g.
h -> CLabel -> [GlobalRegUse] -> g -> GenCmmDecl d h g
CmmProc LabelMap t
info CLabel
lbl [GlobalRegUse]
live ([GenBasicBlock instr] -> ListGraph instr
forall i. [GenBasicBlock i] -> ListGraph i
ListGraph (GenBasicBlock instr
headGenBasicBlock instr
-> [GenBasicBlock instr] -> [GenBasicBlock instr]
forall a. a -> [a] -> [a]
:[GenBasicBlock instr]
others)), LabelMap jumpDest
mapping)
where
shortcut_blocks :: [(BlockId, jumpDest)]
(LabelSet
_, [(Label, jumpDest)]
shortcut_blocks, [GenBasicBlock instr]
others) =
((LabelSet, [(Label, jumpDest)], [GenBasicBlock instr])
-> GenBasicBlock instr
-> (LabelSet, [(Label, jumpDest)], [GenBasicBlock instr]))
-> (LabelSet, [(Label, jumpDest)], [GenBasicBlock instr])
-> [GenBasicBlock instr]
-> (LabelSet, [(Label, jumpDest)], [GenBasicBlock instr])
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (LabelSet, [(Label, jumpDest)], [GenBasicBlock instr])
-> GenBasicBlock instr
-> (LabelSet, [(Label, jumpDest)], [GenBasicBlock instr])
split (LabelSet
setEmpty :: LabelSet, [], []) [GenBasicBlock instr]
blocks
split :: (LabelSet, [(Label, jumpDest)], [GenBasicBlock instr])
-> GenBasicBlock instr
-> (LabelSet, [(Label, jumpDest)], [GenBasicBlock instr])
split (LabelSet
s, [(Label, jumpDest)]
shortcut_blocks, [GenBasicBlock instr]
others) b :: GenBasicBlock instr
b@(BasicBlock Label
id [instr
insn])
| Just jumpDest
jd <- NcgImpl statics instr jumpDest -> instr -> Maybe jumpDest
forall statics instr jumpDest.
NcgImpl statics instr jumpDest -> instr -> Maybe jumpDest
canShortcut NcgImpl statics instr jumpDest
ncgImpl instr
insn
, Just Label
dest <- NcgImpl statics instr jumpDest -> jumpDest -> Maybe Label
forall statics instr jumpDest.
NcgImpl statics instr jumpDest -> jumpDest -> Maybe Label
getJumpDestBlockId NcgImpl statics instr jumpDest
ncgImpl jumpDest
jd
, Bool -> Bool
not (Label -> Bool
has_info Label
id)
, (Label -> LabelSet -> Bool
setMember Label
dest LabelSet
s) Bool -> Bool -> Bool
|| Label
dest Label -> Label -> Bool
forall a. Eq a => a -> a -> Bool
== Label
id
= (LabelSet
s, [(Label, jumpDest)]
shortcut_blocks, GenBasicBlock instr
b GenBasicBlock instr
-> [GenBasicBlock instr] -> [GenBasicBlock instr]
forall a. a -> [a] -> [a]
: [GenBasicBlock instr]
others)
split (LabelSet
s, [(Label, jumpDest)]
shortcut_blocks, [GenBasicBlock instr]
others) (BasicBlock Label
id [instr
insn])
| Just jumpDest
dest <- NcgImpl statics instr jumpDest -> instr -> Maybe jumpDest
forall statics instr jumpDest.
NcgImpl statics instr jumpDest -> instr -> Maybe jumpDest
canShortcut NcgImpl statics instr jumpDest
ncgImpl instr
insn
, Bool -> Bool
not (Label -> Bool
has_info Label
id)
= (Label -> LabelSet -> LabelSet
setInsert Label
id LabelSet
s, (Label
id,jumpDest
dest) (Label, jumpDest) -> [(Label, jumpDest)] -> [(Label, jumpDest)]
forall a. a -> [a] -> [a]
: [(Label, jumpDest)]
shortcut_blocks, [GenBasicBlock instr]
others)
split (LabelSet
s, [(Label, jumpDest)]
shortcut_blocks, [GenBasicBlock instr]
others) GenBasicBlock instr
other = (LabelSet
s, [(Label, jumpDest)]
shortcut_blocks, GenBasicBlock instr
other GenBasicBlock instr
-> [GenBasicBlock instr] -> [GenBasicBlock instr]
forall a. a -> [a] -> [a]
: [GenBasicBlock instr]
others)
has_info :: Label -> Bool
has_info Label
l = Label -> LabelMap t -> Bool
forall a. Label -> LabelMap a -> Bool
mapMember Label
l LabelMap t
info
mapping :: LabelMap jumpDest
mapping = [(Label, jumpDest)] -> LabelMap jumpDest
forall v. [(Label, v)] -> LabelMap v
mapFromList [(Label, jumpDest)]
shortcut_blocks
apply_mapping :: NcgImpl statics instr jumpDest
-> LabelMap jumpDest
-> GenCmmDecl statics h (ListGraph instr)
-> GenCmmDecl statics h (ListGraph instr)
apply_mapping :: forall statics instr jumpDest h.
NcgImpl statics instr jumpDest
-> LabelMap jumpDest
-> GenCmmDecl statics h (ListGraph instr)
-> GenCmmDecl statics h (ListGraph instr)
apply_mapping NcgImpl statics instr jumpDest
ncgImpl LabelMap jumpDest
ufm (CmmData Section
sec statics
statics)
= Section -> statics -> GenCmmDecl statics h (ListGraph instr)
forall d h g. Section -> d -> GenCmmDecl d h g
CmmData Section
sec (NcgImpl statics instr jumpDest
-> (Label -> Maybe jumpDest) -> statics -> statics
forall statics instr jumpDest.
NcgImpl statics instr jumpDest
-> (Label -> Maybe jumpDest) -> statics -> statics
shortcutStatics NcgImpl statics instr jumpDest
ncgImpl (\Label
bid -> Label -> LabelMap jumpDest -> Maybe jumpDest
forall a. Label -> LabelMap a -> Maybe a
mapLookup Label
bid LabelMap jumpDest
ufm) statics
statics)
apply_mapping NcgImpl statics instr jumpDest
ncgImpl LabelMap jumpDest
ufm (CmmProc h
info CLabel
lbl [GlobalRegUse]
live (ListGraph [GenBasicBlock instr]
blocks))
= h
-> CLabel
-> [GlobalRegUse]
-> ListGraph instr
-> GenCmmDecl statics h (ListGraph instr)
forall d h g.
h -> CLabel -> [GlobalRegUse] -> g -> GenCmmDecl d h g
CmmProc h
info CLabel
lbl [GlobalRegUse]
live ([GenBasicBlock instr] -> ListGraph instr
forall i. [GenBasicBlock i] -> ListGraph i
ListGraph ([GenBasicBlock instr] -> ListGraph instr)
-> [GenBasicBlock instr] -> ListGraph instr
forall a b. (a -> b) -> a -> b
$ (GenBasicBlock instr -> GenBasicBlock instr)
-> [GenBasicBlock instr] -> [GenBasicBlock instr]
forall a b. (a -> b) -> [a] -> [b]
map GenBasicBlock instr -> GenBasicBlock instr
short_bb [GenBasicBlock instr]
blocks)
where
short_bb :: GenBasicBlock instr -> GenBasicBlock instr
short_bb (BasicBlock Label
id [instr]
insns) = Label -> [instr] -> GenBasicBlock instr
forall i. Label -> [i] -> GenBasicBlock i
BasicBlock Label
id ([instr] -> GenBasicBlock instr) -> [instr] -> GenBasicBlock instr
forall a b. (a -> b) -> a -> b
$! (instr -> instr) -> [instr] -> [instr]
forall a b. (a -> b) -> [a] -> [b]
map instr -> instr
short_insn [instr]
insns
short_insn :: instr -> instr
short_insn instr
i = NcgImpl statics instr jumpDest
-> (Label -> Maybe jumpDest) -> instr -> instr
forall statics instr jumpDest.
NcgImpl statics instr jumpDest
-> (Label -> Maybe jumpDest) -> instr -> instr
shortcutJump NcgImpl statics instr jumpDest
ncgImpl (\Label
bid -> Label -> LabelMap jumpDest -> Maybe jumpDest
forall a. Label -> LabelMap a -> Maybe a
mapLookup Label
bid LabelMap jumpDest
ufm) instr
i
genMachCode
:: NCGConfig
-> (RawCmmDecl -> NatM [NatCmmDecl statics instr])
-> DwarfFiles
-> LabelMap DebugBlock
-> RawCmmDecl
-> CFG
-> UniqDSM
( [NatCmmDecl statics instr]
, [CLabel]
, DwarfFiles
, CFG
)
genMachCode :: forall statics instr.
NCGConfig
-> (RawCmmDecl -> NatM [NatCmmDecl statics instr])
-> DwarfFiles
-> LabelMap DebugBlock
-> RawCmmDecl
-> CFG
-> UniqDSM ([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG)
genMachCode NCGConfig
config RawCmmDecl -> NatM [NatCmmDecl statics instr]
cmmTopCodeGen DwarfFiles
fileIds LabelMap DebugBlock
dbgMap RawCmmDecl
cmm_top CFG
cmm_cfg
= (DUniqSupply
-> DUniqResult
([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG))
-> UniqDSM ([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG)
forall a. (DUniqSupply -> DUniqResult a) -> UniqDSM a
UDSM ((DUniqSupply
-> DUniqResult
([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG))
-> UniqDSM ([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG))
-> (DUniqSupply
-> DUniqResult
([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG))
-> UniqDSM ([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG)
forall a b. (a -> b) -> a -> b
$ \DUniqSupply
initial_us -> do
{ let initial_st :: NatM_State
initial_st = DUniqSupply
-> Int
-> NCGConfig
-> DwarfFiles
-> LabelMap DebugBlock
-> CFG
-> NatM_State
mkNatM_State DUniqSupply
initial_us Int
0 NCGConfig
config
DwarfFiles
fileIds LabelMap DebugBlock
dbgMap CFG
cmm_cfg
([NatCmmDecl statics instr]
new_tops, NatM_State
final_st) = NatM_State
-> NatM [NatCmmDecl statics instr]
-> ([NatCmmDecl statics instr], NatM_State)
forall a. NatM_State -> NatM a -> (a, NatM_State)
initNat NatM_State
initial_st (RawCmmDecl -> NatM [NatCmmDecl statics instr]
cmmTopCodeGen RawCmmDecl
cmm_top)
final_delta :: Int
final_delta = NatM_State -> Int
natm_delta NatM_State
final_st
final_imports :: [CLabel]
final_imports = NatM_State -> [CLabel]
natm_imports NatM_State
final_st
final_cfg :: CFG
final_cfg = NatM_State -> CFG
natm_cfg NatM_State
final_st
; if Int
final_delta Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
then ([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG)
-> DUniqSupply
-> DUniqResult
([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG)
forall a. a -> DUniqSupply -> (# a, DUniqSupply #)
DUniqResult
([NatCmmDecl statics instr]
new_tops, [CLabel]
final_imports
, NatM_State -> DwarfFiles
natm_fileid NatM_State
final_st, CFG
final_cfg) (NatM_State -> DUniqSupply
natm_us NatM_State
final_st)
else ([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG)
-> DUniqSupply
-> DUniqResult
([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG)
forall a. a -> DUniqSupply -> (# a, DUniqSupply #)
DUniqResult (String
-> SDoc -> ([NatCmmDecl statics instr], [CLabel], DwarfFiles, CFG)
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"genMachCode: nonzero final delta" (Int -> SDoc
forall doc. IsLine doc => Int -> doc
int Int
final_delta)) DUniqSupply
forall a. HasCallStack => a
undefined
}