{-# LANGUAGE CPP, TypeFamilies, ViewPatterns #-}
module LlvmCodeGen ( LlvmVersion (..), llvmCodeGen, llvmFixupAsm ) where
#include "HsVersions.h"
import GhcPrelude
import Llvm
import LlvmCodeGen.Base
import LlvmCodeGen.CodeGen
import LlvmCodeGen.Data
import LlvmCodeGen.Ppr
import LlvmCodeGen.Regs
import LlvmMangler
import BlockId
import CgUtils ( fixStgRegisters )
import Cmm
import CmmUtils
import Hoopl.Block
import Hoopl.Collections
import PprCmm
import BufWrite
import DynFlags
import ErrUtils
import FastString
import Outputable
import UniqSupply
import SysTools ( figureLlvmVersion )
import qualified Stream
import Control.Monad ( when )
import Data.Maybe ( fromMaybe, catMaybes )
import System.IO
llvmCodeGen :: DynFlags -> Handle -> UniqSupply
-> Stream.Stream IO RawCmmGroup ()
-> IO ()
llvmCodeGen :: DynFlags
-> Handle -> UniqSupply -> Stream IO RawCmmGroup () -> IO ()
llvmCodeGen dflags :: DynFlags
dflags h :: Handle
h us :: UniqSupply
us cmm_stream :: Stream IO RawCmmGroup ()
cmm_stream
= IO DynFlags -> SDoc -> (() -> ()) -> IO () -> IO ()
forall (m :: * -> *) a.
MonadIO m =>
m DynFlags -> SDoc -> (a -> ()) -> m a -> m a
withTiming (DynFlags -> IO DynFlags
forall (f :: * -> *) a. Applicative f => a -> f a
pure DynFlags
dflags) (String -> SDoc
text "LLVM CodeGen") (() -> () -> ()
forall a b. a -> b -> a
const ()) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
BufHandle
bufh <- Handle -> IO BufHandle
newBufHandle Handle
h
DynFlags -> String -> IO ()
showPass DynFlags
dflags "LLVM CodeGen"
LlvmVersion
ver <- (LlvmVersion -> Maybe LlvmVersion -> LlvmVersion
forall a. a -> Maybe a -> a
fromMaybe LlvmVersion
supportedLlvmVersion) (Maybe LlvmVersion -> LlvmVersion)
-> IO (Maybe LlvmVersion) -> IO LlvmVersion
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` DynFlags -> IO (Maybe LlvmVersion)
figureLlvmVersion DynFlags
dflags
DynFlags -> Int -> SDoc -> IO ()
debugTraceMsg DynFlags
dflags 2
(String -> SDoc
text "Using LLVM version:" SDoc -> SDoc -> SDoc
<+> String -> SDoc
text (LlvmVersion -> String
forall a. Show a => a -> String
show LlvmVersion
ver))
let doWarn :: Bool
doWarn = WarningFlag -> DynFlags -> Bool
wopt WarningFlag
Opt_WarnUnsupportedLlvmVersion DynFlags
dflags
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (LlvmVersion
ver LlvmVersion -> LlvmVersion -> Bool
forall a. Eq a => a -> a -> Bool
/= LlvmVersion
supportedLlvmVersion Bool -> Bool -> Bool
&& Bool
doWarn) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
DynFlags -> SDoc -> IO ()
putMsg DynFlags
dflags (String -> SDoc
text "You are using an unsupported version of LLVM!"
SDoc -> SDoc -> SDoc
$+$ String -> SDoc
text ("Currently only " String -> String -> String
forall a. [a] -> [a] -> [a]
++
LlvmVersion -> String
llvmVersionStr LlvmVersion
supportedLlvmVersion String -> String -> String
forall a. [a] -> [a] -> [a]
++
" is supported.")
SDoc -> SDoc -> SDoc
$+$ String -> SDoc
text "We will try though...")
DynFlags
-> LlvmVersion -> BufHandle -> UniqSupply -> LlvmM () -> IO ()
runLlvm DynFlags
dflags LlvmVersion
ver BufHandle
bufh UniqSupply
us (LlvmM () -> IO ()) -> LlvmM () -> IO ()
forall a b. (a -> b) -> a -> b
$
Stream LlvmM RawCmmGroup () -> LlvmM ()
llvmCodeGen' (Stream IO RawCmmGroup () -> Stream LlvmM RawCmmGroup ()
forall a x. Stream IO a x -> Stream LlvmM a x
liftStream Stream IO RawCmmGroup ()
cmm_stream)
BufHandle -> IO ()
bFlush BufHandle
bufh
llvmCodeGen' :: Stream.Stream LlvmM RawCmmGroup () -> LlvmM ()
llvmCodeGen' :: Stream LlvmM RawCmmGroup () -> LlvmM ()
llvmCodeGen' cmm_stream :: Stream LlvmM RawCmmGroup ()
cmm_stream
= do
SDoc -> LlvmM ()
renderLlvm SDoc
header
LlvmM ()
ghcInternalFunctions
LlvmM ()
cmmMetaLlvmPrelude
let llvmStream :: Stream LlvmM () ()
llvmStream = (RawCmmGroup -> LlvmM ())
-> Stream LlvmM RawCmmGroup () -> Stream LlvmM () ()
forall (m :: * -> *) a b x.
Monad m =>
(a -> m b) -> Stream m a x -> Stream m b x
Stream.mapM RawCmmGroup -> LlvmM ()
llvmGroupLlvmGens Stream LlvmM RawCmmGroup ()
cmm_stream
[()]
_ <- Stream LlvmM () () -> LlvmM [()]
forall (m :: * -> *) a. Monad m => Stream m a () -> m [a]
Stream.collect Stream LlvmM () ()
llvmStream
SDoc -> LlvmM ()
renderLlvm (SDoc -> LlvmM ()) -> (LlvmData -> SDoc) -> LlvmData -> LlvmM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LlvmData -> SDoc
pprLlvmData (LlvmData -> LlvmM ()) -> LlvmM LlvmData -> LlvmM ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< LlvmM LlvmData
generateExternDecls
LlvmM ()
cmmUsedLlvmGens
where
header :: SDoc
header :: SDoc
header = (DynFlags -> SDoc) -> SDoc
sdocWithDynFlags ((DynFlags -> SDoc) -> SDoc) -> (DynFlags -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \dflags :: DynFlags
dflags ->
let target :: String
target = LLVM_TARGET
layout :: String
layout = case String -> [(String, LlvmTarget)] -> Maybe LlvmTarget
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
target (DynFlags -> [(String, LlvmTarget)]
llvmTargets DynFlags
dflags) of
Just (LlvmTarget dl :: String
dl _ _) -> String
dl
Nothing -> String -> String
forall a. HasCallStack => String -> a
error (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ "Failed to lookup the datalayout for " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
target String -> String -> String
forall a. [a] -> [a] -> [a]
++ "; available targets: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [String] -> String
forall a. Show a => a -> String
show (((String, LlvmTarget) -> String)
-> [(String, LlvmTarget)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, LlvmTarget) -> String
forall a b. (a, b) -> a
fst ([(String, LlvmTarget)] -> [String])
-> [(String, LlvmTarget)] -> [String]
forall a b. (a -> b) -> a -> b
$ DynFlags -> [(String, LlvmTarget)]
llvmTargets DynFlags
dflags)
in String -> SDoc
text ("target datalayout = \"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
layout String -> String -> String
forall a. [a] -> [a] -> [a]
++ "\"")
SDoc -> SDoc -> SDoc
$+$ String -> SDoc
text ("target triple = \"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
target String -> String -> String
forall a. [a] -> [a] -> [a]
++ "\"")
llvmGroupLlvmGens :: RawCmmGroup -> LlvmM ()
llvmGroupLlvmGens :: RawCmmGroup -> LlvmM ()
llvmGroupLlvmGens cmm :: RawCmmGroup
cmm = do
let split :: GenCmmDecl b (map CmmStatics) (GenCmmGraph n)
-> LlvmM (Maybe (Section, b))
split (CmmData s :: Section
s d' :: b
d' ) = Maybe (Section, b) -> LlvmM (Maybe (Section, b))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Section, b) -> LlvmM (Maybe (Section, b)))
-> Maybe (Section, b) -> LlvmM (Maybe (Section, b))
forall a b. (a -> b) -> a -> b
$ (Section, b) -> Maybe (Section, b)
forall a. a -> Maybe a
Just (Section
s, b
d')
split (CmmProc h :: map CmmStatics
h l :: CLabel
l live :: [GlobalReg]
live g :: GenCmmGraph n
g) = do
let l' :: CLabel
l' = case KeyOf map -> map CmmStatics -> Maybe CmmStatics
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup (GenCmmGraph n -> BlockId
forall (n :: * -> * -> *). GenCmmGraph n -> BlockId
g_entry GenCmmGraph n
g) map CmmStatics
h of
Nothing -> CLabel
l
Just (Statics info_lbl :: CLabel
info_lbl _) -> CLabel
info_lbl
LMString
lml <- CLabel -> LlvmM LMString
strCLabel_llvm CLabel
l'
LMString -> LlvmType -> LlvmM ()
forall key. Uniquable key => key -> LlvmType -> LlvmM ()
funInsert LMString
lml (LlvmType -> LlvmM ()) -> LlvmM LlvmType -> LlvmM ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [GlobalReg] -> LlvmM LlvmType
llvmFunTy [GlobalReg]
live
Maybe (Section, b) -> LlvmM (Maybe (Section, b))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Section, b)
forall a. Maybe a
Nothing
[(Section, CmmStatics)]
cdata <- ([Maybe (Section, CmmStatics)] -> [(Section, CmmStatics)])
-> LlvmM [Maybe (Section, CmmStatics)]
-> LlvmM [(Section, CmmStatics)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Maybe (Section, CmmStatics)] -> [(Section, CmmStatics)]
forall a. [Maybe a] -> [a]
catMaybes (LlvmM [Maybe (Section, CmmStatics)]
-> LlvmM [(Section, CmmStatics)])
-> LlvmM [Maybe (Section, CmmStatics)]
-> LlvmM [(Section, CmmStatics)]
forall a b. (a -> b) -> a -> b
$ (GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM (Maybe (Section, CmmStatics)))
-> RawCmmGroup -> LlvmM [Maybe (Section, CmmStatics)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM (Maybe (Section, CmmStatics))
forall (map :: * -> *) b (n :: * -> * -> *).
(IsMap map, KeyOf map ~ BlockId) =>
GenCmmDecl b (map CmmStatics) (GenCmmGraph n)
-> LlvmM (Maybe (Section, b))
split RawCmmGroup
cmm
{-# SCC "llvm_datas_gen" #-}
[(Section, CmmStatics)] -> LlvmM ()
cmmDataLlvmGens [(Section, CmmStatics)]
cdata
{-# SCC "llvm_procs_gen" #-}
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM ())
-> RawCmmGroup -> LlvmM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM ()
cmmLlvmGen RawCmmGroup
cmm
cmmDataLlvmGens :: [(Section,CmmStatics)] -> LlvmM ()
cmmDataLlvmGens :: [(Section, CmmStatics)] -> LlvmM ()
cmmDataLlvmGens statics :: [(Section, CmmStatics)]
statics
= do [LlvmData]
lmdatas <- ((Section, CmmStatics) -> LlvmM LlvmData)
-> [(Section, CmmStatics)] -> LlvmM [LlvmData]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Section, CmmStatics) -> LlvmM LlvmData
genLlvmData [(Section, CmmStatics)]
statics
let ([[LMGlobal]] -> [LMGlobal]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat -> [LMGlobal]
gs, tss :: [[LlvmType]]
tss) = [LlvmData] -> ([[LMGlobal]], [[LlvmType]])
forall a b. [(a, b)] -> ([a], [b])
unzip [LlvmData]
lmdatas
let regGlobal :: LMGlobal -> LlvmM ()
regGlobal (LMGlobal (LMGlobalVar l :: LMString
l ty :: LlvmType
ty _ _ _ _) _)
= LMString -> LlvmType -> LlvmM ()
forall key. Uniquable key => key -> LlvmType -> LlvmM ()
funInsert LMString
l LlvmType
ty
regGlobal _ = () -> LlvmM ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
(LMGlobal -> LlvmM ()) -> [LMGlobal] -> LlvmM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ LMGlobal -> LlvmM ()
regGlobal [LMGlobal]
gs
[[LMGlobal]]
gss' <- (LMGlobal -> LlvmM [LMGlobal]) -> [LMGlobal] -> LlvmM [[LMGlobal]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM LMGlobal -> LlvmM [LMGlobal]
aliasify ([LMGlobal] -> LlvmM [[LMGlobal]])
-> [LMGlobal] -> LlvmM [[LMGlobal]]
forall a b. (a -> b) -> a -> b
$ [LMGlobal]
gs
SDoc -> LlvmM ()
renderLlvm (SDoc -> LlvmM ()) -> SDoc -> LlvmM ()
forall a b. (a -> b) -> a -> b
$ LlvmData -> SDoc
pprLlvmData ([[LMGlobal]] -> [LMGlobal]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[LMGlobal]]
gss', [[LlvmType]] -> [LlvmType]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[LlvmType]]
tss)
fixBottom :: RawCmmDecl -> LlvmM RawCmmDecl
fixBottom :: GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
fixBottom cp :: GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
cp@(CmmProc hdr :: LabelMap CmmStatics
hdr entry_lbl :: CLabel
entry_lbl live :: [GlobalReg]
live g :: GenCmmGraph CmmNode
g) =
LlvmM
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
-> (CmmBlock
-> LlvmM
(GenCmmDecl
CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)))
-> Maybe CmmBlock
-> LlvmM
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
forall (f :: * -> *) a. Applicative f => a -> f a
pure GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
cp) CmmBlock
-> LlvmM
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
fix_block (Maybe CmmBlock
-> LlvmM
(GenCmmDecl
CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)))
-> Maybe CmmBlock
-> LlvmM
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
forall a b. (a -> b) -> a -> b
$ KeyOf LabelMap -> LabelMap CmmBlock -> Maybe CmmBlock
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
mapLookup (GenCmmGraph CmmNode -> BlockId
forall (n :: * -> * -> *). GenCmmGraph n -> BlockId
g_entry GenCmmGraph CmmNode
g) LabelMap CmmBlock
blk_map
where
blk_map :: LabelMap CmmBlock
blk_map = GenCmmGraph CmmNode -> LabelMap CmmBlock
toBlockMap GenCmmGraph CmmNode
g
fix_block :: CmmBlock -> LlvmM RawCmmDecl
fix_block :: CmmBlock
-> LlvmM
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
fix_block blk :: CmmBlock
blk
| (CmmEntry e_lbl :: BlockId
e_lbl tickscp :: CmmTickScope
tickscp, middle :: Block CmmNode O O
middle, CmmBranch b_lbl :: BlockId
b_lbl) <- CmmBlock -> (CmmNode C O, Block CmmNode O O, CmmNode O C)
forall (n :: * -> * -> *).
Block n C C -> (n C O, Block n O O, n O C)
blockSplit CmmBlock
blk
, Block CmmNode O O -> Bool
forall (n :: * -> * -> *) e x. Block n e x -> Bool
isEmptyBlock Block CmmNode O O
middle
, BlockId
e_lbl BlockId -> BlockId -> Bool
forall a. Eq a => a -> a -> Bool
== BlockId
b_lbl = do
BlockId
new_lbl <- Unique -> BlockId
mkBlockId (Unique -> BlockId) -> LlvmM Unique -> LlvmM BlockId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LlvmM Unique
forall (m :: * -> *). MonadUnique m => m Unique
getUniqueM
let fst_blk :: CmmBlock
fst_blk =
CmmNode C O -> Block CmmNode O O -> CmmNode O C -> CmmBlock
forall (n :: * -> * -> *).
n C O -> Block n O O -> n O C -> Block n C C
BlockCC (BlockId -> CmmTickScope -> CmmNode C O
CmmEntry BlockId
e_lbl CmmTickScope
tickscp) Block CmmNode O O
forall (n :: * -> * -> *). Block n O O
BNil (BlockId -> CmmNode O C
CmmBranch BlockId
new_lbl)
snd_blk :: CmmBlock
snd_blk =
CmmNode C O -> Block CmmNode O O -> CmmNode O C -> CmmBlock
forall (n :: * -> * -> *).
n C O -> Block n O O -> n O C -> Block n C C
BlockCC (BlockId -> CmmTickScope -> CmmNode C O
CmmEntry BlockId
new_lbl CmmTickScope
tickscp) Block CmmNode O O
forall (n :: * -> * -> *). Block n O O
BNil (BlockId -> CmmNode O C
CmmBranch BlockId
new_lbl)
GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM
(GenCmmDecl
CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)))
-> (LabelMap CmmBlock
-> GenCmmDecl
CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
-> LabelMap CmmBlock
-> LlvmM
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabelMap CmmStatics
-> CLabel
-> [GlobalReg]
-> GenCmmGraph CmmNode
-> GenCmmDecl
CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
forall d h g. h -> CLabel -> [GlobalReg] -> g -> GenCmmDecl d h g
CmmProc LabelMap CmmStatics
hdr CLabel
entry_lbl [GlobalReg]
live (GenCmmGraph CmmNode
-> GenCmmDecl
CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
-> (LabelMap CmmBlock -> GenCmmGraph CmmNode)
-> LabelMap CmmBlock
-> GenCmmDecl
CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BlockId -> LabelMap CmmBlock -> GenCmmGraph CmmNode
ofBlockMap (GenCmmGraph CmmNode -> BlockId
forall (n :: * -> * -> *). GenCmmGraph n -> BlockId
g_entry GenCmmGraph CmmNode
g)
(LabelMap CmmBlock
-> LlvmM
(GenCmmDecl
CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)))
-> LabelMap CmmBlock
-> LlvmM
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
forall a b. (a -> b) -> a -> b
$ [(KeyOf LabelMap, CmmBlock)] -> LabelMap CmmBlock
forall (map :: * -> *) a. IsMap map => [(KeyOf map, a)] -> map a
mapFromList [(KeyOf LabelMap
BlockId
e_lbl, CmmBlock
fst_blk), (KeyOf LabelMap
BlockId
new_lbl, CmmBlock
snd_blk)]
fix_block _ = GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
forall (f :: * -> *) a. Applicative f => a -> f a
pure GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
cp
fixBottom rcd :: GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
rcd = GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
forall (f :: * -> *) a. Applicative f => a -> f a
pure GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
rcd
cmmLlvmGen ::RawCmmDecl -> LlvmM ()
cmmLlvmGen :: GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM ()
cmmLlvmGen cmm :: GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
cmm@CmmProc{} = do
DynFlags
dflags <- (DynFlags -> DynFlags) -> LlvmM DynFlags
forall a. (DynFlags -> a) -> LlvmM a
getDynFlag DynFlags -> DynFlags
forall a. a -> a
id
GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
fixed_cmm <- GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
fixBottom (GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM
(GenCmmDecl
CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)))
-> GenCmmDecl
CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM
(GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode))
forall a b. (a -> b) -> a -> b
$
{-# SCC "llvm_fix_regs" #-}
DynFlags
-> GenCmmDecl
CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> GenCmmDecl
CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
fixStgRegisters DynFlags
dflags GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
cmm
DumpFlag -> String -> SDoc -> LlvmM ()
dumpIfSetLlvm DumpFlag
Opt_D_dump_opt_cmm "Optimised Cmm" (RawCmmGroup -> SDoc
forall d info g.
(Outputable d, Outputable info, Outputable g) =>
GenCmmGroup d info g -> SDoc
pprCmmGroup [GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
fixed_cmm])
[LlvmCmmDecl]
llvmBC <- LlvmM [LlvmCmmDecl] -> LlvmM [LlvmCmmDecl]
forall a. LlvmM a -> LlvmM a
withClearVars (LlvmM [LlvmCmmDecl] -> LlvmM [LlvmCmmDecl])
-> LlvmM [LlvmCmmDecl] -> LlvmM [LlvmCmmDecl]
forall a b. (a -> b) -> a -> b
$ GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
-> LlvmM [LlvmCmmDecl]
genLlvmProc GenCmmDecl CmmStatics (LabelMap CmmStatics) (GenCmmGraph CmmNode)
fixed_cmm
(docs :: [SDoc]
docs, ivars :: [[LlvmVar]]
ivars) <- ([(SDoc, [LlvmVar])] -> ([SDoc], [[LlvmVar]]))
-> LlvmM [(SDoc, [LlvmVar])] -> LlvmM ([SDoc], [[LlvmVar]])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(SDoc, [LlvmVar])] -> ([SDoc], [[LlvmVar]])
forall a b. [(a, b)] -> ([a], [b])
unzip (LlvmM [(SDoc, [LlvmVar])] -> LlvmM ([SDoc], [[LlvmVar]]))
-> LlvmM [(SDoc, [LlvmVar])] -> LlvmM ([SDoc], [[LlvmVar]])
forall a b. (a -> b) -> a -> b
$ (LlvmCmmDecl -> LlvmM (SDoc, [LlvmVar]))
-> [LlvmCmmDecl] -> LlvmM [(SDoc, [LlvmVar])]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM LlvmCmmDecl -> LlvmM (SDoc, [LlvmVar])
pprLlvmCmmDecl [LlvmCmmDecl]
llvmBC
SDoc -> LlvmM ()
renderLlvm ([SDoc] -> SDoc
vcat [SDoc]
docs)
(LlvmVar -> LlvmM ()) -> [LlvmVar] -> LlvmM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ LlvmVar -> LlvmM ()
markUsedVar ([LlvmVar] -> LlvmM ()) -> [LlvmVar] -> LlvmM ()
forall a b. (a -> b) -> a -> b
$ [[LlvmVar]] -> [LlvmVar]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[LlvmVar]]
ivars
cmmLlvmGen _ = () -> LlvmM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
cmmMetaLlvmPrelude :: LlvmM ()
cmmMetaLlvmPrelude :: LlvmM ()
cmmMetaLlvmPrelude = do
[MetaDecl]
metas <- (((Unique, LMString, Maybe Unique) -> LlvmM MetaDecl)
-> [(Unique, LMString, Maybe Unique)] -> LlvmM [MetaDecl])
-> [(Unique, LMString, Maybe Unique)]
-> ((Unique, LMString, Maybe Unique) -> LlvmM MetaDecl)
-> LlvmM [MetaDecl]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Unique, LMString, Maybe Unique) -> LlvmM MetaDecl)
-> [(Unique, LMString, Maybe Unique)] -> LlvmM [MetaDecl]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM [(Unique, LMString, Maybe Unique)]
stgTBAA (((Unique, LMString, Maybe Unique) -> LlvmM MetaDecl)
-> LlvmM [MetaDecl])
-> ((Unique, LMString, Maybe Unique) -> LlvmM MetaDecl)
-> LlvmM [MetaDecl]
forall a b. (a -> b) -> a -> b
$ \(uniq :: Unique
uniq, name :: LMString
name, parent :: Maybe Unique
parent) -> do
MetaId
tbaaId <- LlvmM MetaId
getMetaUniqueId
Unique -> MetaId -> LlvmM ()
setUniqMeta Unique
uniq MetaId
tbaaId
Maybe MetaId
parentId <- LlvmM (Maybe MetaId)
-> (Unique -> LlvmM (Maybe MetaId))
-> Maybe Unique
-> LlvmM (Maybe MetaId)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe MetaId -> LlvmM (Maybe MetaId)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe MetaId
forall a. Maybe a
Nothing) Unique -> LlvmM (Maybe MetaId)
getUniqMeta Maybe Unique
parent
MetaDecl -> LlvmM MetaDecl
forall (m :: * -> *) a. Monad m => a -> m a
return (MetaDecl -> LlvmM MetaDecl) -> MetaDecl -> LlvmM MetaDecl
forall a b. (a -> b) -> a -> b
$ MetaId -> MetaExpr -> MetaDecl
MetaUnnamed MetaId
tbaaId (MetaExpr -> MetaDecl) -> MetaExpr -> MetaDecl
forall a b. (a -> b) -> a -> b
$ [MetaExpr] -> MetaExpr
MetaStruct ([MetaExpr] -> MetaExpr) -> [MetaExpr] -> MetaExpr
forall a b. (a -> b) -> a -> b
$
case Maybe MetaId
parentId of
Just p :: MetaId
p -> [ LMString -> MetaExpr
MetaStr LMString
name, MetaId -> MetaExpr
MetaNode MetaId
p ]
Nothing -> [ LMString -> MetaExpr
MetaStr LMString
name ]
SDoc -> LlvmM ()
renderLlvm (SDoc -> LlvmM ()) -> SDoc -> LlvmM ()
forall a b. (a -> b) -> a -> b
$ [MetaDecl] -> SDoc
ppLlvmMetas [MetaDecl]
metas
cmmUsedLlvmGens :: LlvmM ()
cmmUsedLlvmGens :: LlvmM ()
cmmUsedLlvmGens = do
[LlvmVar]
ivars <- LlvmM [LlvmVar]
getUsedVars
let cast :: LlvmVar -> LlvmStatic
cast x :: LlvmVar
x = LlvmStatic -> LlvmType -> LlvmStatic
LMBitc (LlvmVar -> LlvmStatic
LMStaticPointer (LlvmVar -> LlvmVar
pVarLift LlvmVar
x)) LlvmType
i8Ptr
ty :: LlvmType
ty = (Int -> LlvmType -> LlvmType
LMArray ([LlvmVar] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [LlvmVar]
ivars) LlvmType
i8Ptr)
usedArray :: LlvmStatic
usedArray = [LlvmStatic] -> LlvmType -> LlvmStatic
LMStaticArray ((LlvmVar -> LlvmStatic) -> [LlvmVar] -> [LlvmStatic]
forall a b. (a -> b) -> [a] -> [b]
map LlvmVar -> LlvmStatic
cast [LlvmVar]
ivars) LlvmType
ty
sectName :: Maybe LMString
sectName = LMString -> Maybe LMString
forall a. a -> Maybe a
Just (LMString -> Maybe LMString) -> LMString -> Maybe LMString
forall a b. (a -> b) -> a -> b
$ String -> LMString
fsLit "llvm.metadata"
lmUsedVar :: LlvmVar
lmUsedVar = LMString
-> LlvmType
-> LlvmLinkageType
-> Maybe LMString
-> LMAlign
-> LMConst
-> LlvmVar
LMGlobalVar (String -> LMString
fsLit "llvm.used") LlvmType
ty LlvmLinkageType
Appending Maybe LMString
sectName LMAlign
forall a. Maybe a
Nothing LMConst
Constant
lmUsed :: LMGlobal
lmUsed = LlvmVar -> Maybe LlvmStatic -> LMGlobal
LMGlobal LlvmVar
lmUsedVar (LlvmStatic -> Maybe LlvmStatic
forall a. a -> Maybe a
Just LlvmStatic
usedArray)
if [LlvmVar] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [LlvmVar]
ivars
then () -> LlvmM ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
else SDoc -> LlvmM ()
renderLlvm (SDoc -> LlvmM ()) -> SDoc -> LlvmM ()
forall a b. (a -> b) -> a -> b
$ LlvmData -> SDoc
pprLlvmData ([LMGlobal
lmUsed], [])