content: 
  
  -- ----------------------------------------------------------------------------
  -- | Pretty print helpers for the LLVM Code generator.
  --
  module GHC.CmmToLlvm.Ppr (
          pprLlvmCmmDecl, pprLlvmData, infoSection
      ) where
  
  import GHC.Prelude
  
  import GHC.Llvm
  import GHC.CmmToLlvm.Base
  import GHC.CmmToLlvm.Data
  import GHC.CmmToLlvm.Config
  
  import GHC.Cmm.CLabel
  import GHC.Cmm
  
  import GHC.Data.FastString
  import GHC.Utils.Outputable
  import GHC.Types.Unique
  
  -- ----------------------------------------------------------------------------
  -- * Top level
  --
  
  -- | Pretty print LLVM data code
  pprLlvmData :: IsDoc doc => LlvmCgConfig -> LlvmData -> doc
  pprLlvmData cfg (globals, types) =
      let ppLlvmTys (LMAlias    a) = line $ ppLlvmAlias a
          ppLlvmTys (LMFunction f) = ppLlvmFunctionDecl f
          ppLlvmTys _other         = empty
  
          types'   = vcat $ map ppLlvmTys types
          globals' = ppLlvmGlobals cfg globals
      in types' $$ globals'
  {-# SPECIALIZE pprLlvmData :: LlvmCgConfig -> LlvmData -> SDoc #-}
  {-# SPECIALIZE pprLlvmData :: LlvmCgConfig -> LlvmData -> HDoc #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable
  
  
  -- | Pretty print LLVM code
  -- The HDoc we return is used to produce the final LLVM file, with the
  -- SDoc being returned alongside for use when @Opt_D_dump_llvm@ is set
  -- as we can't (currently) dump HDocs.
  pprLlvmCmmDecl :: LlvmCmmDecl -> LlvmM (HDoc, SDoc)
  pprLlvmCmmDecl (CmmData _ lmdata) = do
    opts <- getConfig
    return ( vcat $ map (pprLlvmData opts) lmdata
           , vcat $ map (pprLlvmData opts) lmdata)
  
  pprLlvmCmmDecl (CmmProc mb_info entry_lbl live (ListGraph blks))
    = do let lbl = case mb_info of
                       Nothing -> entry_lbl
                       Just (CmmStaticsRaw info_lbl _) -> info_lbl
             link = if externallyVisibleCLabel lbl
                        then ExternallyVisible
                        else Internal
             lmblocks = map (\(BasicBlock id stmts) ->
                                  LlvmBlock (getUnique id) stmts) blks
  
         funDec   <- llvmFunSig live lbl link
         cfg      <- getConfig
         platform <- getPlatform
         let buildArg = fsLit . showSDocOneLine (llvmCgContext cfg). ppPlainName cfg
             funArgs = map buildArg (llvmFunArgs platform live)
             funSect = llvmFunSection cfg (decName funDec)
  
         -- generate the info table
         prefix <- case mb_info of
                       Nothing -> return Nothing
                       Just (CmmStaticsRaw _ statics) -> do
                         infoStatics <- mapM genData statics
                         let infoTy = LMStruct $ map getStatType infoStatics
                         return $ Just $ LMStaticStruc infoStatics infoTy
  
  
         let fun = LlvmFunction funDec funArgs llvmStdFunAttrs funSect
                                prefix lmblocks
             name = decName $ funcDecl fun
             defName = llvmDefLabel name
             funcDecl' = (funcDecl fun) { decName = defName }
             fun' = fun { funcDecl = funcDecl' }
             funTy = LMFunction funcDecl'
             funVar = LMGlobalVar name
                                  (LMPointer funTy)
                                  link
                                  Nothing
                                  Nothing
                                  Alias
             defVar = LMGlobalVar defName
                                  (LMPointer funTy)
                                  (funcLinkage funcDecl')
                                  (funcSect fun)
                                  (funcAlign funcDecl')
                                  Alias
             alias = LMGlobal funVar
                              (Just $ LMBitc (LMStaticPointer defVar)
                                             i8Ptr)
  
         return ( vcat [line $ ppLlvmGlobal cfg alias, ppLlvmFunction cfg fun']
                , vcat [line $ ppLlvmGlobal cfg alias, ppLlvmFunction cfg fun'])
  
  
  -- | The section we are putting info tables and their entry code into, should
  -- be unique since we process the assembly pattern matching this.
  infoSection :: String
  infoSection = "X98A__STRIP,__me"
  