diff options
Diffstat (limited to 'compiler/llvmGen')
-rw-r--r-- | compiler/llvmGen/LlvmCodeGen/Base.hs | 8 | ||||
-rw-r--r-- | compiler/llvmGen/LlvmCodeGen/CodeGen.hs | 4 | ||||
-rw-r--r-- | compiler/llvmGen/LlvmCodeGen/Data.hs | 43 | ||||
-rw-r--r-- | compiler/llvmGen/LlvmCodeGen/Ppr.hs | 4 |
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" |