PageRenderTime 55ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/compiler/llvmGen/LlvmCodeGen/Base.hs

https://github.com/crdueck/ghc
Haskell | 479 lines | 286 code | 81 blank | 112 comment | 3 complexity | 3cf95480d36a62dcca8a670da9c0b585 MD5 | raw file
  1. -- ----------------------------------------------------------------------------
  2. -- | Base LLVM Code Generation module
  3. --
  4. -- Contains functions useful through out the code generator.
  5. --
  6. module LlvmCodeGen.Base (
  7. LlvmCmmDecl, LlvmBasicBlock,
  8. LiveGlobalRegs,
  9. LlvmUnresData, LlvmData, UnresLabel, UnresStatic,
  10. LlvmVersion, defaultLlvmVersion, minSupportLlvmVersion,
  11. maxSupportLlvmVersion,
  12. LlvmM,
  13. runLlvm, liftStream, withClearVars, varLookup, varInsert,
  14. markStackReg, checkStackReg,
  15. funLookup, funInsert, getLlvmVer, getDynFlags, getDynFlag, getLlvmPlatform,
  16. dumpIfSetLlvm, renderLlvm, runUs, markUsedVar, getUsedVars,
  17. ghcInternalFunctions,
  18. getMetaUniqueId,
  19. setUniqMeta, getUniqMeta,
  20. freshSectionId,
  21. cmmToLlvmType, widthToLlvmFloat, widthToLlvmInt, llvmFunTy,
  22. llvmFunSig, llvmStdFunAttrs, llvmFunAlign, llvmInfAlign,
  23. llvmPtrBits, mkLlvmFunc, tysToParams,
  24. strCLabel_llvm, strDisplayName_llvm, strProcedureName_llvm,
  25. getGlobalPtr, generateAliases,
  26. ) where
  27. #include "HsVersions.h"
  28. import Llvm
  29. import LlvmCodeGen.Regs
  30. import CLabel
  31. import CodeGen.Platform ( activeStgRegs )
  32. import DynFlags
  33. import FastString
  34. import Cmm
  35. import qualified Outputable as Outp
  36. import qualified Pretty as Prt
  37. import Platform
  38. import UniqFM
  39. import Unique
  40. import BufWrite ( BufHandle )
  41. import UniqSet
  42. import UniqSupply
  43. import ErrUtils
  44. import qualified Stream
  45. -- ----------------------------------------------------------------------------
  46. -- * Some Data Types
  47. --
  48. type LlvmCmmDecl = GenCmmDecl [LlvmData] (Maybe CmmStatics) (ListGraph LlvmStatement)
  49. type LlvmBasicBlock = GenBasicBlock LlvmStatement
  50. -- | Global registers live on proc entry
  51. type LiveGlobalRegs = [GlobalReg]
  52. -- | Unresolved code.
  53. -- Of the form: (data label, data type, unresolved data)
  54. type LlvmUnresData = (CLabel, Section, LlvmType, [UnresStatic])
  55. -- | Top level LLVM Data (globals and type aliases)
  56. type LlvmData = ([LMGlobal], [LlvmType])
  57. -- | An unresolved Label.
  58. --
  59. -- Labels are unresolved when we haven't yet determined if they are defined in
  60. -- the module we are currently compiling, or an external one.
  61. type UnresLabel = CmmLit
  62. type UnresStatic = Either UnresLabel LlvmStatic
  63. -- ----------------------------------------------------------------------------
  64. -- * Type translations
  65. --
  66. -- | Translate a basic CmmType to an LlvmType.
  67. cmmToLlvmType :: CmmType -> LlvmType
  68. cmmToLlvmType ty | isVecType ty = LMVector (vecLength ty) (cmmToLlvmType (vecElemType ty))
  69. | isFloatType ty = widthToLlvmFloat $ typeWidth ty
  70. | otherwise = widthToLlvmInt $ typeWidth ty
  71. -- | Translate a Cmm Float Width to a LlvmType.
  72. widthToLlvmFloat :: Width -> LlvmType
  73. widthToLlvmFloat W32 = LMFloat
  74. widthToLlvmFloat W64 = LMDouble
  75. widthToLlvmFloat W80 = LMFloat80
  76. widthToLlvmFloat W128 = LMFloat128
  77. widthToLlvmFloat w = panic $ "widthToLlvmFloat: Bad float size: " ++ show w
  78. -- | Translate a Cmm Bit Width to a LlvmType.
  79. widthToLlvmInt :: Width -> LlvmType
  80. widthToLlvmInt w = LMInt $ widthInBits w
  81. -- | GHC Call Convention for LLVM
  82. llvmGhcCC :: DynFlags -> LlvmCallConvention
  83. llvmGhcCC dflags
  84. | platformUnregisterised (targetPlatform dflags) = CC_Ccc
  85. | otherwise = CC_Ncc 10
  86. -- | Llvm Function type for Cmm function
  87. llvmFunTy :: LiveGlobalRegs -> LlvmM LlvmType
  88. llvmFunTy live = return . LMFunction =<< llvmFunSig' live (fsLit "a") ExternallyVisible
  89. -- | Llvm Function signature
  90. llvmFunSig :: LiveGlobalRegs -> CLabel -> LlvmLinkageType -> LlvmM LlvmFunctionDecl
  91. llvmFunSig live lbl link = do
  92. lbl' <- strCLabel_llvm lbl
  93. llvmFunSig' live lbl' link
  94. llvmFunSig' :: LiveGlobalRegs -> LMString -> LlvmLinkageType -> LlvmM LlvmFunctionDecl
  95. llvmFunSig' live lbl link
  96. = do let toParams x | isPointer x = (x, [NoAlias, NoCapture])
  97. | otherwise = (x, [])
  98. dflags <- getDynFlags
  99. return $ LlvmFunctionDecl lbl link (llvmGhcCC dflags) LMVoid FixedArgs
  100. (map (toParams . getVarType) (llvmFunArgs dflags live))
  101. (llvmFunAlign dflags)
  102. -- | Create a Haskell function in LLVM.
  103. mkLlvmFunc :: LiveGlobalRegs -> CLabel -> LlvmLinkageType -> LMSection -> LlvmBlocks
  104. -> LlvmM LlvmFunction
  105. mkLlvmFunc live lbl link sec blks
  106. = do funDec <- llvmFunSig live lbl link
  107. dflags <- getDynFlags
  108. let funArgs = map (fsLit . Outp.showSDoc dflags . ppPlainName) (llvmFunArgs dflags live)
  109. return $ LlvmFunction funDec funArgs llvmStdFunAttrs sec blks
  110. -- | Alignment to use for functions
  111. llvmFunAlign :: DynFlags -> LMAlign
  112. llvmFunAlign dflags = Just (wORD_SIZE dflags)
  113. -- | Alignment to use for into tables
  114. llvmInfAlign :: DynFlags -> LMAlign
  115. llvmInfAlign dflags = Just (wORD_SIZE dflags)
  116. -- | A Function's arguments
  117. llvmFunArgs :: DynFlags -> LiveGlobalRegs -> [LlvmVar]
  118. llvmFunArgs dflags live =
  119. map (lmGlobalRegArg dflags) (filter isPassed (activeStgRegs platform))
  120. where platform = targetPlatform dflags
  121. isLive r = not (isSSE r) || r `elem` alwaysLive || r `elem` live
  122. isPassed r = not (isSSE r) || isLive r
  123. isSSE (FloatReg _) = True
  124. isSSE (DoubleReg _) = True
  125. isSSE (XmmReg _) = True
  126. isSSE _ = False
  127. -- | Llvm standard fun attributes
  128. llvmStdFunAttrs :: [LlvmFuncAttr]
  129. llvmStdFunAttrs = [NoUnwind]
  130. -- | Convert a list of types to a list of function parameters
  131. -- (each with no parameter attributes)
  132. tysToParams :: [LlvmType] -> [LlvmParameter]
  133. tysToParams = map (\ty -> (ty, []))
  134. -- | Pointer width
  135. llvmPtrBits :: DynFlags -> Int
  136. llvmPtrBits dflags = widthInBits $ typeWidth $ gcWord dflags
  137. -- ----------------------------------------------------------------------------
  138. -- * Llvm Version
  139. --
  140. -- | LLVM Version Number
  141. type LlvmVersion = Int
  142. -- | The LLVM Version we assume if we don't know
  143. defaultLlvmVersion :: LlvmVersion
  144. defaultLlvmVersion = 30
  145. minSupportLlvmVersion :: LlvmVersion
  146. minSupportLlvmVersion = 28
  147. maxSupportLlvmVersion :: LlvmVersion
  148. maxSupportLlvmVersion = 33
  149. -- ----------------------------------------------------------------------------
  150. -- * Environment Handling
  151. --
  152. data LlvmEnv = LlvmEnv
  153. { envVersion :: LlvmVersion -- ^ LLVM version
  154. , envDynFlags :: DynFlags -- ^ Dynamic flags
  155. , envOutput :: BufHandle -- ^ Output buffer
  156. , envUniq :: UniqSupply -- ^ Supply of unique values
  157. , envNextSection :: Int -- ^ Supply of fresh section IDs
  158. , envFreshMeta :: Int -- ^ Supply of fresh metadata IDs
  159. , envUniqMeta :: UniqFM Int -- ^ Global metadata nodes
  160. , envFunMap :: LlvmEnvMap -- ^ Global functions so far, with type
  161. , envAliases :: UniqSet LMString -- ^ Globals that we had to alias, see [Llvm Forward References]
  162. , envUsedVars :: [LlvmVar] -- ^ Pointers to be added to llvm.used (see @cmmUsedLlvmGens@)
  163. -- the following get cleared for every function (see @withClearVars@)
  164. , envVarMap :: LlvmEnvMap -- ^ Local variables so far, with type
  165. , envStackRegs :: [GlobalReg] -- ^ Non-constant registers (alloca'd in the function prelude)
  166. }
  167. type LlvmEnvMap = UniqFM LlvmType
  168. -- | The Llvm monad. Wraps @LlvmEnv@ state as well as the @IO@ monad
  169. newtype LlvmM a = LlvmM { runLlvmM :: LlvmEnv -> IO (a, LlvmEnv) }
  170. instance Monad LlvmM where
  171. return x = LlvmM $ \env -> return (x, env)
  172. m >>= f = LlvmM $ \env -> do (x, env') <- runLlvmM m env
  173. runLlvmM (f x) env'
  174. instance Functor LlvmM where
  175. fmap f m = LlvmM $ \env -> do (x, env') <- runLlvmM m env
  176. return (f x, env')
  177. instance HasDynFlags LlvmM where
  178. getDynFlags = LlvmM $ \env -> return (envDynFlags env, env)
  179. -- | Lifting of IO actions. Not exported, as we want to encapsulate IO.
  180. liftIO :: IO a -> LlvmM a
  181. liftIO m = LlvmM $ \env -> do x <- m
  182. return (x, env)
  183. -- | Get initial Llvm environment.
  184. runLlvm :: DynFlags -> LlvmVersion -> BufHandle -> UniqSupply -> LlvmM () -> IO ()
  185. runLlvm dflags ver out us m = do
  186. _ <- runLlvmM m env
  187. return ()
  188. where env = LlvmEnv { envFunMap = emptyUFM
  189. , envVarMap = emptyUFM
  190. , envStackRegs = []
  191. , envUsedVars = []
  192. , envAliases = emptyUniqSet
  193. , envVersion = ver
  194. , envDynFlags = dflags
  195. , envOutput = out
  196. , envUniq = us
  197. , envFreshMeta = 0
  198. , envUniqMeta = emptyUFM
  199. , envNextSection = 1
  200. }
  201. -- | Get environment (internal)
  202. getEnv :: (LlvmEnv -> a) -> LlvmM a
  203. getEnv f = LlvmM (\env -> return (f env, env))
  204. -- | Modify environment (internal)
  205. modifyEnv :: (LlvmEnv -> LlvmEnv) -> LlvmM ()
  206. modifyEnv f = LlvmM (\env -> return ((), f env))
  207. -- | Lift a stream into the LlvmM monad
  208. liftStream :: Stream.Stream IO a x -> Stream.Stream LlvmM a x
  209. liftStream s = Stream.Stream $ do
  210. r <- liftIO $ Stream.runStream s
  211. case r of
  212. Left b -> return (Left b)
  213. Right (a, r2) -> return (Right (a, liftStream r2))
  214. -- | Clear variables from the environment for a subcomputation
  215. withClearVars :: LlvmM a -> LlvmM a
  216. withClearVars m = LlvmM $ \env -> do
  217. (x, env') <- runLlvmM m env { envVarMap = emptyUFM, envStackRegs = [] }
  218. return (x, env' { envVarMap = emptyUFM, envStackRegs = [] })
  219. -- | Insert variables or functions into the environment.
  220. varInsert, funInsert :: Uniquable key => key -> LlvmType -> LlvmM ()
  221. varInsert s t = modifyEnv $ \env -> env { envVarMap = addToUFM (envVarMap env) s t }
  222. funInsert s t = modifyEnv $ \env -> env { envFunMap = addToUFM (envFunMap env) s t }
  223. -- | Lookup variables or functions in the environment.
  224. varLookup, funLookup :: Uniquable key => key -> LlvmM (Maybe LlvmType)
  225. varLookup s = getEnv (flip lookupUFM s . envVarMap)
  226. funLookup s = getEnv (flip lookupUFM s . envFunMap)
  227. -- | Set a register as allocated on the stack
  228. markStackReg :: GlobalReg -> LlvmM ()
  229. markStackReg r = modifyEnv $ \env -> env { envStackRegs = r : envStackRegs env }
  230. -- | Check whether a register is allocated on the stack
  231. checkStackReg :: GlobalReg -> LlvmM Bool
  232. checkStackReg r = getEnv ((elem r) . envStackRegs)
  233. -- | Allocate a new global unnamed metadata identifier
  234. getMetaUniqueId :: LlvmM Int
  235. getMetaUniqueId = LlvmM $ \env -> return (envFreshMeta env, env { envFreshMeta = envFreshMeta env + 1})
  236. -- | Get the LLVM version we are generating code for
  237. getLlvmVer :: LlvmM LlvmVersion
  238. getLlvmVer = getEnv envVersion
  239. -- | Get the platform we are generating code for
  240. getDynFlag :: (DynFlags -> a) -> LlvmM a
  241. getDynFlag f = getEnv (f . envDynFlags)
  242. -- | Get the platform we are generating code for
  243. getLlvmPlatform :: LlvmM Platform
  244. getLlvmPlatform = getDynFlag targetPlatform
  245. -- | Dumps the document if the corresponding flag has been set by the user
  246. dumpIfSetLlvm :: DumpFlag -> String -> Outp.SDoc -> LlvmM ()
  247. dumpIfSetLlvm flag hdr doc = do
  248. dflags <- getDynFlags
  249. liftIO $ dumpIfSet_dyn dflags flag hdr doc
  250. -- | Prints the given contents to the output handle
  251. renderLlvm :: Outp.SDoc -> LlvmM ()
  252. renderLlvm sdoc = do
  253. -- Write to output
  254. dflags <- getDynFlags
  255. out <- getEnv envOutput
  256. let doc = Outp.withPprStyleDoc dflags (Outp.mkCodeStyle Outp.CStyle) sdoc
  257. liftIO $ Prt.bufLeftRender out doc
  258. -- Dump, if requested
  259. dumpIfSetLlvm Opt_D_dump_llvm "LLVM Code" sdoc
  260. return ()
  261. -- | Run a @UniqSM@ action with our unique supply
  262. runUs :: UniqSM a -> LlvmM a
  263. runUs m = LlvmM $ \env -> do
  264. let (x, us') = initUs (envUniq env) m
  265. return (x, env { envUniq = us' })
  266. -- | Marks a variable as "used"
  267. markUsedVar :: LlvmVar -> LlvmM ()
  268. markUsedVar v = modifyEnv $ \env -> env { envUsedVars = v : envUsedVars env }
  269. -- | Return all variables marked as "used" so far
  270. getUsedVars :: LlvmM [LlvmVar]
  271. getUsedVars = getEnv envUsedVars
  272. -- | Saves that at some point we didn't know the type of the label and
  273. -- generated a reference to a type variable instead
  274. saveAlias :: LMString -> LlvmM ()
  275. saveAlias lbl = modifyEnv $ \env -> env { envAliases = addOneToUniqSet (envAliases env) lbl }
  276. -- | Sets metadata node for a given unique
  277. setUniqMeta :: Unique -> Int -> LlvmM ()
  278. setUniqMeta f m = modifyEnv $ \env -> env { envUniqMeta = addToUFM (envUniqMeta env) f m }
  279. -- | Gets metadata node for given unique
  280. getUniqMeta :: Unique -> LlvmM (Maybe Int)
  281. getUniqMeta s = getEnv (flip lookupUFM s . envUniqMeta)
  282. -- | Returns a fresh section ID
  283. freshSectionId :: LlvmM Int
  284. freshSectionId = LlvmM $ \env -> return (envNextSection env, env { envNextSection = envNextSection env + 1})
  285. -- ----------------------------------------------------------------------------
  286. -- * Internal functions
  287. --
  288. -- | Here we pre-initialise some functions that are used internally by GHC
  289. -- so as to make sure they have the most general type in the case that
  290. -- user code also uses these functions but with a different type than GHC
  291. -- internally. (Main offender is treating return type as 'void' instead of
  292. -- 'void *'). Fixes trac #5486.
  293. ghcInternalFunctions :: LlvmM ()
  294. ghcInternalFunctions = do
  295. dflags <- getDynFlags
  296. mk "memcpy" i8Ptr [i8Ptr, i8Ptr, llvmWord dflags]
  297. mk "memmove" i8Ptr [i8Ptr, i8Ptr, llvmWord dflags]
  298. mk "memset" i8Ptr [i8Ptr, llvmWord dflags, llvmWord dflags]
  299. mk "newSpark" (llvmWord dflags) [i8Ptr, i8Ptr]
  300. where
  301. mk n ret args = do
  302. let n' = fsLit n
  303. decl = LlvmFunctionDecl n' ExternallyVisible CC_Ccc ret
  304. FixedArgs (tysToParams args) Nothing
  305. renderLlvm $ ppLlvmFunctionDecl decl
  306. funInsert n' (LMFunction decl)
  307. -- ----------------------------------------------------------------------------
  308. -- * Label handling
  309. --
  310. -- | Pretty print a 'CLabel'.
  311. strCLabel_llvm :: CLabel -> LlvmM LMString
  312. strCLabel_llvm lbl = do
  313. platform <- getLlvmPlatform
  314. dflags <- getDynFlags
  315. let sdoc = pprCLabel platform lbl
  316. str = Outp.renderWithStyle dflags sdoc (Outp.mkCodeStyle Outp.CStyle)
  317. return (fsLit str)
  318. strDisplayName_llvm :: CLabel -> LlvmM LMString
  319. strDisplayName_llvm lbl = do
  320. platform <- getLlvmPlatform
  321. dflags <- getDynFlags
  322. let sdoc = pprCLabel platform lbl
  323. depth = Outp.PartWay 1
  324. style = Outp.mkUserStyle (const Outp.NameNotInScope2, const True) depth
  325. str = Outp.renderWithStyle dflags sdoc style
  326. return (fsLit (dropInfoSuffix str))
  327. dropInfoSuffix :: String -> String
  328. dropInfoSuffix = go
  329. where go "_info" = []
  330. go "_static_info" = []
  331. go "_con_info" = []
  332. go (x:xs) = x:go xs
  333. go [] = []
  334. strProcedureName_llvm :: CLabel -> LlvmM LMString
  335. strProcedureName_llvm lbl = do
  336. platform <- getLlvmPlatform
  337. dflags <- getDynFlags
  338. let sdoc = pprCLabel platform lbl
  339. depth = Outp.PartWay 1
  340. style = Outp.mkUserStyle (const Outp.NameUnqual, const False) depth
  341. str = Outp.renderWithStyle dflags sdoc style
  342. return (fsLit str)
  343. -- ----------------------------------------------------------------------------
  344. -- * Global variables / forward references
  345. --
  346. -- | Create/get a pointer to a global value. Might return an alias if
  347. -- the value in question hasn't been defined yet. We especially make
  348. -- no guarantees on the type of the returned pointer.
  349. getGlobalPtr :: LMString -> LlvmM LlvmVar
  350. getGlobalPtr llvmLbl = do
  351. m_ty <- funLookup llvmLbl
  352. let mkGlbVar lbl ty = LMGlobalVar lbl (LMPointer ty) Private Nothing Nothing
  353. case m_ty of
  354. -- Directly reference if we have seen it already
  355. Just ty -> return $ mkGlbVar llvmLbl ty Global
  356. -- Otherwise use a forward alias of it
  357. Nothing -> do
  358. saveAlias llvmLbl
  359. return $ mkGlbVar (llvmLbl `appendFS` fsLit "$alias") i8 Alias
  360. -- | Generate definitions for aliases forward-referenced by @getGlobalPtr@.
  361. --
  362. -- Must be called at a point where we are sure that no new global definitions
  363. -- will be generated anymore!
  364. generateAliases :: LlvmM ([LMGlobal], [LlvmType])
  365. generateAliases = do
  366. delayed <- fmap uniqSetToList $ getEnv envAliases
  367. defss <- flip mapM delayed $ \lbl -> do
  368. let var ty = LMGlobalVar lbl (LMPointer ty) External Nothing Nothing Global
  369. aliasLbl = lbl `appendFS` fsLit "$alias"
  370. aliasVar = LMGlobalVar aliasLbl i8Ptr Private Nothing Nothing Alias
  371. -- If we have a definition, set the alias value using a
  372. -- cost. Otherwise, declare it as an undefined external symbol.
  373. m_ty <- funLookup lbl
  374. case m_ty of
  375. Just ty -> return [LMGlobal aliasVar $ Just $ LMBitc (LMStaticPointer (var ty)) i8Ptr]
  376. Nothing -> return [LMGlobal (var i8) Nothing,
  377. LMGlobal aliasVar $ Just $ LMStaticPointer (var i8) ]
  378. -- Reset forward list
  379. modifyEnv $ \env -> env { envAliases = emptyUniqSet }
  380. return (concat defss, [])
  381. -- Note [Llvm Forward References]
  382. --
  383. -- The issue here is that LLVM insists on being strongly typed at
  384. -- every corner, so the first time we mention something, we have to
  385. -- settle what type we assign to it. That makes things awkward, as Cmm
  386. -- will often reference things before their definition, and we have no
  387. -- idea what (LLVM) type it is going to be before that point.
  388. --
  389. -- Our work-around is to define "aliases" of a standard type (i8 *) in
  390. -- these kind of situations, which we later tell LLVM to be either
  391. -- references to their actual local definitions (involving a cast) or
  392. -- an external reference. This obviously only works for pointers.
  393. -- ----------------------------------------------------------------------------
  394. -- * Misc
  395. --
  396. -- | Error function
  397. panic :: String -> a
  398. panic s = Outp.panic $ "LlvmCodeGen.Base." ++ s