Implement function-sections for Haskell code, #8405
[ghc.git] / compiler / llvmGen / LlvmCodeGen / Data.hs
index 6212cfc..3c1af4f 100644 (file)
@@ -1,9 +1,10 @@
+{-# LANGUAGE CPP #-}
 -- ----------------------------------------------------------------------------
 -- | Handle conversion of CmmData to LLVM code.
 --
 
 module LlvmCodeGen.Data (
-        genLlvmData
+        genLlvmData, genData
     ) where
 
 #include "HsVersions.h"
@@ -14,9 +15,10 @@ import LlvmCodeGen.Base
 import BlockId
 import CLabel
 import Cmm
+import DynFlags
 
 import FastString
-import qualified Outputable
+import Outputable
 
 -- ----------------------------------------------------------------------------
 -- * Constants
@@ -35,29 +37,53 @@ genLlvmData :: (Section, CmmStatics) -> LlvmM LlvmData
 genLlvmData (sec, Statics lbl xs) = do
     label <- strCLabel_llvm lbl
     static <- mapM genData xs
+    lmsec <- llvmSection sec
     let types   = map getStatType static
 
         strucTy = LMStruct types
-        alias   = LMAlias ((label `appendFS` structStr), strucTy)
+        tyAlias = LMAlias ((label `appendFS` structStr), strucTy)
 
-        struct         = Just $ LMStaticStruc static alias
+        struct         = Just $ LMStaticStruc static tyAlias
         link           = if (externallyVisibleCLabel lbl)
                             then ExternallyVisible else Internal
         const          = if isSecConstant sec then Constant else Global
-        glob           = LMGlobalVar label alias link Nothing Nothing const
+        varDef         = LMGlobalVar label tyAlias link lmsec Nothing const
+        globDef        = LMGlobal varDef struct
 
-    return ([LMGlobal glob struct], [alias])
+    return ([globDef], [tyAlias])
 
 -- | Should a data in this section be considered constant
 isSecConstant :: Section -> Bool
-isSecConstant Text                    = True
-isSecConstant ReadOnlyData            = True
-isSecConstant RelocatableReadOnlyData = True
-isSecConstant ReadOnlyData16          = True
-isSecConstant Data                    = False
-isSecConstant UninitialisedData       = False
-isSecConstant (OtherSection _)        = False
-
+isSecConstant (Section t _) = case t of
+    Text                    -> True
+    ReadOnlyData            -> True
+    RelocatableReadOnlyData -> True
+    ReadOnlyData16          -> True
+    Data                    -> False
+    UninitialisedData       -> False
+    (OtherSection _)        -> False
+
+-- | Format the section type part of a Cmm Section
+llvmSectionType :: SectionType -> FastString
+llvmSectionType t = case t of
+    Text                    -> fsLit ".text"
+    ReadOnlyData            -> fsLit ".rodata"
+    RelocatableReadOnlyData -> fsLit ".data.rel.ro"
+    ReadOnlyData16          -> fsLit ".rodata.cst16"
+    Data                    -> fsLit ".data"
+    UninitialisedData       -> fsLit ".bss"
+    (OtherSection _)        -> panic "llvmSectionType: unknown section type"
+
+-- | Format a Cmm Section into a LLVM section name
+llvmSection :: Section -> LlvmM LMSection
+llvmSection (Section t suffix) = do
+  dflags <- getDynFlags
+  let splitSect = gopt Opt_SplitSections dflags
+  if not splitSect
+  then return Nothing
+  else do
+    lmsuffix <- strCLabel_llvm suffix
+    return (Just (concatFS [llvmSectionType t, fsLit ".", lmsuffix]))
 
 -- ----------------------------------------------------------------------------
 -- * Generate static data
@@ -125,12 +151,3 @@ genStaticLit (CmmBlock b) = genStaticLit $ CmmLabel $ infoTblLbl b
 
 genStaticLit (CmmHighStackMark)
     = panic "genStaticLit: CmmHighStackMark unsupported!"
-
--- -----------------------------------------------------------------------------
--- * Misc
---
-
--- | Error Function
-panic :: String -> a
-panic s = Outputable.panic $ "LlvmCodeGen.Data." ++ s
-