summaryrefslogtreecommitdiff
path: root/compiler/GHC/CmmToAsm.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/CmmToAsm.hs')
-rw-r--r--compiler/GHC/CmmToAsm.hs174
1 files changed, 57 insertions, 117 deletions
diff --git a/compiler/GHC/CmmToAsm.hs b/compiler/GHC/CmmToAsm.hs
index 82122911b6..f28403e9b8 100644
--- a/compiler/GHC/CmmToAsm.hs
+++ b/compiler/GHC/CmmToAsm.hs
@@ -75,7 +75,6 @@ module GHC.CmmToAsm
-- cmmNativeGen emits
, cmmNativeGen
, NcgImpl(..)
- , initNCGConfig
)
where
@@ -149,15 +148,14 @@ import Control.Monad
import System.IO
--------------------
-nativeCodeGen :: forall a . Logger -> DynFlags -> Module -> ModLocation -> Handle -> UniqSupply
+nativeCodeGen :: forall a . Logger -> NCGConfig -> ModLocation -> Handle -> UniqSupply
-> Stream IO RawCmmGroup a
-> IO a
-nativeCodeGen logger dflags this_mod modLoc h us cmms
- = let config = initNCGConfig dflags this_mod
- platform = ncgPlatform config
+nativeCodeGen logger config modLoc h us cmms
+ = let platform = ncgPlatform config
nCG' :: ( OutputableP Platform statics, Outputable jumpDest, Instruction instr)
=> NcgImpl statics instr jumpDest -> IO a
- nCG' ncgImpl = nativeCodeGen' logger dflags config modLoc ncgImpl h us cmms
+ nCG' ncgImpl = nativeCodeGen' logger config modLoc ncgImpl h us cmms
in case platformArch platform of
ArchX86 -> nCG' (X86.ncgX86 config)
ArchX86_64 -> nCG' (X86.ncgX86_64 config)
@@ -221,7 +219,6 @@ See also Note [What is this unwinding business?] in "GHC.Cmm.DebugBlock".
nativeCodeGen' :: (OutputableP Platform statics, Outputable jumpDest, Instruction instr)
=> Logger
- -> DynFlags
-> NCGConfig
-> ModLocation
-> NcgImpl statics instr jumpDest
@@ -229,35 +226,34 @@ nativeCodeGen' :: (OutputableP Platform statics, Outputable jumpDest, Instructio
-> UniqSupply
-> Stream IO RawCmmGroup a
-> IO a
-nativeCodeGen' logger dflags config modLoc ncgImpl h us cmms
+nativeCodeGen' logger config modLoc ncgImpl h us cmms
= do
-- BufHandle is a performance hack. We could hide it inside
-- Pretty if it weren't for the fact that we do lots of little
-- printDocs here (in order to do codegen in constant space).
bufh <- newBufHandle h
let ngs0 = NGS [] [] [] [] [] [] emptyUFM mapEmpty
- (ngs, us', a) <- cmmNativeGenStream logger dflags config modLoc ncgImpl bufh us
+ (ngs, us', a) <- cmmNativeGenStream logger config modLoc ncgImpl bufh us
cmms ngs0
- _ <- finishNativeGen logger dflags config modLoc bufh us' ngs
+ _ <- finishNativeGen logger config modLoc bufh us' ngs
return a
finishNativeGen :: Instruction instr
=> Logger
- -> DynFlags
-> NCGConfig
-> ModLocation
-> BufHandle
-> UniqSupply
-> NativeGenAcc statics instr
-> IO UniqSupply
-finishNativeGen logger dflags config modLoc bufh@(BufHandle _ _ h) us ngs
- = withTimingSilent logger dflags (text "NCG") (`seq` ()) $ do
+finishNativeGen logger config modLoc bufh@(BufHandle _ _ h) us ngs
+ = withTimingSilent logger (text "NCG") (`seq` ()) $ do
-- Write debug data and finish
us' <- if not (ncgDwarfEnabled config)
then return us
else do
(dwarf, us') <- dwarfGen config modLoc us (ngs_debug ngs)
- emitNativeCode logger dflags config bufh dwarf
+ emitNativeCode logger config bufh dwarf
return us'
bFlush bufh
@@ -274,7 +270,7 @@ finishNativeGen logger dflags config modLoc bufh@(BufHandle _ _ h) us ngs
dump_stats (Color.pprStats stats graphGlobal)
let platform = ncgPlatform config
- dumpIfSet_dyn logger dflags
+ putDumpFileMaybe logger
Opt_D_dump_asm_conflicts "Register conflict graph"
FormatText
$ Color.dotGraph
@@ -296,13 +292,12 @@ finishNativeGen logger dflags config modLoc bufh@(BufHandle _ _ h) us ngs
$ makeImportsDoc config (concat (ngs_imports ngs))
return us'
where
- dump_stats = putDumpMsg logger dflags (mkDumpStyle alwaysQualify)
+ dump_stats = logDumpFile logger (mkDumpStyle alwaysQualify)
Opt_D_dump_asm_stats "NCG stats"
FormatText
cmmNativeGenStream :: forall statics jumpDest instr a . (OutputableP Platform statics, Outputable jumpDest, Instruction instr)
=> Logger
- -> DynFlags
-> NCGConfig
-> ModLocation
-> NcgImpl statics instr jumpDest
@@ -312,7 +307,7 @@ cmmNativeGenStream :: forall statics jumpDest instr a . (OutputableP Platform st
-> NativeGenAcc statics instr
-> IO (NativeGenAcc statics instr, UniqSupply, a)
-cmmNativeGenStream logger dflags config modLoc ncgImpl h us cmm_stream ngs
+cmmNativeGenStream logger config modLoc ncgImpl h us cmm_stream ngs
= loop us (Stream.runStream cmm_stream) ngs
where
ncglabel = text "NCG"
@@ -334,7 +329,6 @@ cmmNativeGenStream logger dflags config modLoc ncgImpl h us cmm_stream ngs
Stream.Yield cmms cmm_stream' -> do
(us', ngs'') <-
withTimingSilent logger
- dflags
ncglabel (\(a, b) -> a `seq` b `seq` ()) $ do
-- Generate debug information
let !ndbgs | ncgDwarfEnabled config = cmmDebugGen modLoc cmms
@@ -342,15 +336,15 @@ cmmNativeGenStream logger dflags config modLoc ncgImpl h us cmm_stream ngs
dbgMap = debugToMap ndbgs
-- Generate native code
- (ngs',us') <- cmmNativeGens logger dflags config modLoc ncgImpl h
+ (ngs',us') <- cmmNativeGens logger config modLoc ncgImpl h
dbgMap us cmms ngs 0
-- Link native code information into debug blocks
-- See Note [What is this unwinding business?] in "GHC.Cmm.DebugBlock".
let !ldbgs = cmmDebugLink (ngs_labels ngs') (ngs_unwinds ngs') ndbgs
- platform = targetPlatform dflags
+ platform = ncgPlatform config
unless (null ldbgs) $
- dumpIfSet_dyn logger dflags Opt_D_dump_debug "Debug Infos" FormatText
+ putDumpFileMaybe logger Opt_D_dump_debug "Debug Infos" FormatText
(vcat $ map (pdoc platform) ldbgs)
-- Accumulate debug information for emission in finishNativeGen.
@@ -365,7 +359,6 @@ cmmNativeGenStream logger dflags config modLoc ncgImpl h us cmm_stream ngs
cmmNativeGens :: forall statics instr jumpDest.
(OutputableP Platform statics, Outputable jumpDest, Instruction instr)
=> Logger
- -> DynFlags
-> NCGConfig
-> ModLocation
-> NcgImpl statics instr jumpDest
@@ -377,7 +370,7 @@ cmmNativeGens :: forall statics instr jumpDest.
-> Int
-> IO (NativeGenAcc statics instr, UniqSupply)
-cmmNativeGens logger dflags config modLoc ncgImpl h dbgMap = go
+cmmNativeGens logger config modLoc ncgImpl h dbgMap = go
where
go :: UniqSupply -> [RawCmmDecl]
-> NativeGenAcc statics instr -> Int
@@ -390,7 +383,7 @@ cmmNativeGens logger dflags config modLoc ncgImpl h dbgMap = go
let fileIds = ngs_dwarfFiles ngs
(us', fileIds', native, imports, colorStats, linearStats, unwinds)
<- {-# SCC "cmmNativeGen" #-}
- cmmNativeGen logger dflags modLoc ncgImpl us fileIds dbgMap
+ cmmNativeGen logger modLoc ncgImpl us fileIds dbgMap
cmm count
-- Generate .file directives for every new file that has been
@@ -402,17 +395,17 @@ cmmNativeGens logger dflags config modLoc ncgImpl h dbgMap = go
pprDecl (f,n) = text "\t.file " <> ppr n <+>
pprFilePathString (unpackFS f)
- emitNativeCode logger dflags config h $ vcat $
+ emitNativeCode logger config h $ vcat $
map pprDecl newFileIds ++
map (pprNatCmmDecl ncgImpl) native
-- force evaluation all this stuff to avoid space leaks
- let platform = targetPlatform dflags
- {-# SCC "seqString" #-} evaluate $ seqList (showSDoc dflags $ vcat $ map (pdoc platform) imports) ()
+ let platform = ncgPlatform config
+ {-# SCC "seqString" #-} evaluate $ seqList (showSDocUnsafe $ vcat $ map (pdoc platform) imports) ()
let !labels' = if ncgDwarfEnabled config
then cmmDebugLabels isMetaInstr native else []
- !natives' = if dopt Opt_D_dump_asm_stats dflags
+ !natives' = if logHasDumpFlag logger Opt_D_dump_asm_stats
then native : ngs_natives ngs else []
mCon = maybe id (:)
@@ -427,14 +420,14 @@ cmmNativeGens logger dflags config modLoc ncgImpl h dbgMap = go
go us' cmms ngs' (count + 1)
-emitNativeCode :: Logger -> DynFlags -> NCGConfig -> BufHandle -> SDoc -> IO ()
-emitNativeCode logger dflags config h sdoc = do
+emitNativeCode :: Logger -> NCGConfig -> BufHandle -> SDoc -> IO ()
+emitNativeCode logger config h sdoc = do
let ctx = ncgAsmContext config
{-# SCC "pprNativeCode" #-} bufLeftRenderSDoc ctx h sdoc
-- dump native code
- dumpIfSet_dyn logger dflags
+ putDumpFileMaybe logger
Opt_D_dump_asm "Asm code" FormatASM
sdoc
@@ -444,7 +437,6 @@ emitNativeCode logger dflags config h sdoc = do
cmmNativeGen
:: forall statics instr jumpDest. (Instruction instr, OutputableP Platform statics, Outputable jumpDest)
=> Logger
- -> DynFlags
-> ModLocation
-> NcgImpl statics instr jumpDest
-> UniqSupply
@@ -461,7 +453,7 @@ cmmNativeGen
, LabelMap [UnwindPoint] -- unwinding information for blocks
)
-cmmNativeGen logger dflags modLoc ncgImpl us fileIds dbgMap cmm count
+cmmNativeGen logger modLoc ncgImpl us fileIds dbgMap cmm count
= do
let config = ncgConfig ncgImpl
let platform = ncgPlatform config
@@ -481,7 +473,7 @@ cmmNativeGen logger dflags modLoc ncgImpl us fileIds dbgMap cmm count
{-# SCC "cmmToCmm" #-}
cmmToCmm config fixed_cmm
- dumpIfSet_dyn logger dflags
+ putDumpFileMaybe logger
Opt_D_dump_opt_cmm "Optimised Cmm" FormatCMM
(pprCmmGroup platform [opt_cmm])
@@ -495,11 +487,11 @@ cmmNativeGen logger dflags modLoc ncgImpl us fileIds dbgMap cmm count
(cmmTopCodeGen ncgImpl)
fileIds dbgMap opt_cmm cmmCfg
- dumpIfSet_dyn logger dflags
+ putDumpFileMaybe logger
Opt_D_dump_asm_native "Native code" FormatASM
(vcat $ map (pprNatCmmDecl ncgImpl) native)
- maybeDumpCfg logger dflags (Just nativeCfgWeights) "CFG Weights - Native" proc_name
+ maybeDumpCfg logger (Just nativeCfgWeights) "CFG Weights - Native" proc_name
-- tag instructions with register liveness information
-- also drops dead code. We don't keep the cfg in sync on
@@ -512,15 +504,14 @@ cmmNativeGen logger dflags modLoc ncgImpl us fileIds dbgMap cmm count
initUs usGen
$ mapM (cmmTopLiveness livenessCfg platform) native
- dumpIfSet_dyn logger dflags
+ putDumpFileMaybe logger
Opt_D_dump_asm_liveness "Liveness annotations added"
FormatCMM
(vcat $ map (pprLiveCmmDecl platform) withLiveness)
-- allocate registers
(alloced, usAlloc, ppr_raStatsColor, ppr_raStatsLinear, raStats, stack_updt_blks) <-
- if ( gopt Opt_RegsGraph dflags
- || gopt Opt_RegsIterative dflags )
+ if ( ncgRegsGraph config || ncgRegsIterative config )
then do
-- the regs usable for allocation
let (alloc_regs :: UniqFM RegClass (UniqSet RealReg))
@@ -552,12 +543,12 @@ cmmNativeGen logger dflags modLoc ncgImpl us fileIds dbgMap cmm count
-- dump out what happened during register allocation
- dumpIfSet_dyn logger dflags
+ putDumpFileMaybe logger
Opt_D_dump_asm_regalloc "Registers allocated"
FormatCMM
(vcat $ map (pprNatCmmDecl ncgImpl) alloced)
- dumpIfSet_dyn logger dflags
+ putDumpFileMaybe logger
Opt_D_dump_asm_regalloc_stages "Build/spill stages"
FormatText
(vcat $ map (\(stage, stats)
@@ -567,7 +558,7 @@ cmmNativeGen logger dflags modLoc ncgImpl us fileIds dbgMap cmm count
$ zip [0..] regAllocStats)
let mPprStats =
- if dopt Opt_D_dump_asm_stats dflags
+ if logHasDumpFlag logger Opt_D_dump_asm_stats
then Just regAllocStats else Nothing
-- force evaluation of the Maybe to avoid space leak
@@ -596,13 +587,13 @@ cmmNativeGen logger dflags modLoc ncgImpl us fileIds dbgMap cmm count
$ liftM unzip3
$ mapM reg_alloc withLiveness
- dumpIfSet_dyn logger dflags
+ putDumpFileMaybe logger
Opt_D_dump_asm_regalloc "Registers allocated"
FormatCMM
(vcat $ map (pprNatCmmDecl ncgImpl) alloced)
let mPprStats =
- if dopt Opt_D_dump_asm_stats dflags
+ if logHasDumpFlag logger Opt_D_dump_asm_stats
then Just (catMaybes regAllocStats) else Nothing
-- force evaluation of the Maybe to avoid space leak
@@ -631,7 +622,7 @@ cmmNativeGen logger dflags modLoc ncgImpl us fileIds dbgMap cmm count
{-# SCC "generateJumpTables" #-}
generateJumpTables ncgImpl alloced
- when (not $ null nativeCfgWeights) $ dumpIfSet_dyn logger dflags
+ when (not $ null nativeCfgWeights) $ putDumpFileMaybe logger
Opt_D_dump_cfg_weights "CFG Update information"
FormatText
( text "stack:" <+> ppr stack_updt_blks $$
@@ -640,20 +631,20 @@ cmmNativeGen logger dflags modLoc ncgImpl us fileIds dbgMap cmm count
---- shortcut branches
let (shorted, postShortCFG) =
{-# SCC "shortcutBranches" #-}
- shortcutBranches dflags ncgImpl tabled postRegCFG
+ shortcutBranches config ncgImpl tabled postRegCFG
let optimizedCFG :: Maybe CFG
optimizedCFG =
- optimizeCFG (gopt Opt_CmmStaticPred dflags) weights cmm <$!> postShortCFG
+ optimizeCFG (ncgCmmStaticPred config) weights cmm <$!> postShortCFG
- maybeDumpCfg logger dflags optimizedCFG "CFG Weights - Final" proc_name
+ maybeDumpCfg logger optimizedCFG "CFG Weights - Final" proc_name
--TODO: Partially check validity of the cfg.
let getBlks (CmmProc _info _lbl _live (ListGraph blocks)) = blocks
getBlks _ = []
when ( backendMaintainsCfg platform &&
- (gopt Opt_DoAsmLinting dflags || debugIsOn )) $ do
+ (ncgAsmLinting config || debugIsOn )) $ do
let blocks = concatMap getBlks shorted
let labels = setFromList $ fmap blockId blocks :: LabelSet
let cfg = fromJust optimizedCFG
@@ -687,7 +678,7 @@ cmmNativeGen logger dflags modLoc ncgImpl us fileIds dbgMap cmm count
ncgExpandTop ncgImpl branchOpt
--ncgExpandTop ncgImpl sequenced
- dumpIfSet_dyn logger dflags
+ putDumpFileMaybe logger
Opt_D_dump_asm_expanded "Synthetic instructions expanded"
FormatCMM
(vcat $ map (pprNatCmmDecl ncgImpl) expanded)
@@ -699,7 +690,7 @@ cmmNativeGen logger dflags modLoc ncgImpl us fileIds dbgMap cmm count
foldl' addUnwind mapEmpty expanded
where
addUnwind acc proc =
- acc `mapUnion` computeUnwinding dflags ncgImpl proc
+ acc `mapUnion` computeUnwinding config ncgImpl proc
return ( usAlloc
, fileIds'
@@ -709,13 +700,13 @@ cmmNativeGen logger dflags modLoc ncgImpl us fileIds dbgMap cmm count
, ppr_raStatsLinear
, unwinds )
-maybeDumpCfg :: Logger -> DynFlags -> Maybe CFG -> String -> SDoc -> IO ()
-maybeDumpCfg _logger _dflags Nothing _ _ = return ()
-maybeDumpCfg logger dflags (Just cfg) msg proc_name
+maybeDumpCfg :: Logger -> Maybe CFG -> String -> SDoc -> IO ()
+maybeDumpCfg _logger Nothing _ _ = return ()
+maybeDumpCfg logger (Just cfg) msg proc_name
| null cfg = return ()
| otherwise
- = dumpIfSet_dyn logger
- dflags Opt_D_dump_cfg_weights msg
+ = putDumpFileMaybe logger
+ Opt_D_dump_cfg_weights msg
FormatText
(proc_name <> char ':' $$ pprEdgeWeights cfg)
@@ -738,15 +729,16 @@ checkLayout procsUnsequenced procsSequenced =
-- | Compute unwinding tables for the blocks of a procedure
computeUnwinding :: Instruction instr
- => DynFlags -> NcgImpl statics instr jumpDest
+ => NCGConfig
+ -> NcgImpl statics instr jumpDest
-> NatCmmDecl statics instr
-- ^ the native code generated for the procedure
-> LabelMap [UnwindPoint]
-- ^ unwinding tables for all points of all blocks of the
-- procedure
-computeUnwinding dflags _ _
- | debugLevel dflags == 0 = mapEmpty
-computeUnwinding _ _ (CmmData _ _) = mapEmpty
+computeUnwinding config _ _
+ | not (ncgComputeUnwinding config) = mapEmpty
+computeUnwinding _ _ (CmmData _ _) = mapEmpty
computeUnwinding _ ncgImpl (CmmProc _ _ _ (ListGraph blks)) =
-- In general we would need to push unwinding information down the
-- block-level call-graph to ensure that we fully account for all
@@ -832,14 +824,15 @@ generateJumpTables ncgImpl xs = concatMap f xs
-- Shortcut branches
shortcutBranches
- :: forall statics instr jumpDest. (Outputable jumpDest) => DynFlags
+ :: forall statics instr jumpDest. (Outputable jumpDest)
+ => NCGConfig
-> NcgImpl statics instr jumpDest
-> [NatCmmDecl statics instr]
-> Maybe CFG
-> ([NatCmmDecl statics instr],Maybe CFG)
-shortcutBranches dflags ncgImpl tops weights
- | gopt Opt_AsmShortcutting dflags
+shortcutBranches config ncgImpl tops weights
+ | ncgEnableShortcutting config
= ( map (apply_mapping ncgImpl mapping) tops'
, shortcutWeightMap mappingBid <$!> weights )
| otherwise
@@ -1144,56 +1137,3 @@ cmmExprNative referenceKind expr = do
other
-> return other
-
--- | Initialize the native code generator configuration from the DynFlags
-initNCGConfig :: DynFlags -> Module -> NCGConfig
-initNCGConfig dflags this_mod = NCGConfig
- { ncgPlatform = targetPlatform dflags
- , ncgThisModule = this_mod
- , ncgAsmContext = initSDocContext dflags (PprCode AsmStyle)
- , ncgProcAlignment = cmmProcAlignment dflags
- , ncgExternalDynamicRefs = gopt Opt_ExternalDynamicRefs dflags
- , ncgPIC = positionIndependent dflags
- , ncgInlineThresholdMemcpy = fromIntegral $ maxInlineMemcpyInsns dflags
- , ncgInlineThresholdMemset = fromIntegral $ maxInlineMemsetInsns dflags
- , ncgSplitSections = gopt Opt_SplitSections dflags
- , ncgRegsIterative = gopt Opt_RegsIterative dflags
- , ncgAsmLinting = gopt Opt_DoAsmLinting dflags
- , ncgCfgWeights = cfgWeights dflags
- , ncgCfgBlockLayout = gopt Opt_CfgBlocklayout dflags
- , ncgCfgWeightlessLayout = gopt Opt_WeightlessBlocklayout dflags
-
- -- With -O1 and greater, the cmmSink pass does constant-folding, so
- -- we don't need to do it again in the native code generator.
- , ncgDoConstantFolding = optLevel dflags < 1
-
- , ncgDumpRegAllocStages = dopt Opt_D_dump_asm_regalloc_stages dflags
- , ncgDumpAsmStats = dopt Opt_D_dump_asm_stats dflags
- , ncgDumpAsmConflicts = dopt Opt_D_dump_asm_conflicts dflags
- , ncgBmiVersion = case platformArch (targetPlatform dflags) of
- ArchX86_64 -> bmiVersion dflags
- ArchX86 -> bmiVersion dflags
- _ -> Nothing
-
- -- We assume SSE1 and SSE2 operations are available on both
- -- x86 and x86_64. Historically we didn't default to SSE2 and
- -- SSE1 on x86, which results in defacto nondeterminism for how
- -- rounding behaves in the associated x87 floating point instructions
- -- because variations in the spill/fpu stack placement of arguments for
- -- operations would change the precision and final result of what
- -- would otherwise be the same expressions with respect to single or
- -- double precision IEEE floating point computations.
- , ncgSseVersion =
- let v | sseVersion dflags < Just SSE2 = Just SSE2
- | otherwise = sseVersion dflags
- in case platformArch (targetPlatform dflags) of
- ArchX86_64 -> v
- ArchX86 -> v
- _ -> Nothing
-
- , ncgDwarfEnabled = osElfTarget (platformOS (targetPlatform dflags)) && debugLevel dflags > 0 && platformArch (targetPlatform dflags) /= ArchAArch64
- , ncgDwarfUnwindings = osElfTarget (platformOS (targetPlatform dflags)) && debugLevel dflags > 0
- , ncgDwarfStripBlockInfo = osElfTarget (platformOS (targetPlatform dflags)) && debugLevel dflags < 2 -- We strip out block information when running with -g0 or -g1.
- , ncgDwarfSourceNotes = osElfTarget (platformOS (targetPlatform dflags)) && debugLevel dflags > 2 -- We produce GHC-specific source-note DIEs only with -g3
- , ncgExposeInternalSymbols = gopt Opt_ExposeInternalSymbols dflags
- }