diff options
Diffstat (limited to 'compiler/llvmGen/LlvmCodeGen')
-rw-r--r-- | compiler/llvmGen/LlvmCodeGen/Base.hs | 4 | ||||
-rw-r--r-- | compiler/llvmGen/LlvmCodeGen/CodeGen.hs | 24 | ||||
-rw-r--r-- | compiler/llvmGen/LlvmCodeGen/Data.hs | 25 | ||||
-rw-r--r-- | compiler/llvmGen/LlvmCodeGen/Ppr.hs | 25 |
4 files changed, 47 insertions, 31 deletions
diff --git a/compiler/llvmGen/LlvmCodeGen/Base.hs b/compiler/llvmGen/LlvmCodeGen/Base.hs index 003c044db8..5e0df3ef86 100644 --- a/compiler/llvmGen/LlvmCodeGen/Base.hs +++ b/compiler/llvmGen/LlvmCodeGen/Base.hs @@ -43,7 +43,7 @@ type LlvmBasicBlock = GenBasicBlock LlvmStatement -- | Unresolved code. -- Of the form: (data label, data type, unresovled data) -type LlvmUnresData = (CLabel, LlvmType, [UnresStatic]) +type LlvmUnresData = (CLabel, Section, LlvmType, [UnresStatic]) -- | Top level LLVM Data (globals and type aliases) type LlvmData = ([LMGlobal], [LlvmType]) @@ -158,7 +158,7 @@ genCmmLabelRef = genStringLabelRef . strCLabel_llvm genStringLabelRef :: LMString -> LMGlobal genStringLabelRef cl = let ty = LMPointer $ LMArray 0 llvmWord - in (LMGlobalVar cl ty External Nothing Nothing, Nothing) + in (LMGlobalVar cl ty External Nothing Nothing False, Nothing) -- ---------------------------------------------------------------------------- diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs index 13fe123f48..85094f7803 100644 --- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs +++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs @@ -156,7 +156,7 @@ genCall env (CmmPrim MO_WriteBarrier) _ _ _ = do FixedArgs (Left [i1, i1, i1, i1, i1]) llvmFunAlign let fty = LMFunction funSig - let fv = LMGlobalVar fname fty (funcLinkage funSig) Nothing Nothing + let fv = LMGlobalVar fname fty (funcLinkage funSig) Nothing Nothing False let tops = case funLookup fname env of Just _ -> [] Nothing -> [CmmData Data [([],[fty])]] @@ -238,14 +238,14 @@ genCall env target res args ret = do Just ty'@(LMFunction sig) -> do -- Function in module in right form let fun = LMGlobalVar name ty' (funcLinkage sig) - Nothing Nothing + Nothing Nothing False return (env1, fun, nilOL, []) Just _ -> do -- label in module but not function pointer, convert let fty@(LMFunction sig) = funTy name let fun = LMGlobalVar name fty (funcLinkage sig) - Nothing Nothing + Nothing Nothing False (v1, s1) <- doExpr (pLift fty) $ Cast LM_Bitcast fun (pLift fty) return (env1, v1, unitOL s1, []) @@ -254,7 +254,7 @@ genCall env target res args ret = do -- label not in module, create external reference let fty@(LMFunction sig) = funTy name let fun = LMGlobalVar name fty (funcLinkage sig) - Nothing Nothing + Nothing Nothing False let top = CmmData Data [([],[fty])] let env' = funInsert name fty env1 return (env', fun, nilOL, [top]) @@ -827,7 +827,7 @@ genLit env cmm@(CmmLabel l) -- pointer to it. Just ty' -> do let var = LMGlobalVar label (LMPointer ty') - ExternallyVisible Nothing Nothing + ExternallyVisible Nothing Nothing False (v1, s1) <- doExpr lmty $ Cast LM_Ptrtoint var llvmWord return (env, v1, unitOL s1, []) @@ -894,26 +894,26 @@ funEpilogue = do -- with foreign functions. getHsFunc :: LlvmEnv -> CLabel -> UniqSM ExprData getHsFunc env lbl - = let fname = strCLabel_llvm lbl - ty = funLookup fname env + = let fn = strCLabel_llvm lbl + ty = funLookup fn env in case ty of Just ty'@(LMFunction sig) -> do -- Function in module in right form - let fun = LMGlobalVar fname ty' (funcLinkage sig) Nothing Nothing + let fun = LMGlobalVar fn ty' (funcLinkage sig) Nothing Nothing False return (env, fun, nilOL, []) Just ty' -> do -- label in module but not function pointer, convert - let fun = LMGlobalVar fname (pLift ty') ExternallyVisible - Nothing Nothing + let fun = LMGlobalVar fn (pLift ty') ExternallyVisible + Nothing Nothing False (v1, s1) <- doExpr (pLift llvmFunTy) $ Cast LM_Bitcast fun (pLift llvmFunTy) return (env, v1, unitOL s1, []) Nothing -> do -- label not in module, create external reference let ty' = LMFunction $ llvmFunSig lbl ExternallyVisible - let fun = LMGlobalVar fname ty' ExternallyVisible Nothing Nothing + let fun = LMGlobalVar fn ty' ExternallyVisible Nothing Nothing False let top = CmmData Data [([],[ty'])] - let env' = funInsert fname ty' env + let env' = funInsert fn ty' env return (env', fun, nilOL, [top]) diff --git a/compiler/llvmGen/LlvmCodeGen/Data.hs b/compiler/llvmGen/LlvmCodeGen/Data.hs index 13da03b840..3cf6cdac85 100644 --- a/compiler/llvmGen/LlvmCodeGen/Data.hs +++ b/compiler/llvmGen/LlvmCodeGen/Data.hs @@ -37,8 +37,8 @@ structStr = fsLit "_struct" -- complete this completely though as we need to pass all CmmStatic -- sections before all references can be resolved. This last step is -- done by 'resolveLlvmData'. -genLlvmData :: [CmmStatic] -> LlvmUnresData -genLlvmData (CmmDataLabel lbl:xs) = +genLlvmData :: (Section, [CmmStatic]) -> LlvmUnresData +genLlvmData (sec, CmmDataLabel lbl:xs) = let static = map genData xs label = strCLabel_llvm lbl @@ -48,10 +48,11 @@ genLlvmData (CmmDataLabel lbl:xs) = strucTy = LMStruct types alias = LMAlias (label `appendFS` structStr) strucTy - in (lbl, alias, static) + in (lbl, sec, alias, static) genLlvmData _ = panic "genLlvmData: CmmData section doesn't start with label!" + resolveLlvmDatas :: LlvmEnv -> [LlvmUnresData] -> [LlvmData] -> (LlvmEnv, [LlvmData]) resolveLlvmDatas env [] ldata @@ -63,17 +64,29 @@ resolveLlvmDatas env (udata : rest) ldata -- | Fix up CLabel references now that we should have passed all CmmData. resolveLlvmData :: LlvmEnv -> LlvmUnresData -> (LlvmEnv, LlvmData) -resolveLlvmData env (lbl, alias, unres) = +resolveLlvmData env (lbl, sec, alias, unres) = let (env', static, refs) = resDatas env unres ([], []) refs' = catMaybes refs struct = Just $ LMStaticStruc static alias label = strCLabel_llvm lbl link = if (externallyVisibleCLabel lbl) then ExternallyVisible else Internal - glob = LMGlobalVar label alias link Nothing Nothing + const = isSecConstant sec + glob = LMGlobalVar label alias link Nothing Nothing const in (env', (refs' ++ [(glob, struct)], [alias])) +-- | Should a data in this section be considered constant +isSecConstant :: Section -> Bool +isSecConstant Text = True +isSecConstant Data = False +isSecConstant ReadOnlyData = True +isSecConstant RelocatableReadOnlyData = True +isSecConstant UninitialisedData = False +isSecConstant ReadOnlyData16 = True +isSecConstant (OtherSection _) = False + + -- ---------------------------------------------------------------------------- -- ** Resolve Data/CLabel references -- @@ -114,7 +127,7 @@ resData env (Left cmm@(CmmLabel l)) = -- pointer to it. Just ty' -> let var = LMGlobalVar label (LMPointer ty') - ExternallyVisible Nothing Nothing + ExternallyVisible Nothing Nothing False ptr = LMStaticPointer var in (env, LMPtoI ptr lmty, [Nothing]) diff --git a/compiler/llvmGen/LlvmCodeGen/Ppr.hs b/compiler/llvmGen/LlvmCodeGen/Ppr.hs index 5afbd174ce..55bb5d04a9 100644 --- a/compiler/llvmGen/LlvmCodeGen/Ppr.hs +++ b/compiler/llvmGen/LlvmCodeGen/Ppr.hs @@ -59,6 +59,17 @@ pprLlvmHeader :: Doc pprLlvmHeader = moduleLayout +-- | Pretty print LLVM data code +pprLlvmData :: LlvmData -> Doc +pprLlvmData (globals, types) = + let tryConst (v, Just s ) = ppLlvmGlobal (v, Just s) + tryConst g@(_, Nothing) = ppLlvmGlobal g + + types' = ppLlvmTypes types + globals' = vcat $ map tryConst globals + in types' $+$ globals' + + -- | Pretty print LLVM code pprLlvmCmmTop :: LlvmEnv -> Int -> LlvmCmmTop -> (Doc, [LlvmVar]) pprLlvmCmmTop _ _ (CmmData _ lmdata) @@ -85,24 +96,16 @@ pprLlvmCmmTop env count (CmmProc info lbl _ (ListGraph blks)) ), ivar) --- | Pretty print LLVM data code -pprLlvmData :: LlvmData -> Doc -pprLlvmData (globals, types) = - let globals' = ppLlvmGlobals globals - types' = ppLlvmTypes types - in types' $+$ globals' - - -- | Pretty print CmmStatic pprCmmStatic :: LlvmEnv -> Int -> [CmmStatic] -> (Doc, [LlvmVar]) pprCmmStatic env count stat - = let unres = genLlvmData stat + = let unres = genLlvmData (Text, stat) (_, (ldata, ltypes)) = resolveLlvmData env unres - setSection (gv@(LMGlobalVar s ty l _ _), d) + setSection (gv@(LMGlobalVar s ty l _ _ c), d) = let v = if l == Internal then [gv] else [] sec = mkLayoutSection count - in ((LMGlobalVar s ty l sec llvmInfAlign, d), v) + in ((LMGlobalVar s ty l sec llvmInfAlign c, d), v) setSection v = (v,[]) (ldata', llvmUsed) = mapAndUnzip setSection ldata |