summaryrefslogtreecommitdiff
path: root/compiler/llvmGen
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/llvmGen')
-rw-r--r--compiler/llvmGen/LlvmCodeGen/Base.hs8
-rw-r--r--compiler/llvmGen/LlvmCodeGen/CodeGen.hs4
-rw-r--r--compiler/llvmGen/LlvmCodeGen/Data.hs43
-rw-r--r--compiler/llvmGen/LlvmCodeGen/Ppr.hs4
4 files changed, 47 insertions, 12 deletions
diff --git a/compiler/llvmGen/LlvmCodeGen/Base.hs b/compiler/llvmGen/LlvmCodeGen/Base.hs
index 5ef0a4bbfa..0cd132ed7f 100644
--- a/compiler/llvmGen/LlvmCodeGen/Base.hs
+++ b/compiler/llvmGen/LlvmCodeGen/Base.hs
@@ -27,7 +27,7 @@ module LlvmCodeGen.Base (
cmmToLlvmType, widthToLlvmFloat, widthToLlvmInt, llvmFunTy,
llvmFunSig, llvmFunArgs, llvmStdFunAttrs, llvmFunAlign, llvmInfAlign,
- llvmPtrBits, tysToParams,
+ llvmPtrBits, tysToParams, llvmFunSection,
strCLabel_llvm, strDisplayName_llvm, strProcedureName_llvm,
getGlobalPtr, generateExternDecls,
@@ -140,6 +140,12 @@ llvmFunAlign dflags = Just (wORD_SIZE dflags)
llvmInfAlign :: DynFlags -> LMAlign
llvmInfAlign dflags = Just (wORD_SIZE dflags)
+-- | Section to use for a function
+llvmFunSection :: DynFlags -> LMString -> LMSection
+llvmFunSection dflags lbl
+ | gopt Opt_SplitSections dflags = Just (concatFS [fsLit ".text.", lbl])
+ | otherwise = Nothing
+
-- | A Function's arguments
llvmFunArgs :: DynFlags -> LiveGlobalRegs -> [LlvmVar]
llvmFunArgs dflags live =
diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
index 9896c4040a..0a669fcb36 100644
--- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
+++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
@@ -145,7 +145,9 @@ getInstrinct2 fname fty@(LMFunction funSig) = do
return []
Nothing -> do
funInsert fname fty
- return [CmmData Data [([],[fty])]]
+ un <- runUs getUniqueM
+ let lbl = mkAsmTempLabel un
+ return [CmmData (Section Data lbl) [([],[fty])]]
return (fv, nilOL, tops)
diff --git a/compiler/llvmGen/LlvmCodeGen/Data.hs b/compiler/llvmGen/LlvmCodeGen/Data.hs
index b306748d23..ac93415b06 100644
--- a/compiler/llvmGen/LlvmCodeGen/Data.hs
+++ b/compiler/llvmGen/LlvmCodeGen/Data.hs
@@ -15,6 +15,7 @@ import LlvmCodeGen.Base
import BlockId
import CLabel
import Cmm
+import DynFlags
import FastString
import Outputable
@@ -36,6 +37,7 @@ 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
@@ -45,21 +47,44 @@ genLlvmData (sec, Statics lbl xs) = do
link = if (externallyVisibleCLabel lbl)
then ExternallyVisible else Internal
const = if isSecConstant sec then Constant else Global
- varDef = LMGlobalVar label tyAlias link Nothing Nothing const
+ varDef = LMGlobalVar label tyAlias link lmsec Nothing const
globDef = LMGlobal varDef struct
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
+
+-- Assumes that we only try to use section splitting on platforms with
+-- compatible section naming and toolchain :)
+llvmSectionType :: SectionType -> String
+llvmSectionType t = case t of
+ Text -> ".text"
+ ReadOnlyData -> ".rodata"
+ RelocatableReadOnlyData -> ".data.rel.ro"
+ ReadOnlyData16 -> ".rodata.cst16"
+ Data -> ".data"
+ UninitialisedData -> ".bss"
+ (OtherSection _) -> panic "llvmSectionType: unknown section type"
+
+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
+ let sectype = llvmSectionType t
+ return (Just (concatFS [fsLit sectype, fsLit ".", lmsuffix]))
-- ----------------------------------------------------------------------------
-- * Generate static data
diff --git a/compiler/llvmGen/LlvmCodeGen/Ppr.hs b/compiler/llvmGen/LlvmCodeGen/Ppr.hs
index 1a9373bce2..75f841a260 100644
--- a/compiler/llvmGen/LlvmCodeGen/Ppr.hs
+++ b/compiler/llvmGen/LlvmCodeGen/Ppr.hs
@@ -114,6 +114,7 @@ pprLlvmCmmDecl (CmmProc mb_info entry_lbl live (ListGraph blks))
dflags <- getDynFlags
let buildArg = fsLit . showSDoc dflags . ppPlainName
funArgs = map buildArg (llvmFunArgs dflags live)
+ funSect = llvmFunSection dflags (decName funDec)
-- generate the info table
prefix <- case mb_info of
@@ -123,7 +124,8 @@ pprLlvmCmmDecl (CmmProc mb_info entry_lbl live (ListGraph blks))
let infoTy = LMStruct $ map getStatType infoStatics
return $ Just $ LMStaticStruc infoStatics infoTy
- let fun = LlvmFunction funDec funArgs llvmStdFunAttrs Nothing
+
+ let fun = LlvmFunction funDec funArgs llvmStdFunAttrs funSect
prefix lmblocks
name = decName $ funcDecl fun
defName = name `appendFS` fsLit "$def"