diff options
author | David Terei <davidterei@gmail.com> | 2011-12-02 15:48:43 -0800 |
---|---|---|
committer | David Terei <davidterei@gmail.com> | 2011-12-03 20:48:22 -0800 |
commit | 7626b2b9c52cb4aa38609a9a70b567e8693c3aa6 (patch) | |
tree | 6699daf7aa52ead5eefe21c5e89cb481dbfda7e9 /compiler/llvmGen | |
parent | f14953e7e8d0346744933b53ed6707764f2f67f5 (diff) | |
download | haskell-7626b2b9c52cb4aa38609a9a70b567e8693c3aa6.tar.gz |
Fix ugly complexity issue in LLVM backend (#5652)
Compile time still isn't as good as I'd like but no easy changes
available. LLVM backend could do with a big rewrite to improve
performance as there are some ugly designs in it.
At least the test case isn't 10min anymore, just a few seconds now.
Diffstat (limited to 'compiler/llvmGen')
-rw-r--r-- | compiler/llvmGen/LlvmCodeGen.hs | 23 | ||||
-rw-r--r-- | compiler/llvmGen/LlvmCodeGen/CodeGen.hs | 13 | ||||
-rw-r--r-- | compiler/llvmGen/LlvmCodeGen/Data.hs | 45 |
3 files changed, 39 insertions, 42 deletions
diff --git a/compiler/llvmGen/LlvmCodeGen.hs b/compiler/llvmGen/LlvmCodeGen.hs index 321fac37a8..f802fc414c 100644 --- a/compiler/llvmGen/LlvmCodeGen.hs +++ b/compiler/llvmGen/LlvmCodeGen.hs @@ -36,7 +36,8 @@ import System.IO llvmCodeGen :: DynFlags -> Handle -> UniqSupply -> [RawCmmGroup] -> IO () llvmCodeGen dflags h us cmms = let cmm = concat cmms - (cdata,env) = foldr split ([],initLlvmEnv (targetPlatform dflags)) cmm + (cdata,env) = {-# SCC "llvm_split" #-} + foldr split ([],initLlvmEnv (targetPlatform dflags)) cmm split (CmmData s d' ) (d,e) = ((s,d'):d,e) split (CmmProc i l _) (d,e) = let lbl = strCLabel_llvm env $ case i of @@ -51,7 +52,7 @@ llvmCodeGen dflags h us cmms ver <- (fromMaybe defaultLlvmVersion) `fmap` figureLlvmVersion dflags env' <- {-# SCC "llvm_datas_gen" #-} cmmDataLlvmGens dflags bufh (setLlvmVer ver env) cdata [] - _ <- {-# SCC "llvm_procs_gen" #-} + {-# SCC "llvm_procs_gen" #-} cmmProcLlvmGens dflags bufh us env' cmm 1 [] bFlush bufh return () @@ -65,19 +66,23 @@ cmmDataLlvmGens :: DynFlags -> BufHandle -> LlvmEnv -> [(Section,CmmStatics)] cmmDataLlvmGens dflags h env [] lmdata = let (env', lmdata') = {-# SCC "llvm_resolve" #-} - resolveLlvmDatas env lmdata [] + resolveLlvmDatas env lmdata lmdoc = {-# SCC "llvm_data_ppr" #-} Prt.vcat $ map pprLlvmData lmdata' in do dumpIfSet_dyn dflags Opt_D_dump_llvm "LLVM Code" $ docToSDoc lmdoc - Prt.bufLeftRender h lmdoc + {-# SCC "llvm_data_out" #-} + Prt.bufLeftRender h lmdoc return env' cmmDataLlvmGens dflags h env (cmm:cmms) lmdata - = let lmdata'@(l, _, ty, _) = {-# SCC "llvm_data_gen" #-} - genLlvmData env cmm - env' = funInsert (strCLabel_llvm env l) ty env - in cmmDataLlvmGens dflags h env' cmms (lmdata ++ [lmdata']) + = let lm@(l, _, ty, _) = {-# SCC "llvm_data_gen" #-} + genLlvmData env cmm + env' = {-# SCC "llvm_data_insert" #-} + funInsert (strCLabel_llvm env l) ty env + lmdata' = {-# SCC "llvm_data_append" #-} + lm:lmdata + in cmmDataLlvmGens dflags h env' cmms lmdata' -- ----------------------------------------------------------------------------- @@ -98,7 +103,7 @@ cmmProcLlvmGens _ h _ _ [] _ ivars usedArray = LMStaticArray (map cast ivars') ty lmUsed = (LMGlobalVar (fsLit "llvm.used") ty Appending (Just $ fsLit "llvm.metadata") Nothing False, Just usedArray) - in Prt.bufLeftRender h $ {-# SCC "llvm_data_ppr" #-} + in Prt.bufLeftRender h $ {-# SCC "llvm_used_ppr" #-} pprLlvmData ([lmUsed], []) cmmProcLlvmGens dflags h us env ((CmmData _ _) : cmms) count ivars diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs index 1ea5d0c038..5b9e711b15 100644 --- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs +++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs @@ -57,8 +57,7 @@ basicBlocksCodeGen env ([]) (blocks, tops) = do let (blocks', allocs) = mapAndUnzip dominateAllocs blocks let allocs' = concat allocs let ((BasicBlock id fstmts):rblks) = blocks' - fplog <- funPrologue - let fblocks = (BasicBlock id (fplog ++ allocs' ++ fstmts)):rblks + let fblocks = (BasicBlock id $ funPrologue ++ allocs' ++ fstmts):rblks return (env, fblocks, tops) basicBlocksCodeGen env (block:blocks) (lblocks', ltops') @@ -1189,13 +1188,13 @@ genLit _ CmmHighStackMark -- -- | Function prologue. Load STG arguments into variables for function. -funPrologue :: UniqSM [LlvmStatement] -funPrologue = liftM concat $ mapM getReg activeStgRegs +funPrologue :: [LlvmStatement] +funPrologue = concat $ map getReg activeStgRegs where getReg rr = - let reg = lmGlobalRegVar rr - arg = lmGlobalRegArg rr + let reg = lmGlobalRegVar rr + arg = lmGlobalRegArg rr alloc = Assignment reg $ Alloca (pLower $ getVarType reg) 1 - in return [alloc, Store arg reg] + in [alloc, Store arg reg] -- | Function epilogue. Load STG variables to use as argument for call. diff --git a/compiler/llvmGen/LlvmCodeGen/Data.hs b/compiler/llvmGen/LlvmCodeGen/Data.hs index c773e1c009..8e42149dce 100644 --- a/compiler/llvmGen/LlvmCodeGen/Data.hs +++ b/compiler/llvmGen/LlvmCodeGen/Data.hs @@ -18,8 +18,7 @@ import OldCmm import FastString import qualified Outputable -import Data.Maybe - +import Data.List (foldl') -- ---------------------------------------------------------------------------- -- * Constants @@ -51,37 +50,33 @@ genLlvmData env (sec, Statics lbl xs) = in (lbl, sec, alias, static) -resolveLlvmDatas :: LlvmEnv -> [LlvmUnresData] -> [LlvmData] - -> (LlvmEnv, [LlvmData]) -resolveLlvmDatas env [] ldata - = (env, ldata) - -resolveLlvmDatas env (udata : rest) ldata - = let (env', ndata) = resolveLlvmData env udata - in resolveLlvmDatas env' rest (ldata ++ [ndata]) +resolveLlvmDatas :: LlvmEnv -> [LlvmUnresData] -> (LlvmEnv, [LlvmData]) +resolveLlvmDatas env ldata + = foldl' res (env, []) ldata + where res (e, xs) ll = + let (e', nd) = resolveLlvmData e ll + in (e', nd:xs) -- | Fix up CLabel references now that we should have passed all CmmData. resolveLlvmData :: LlvmEnv -> LlvmUnresData -> (LlvmEnv, LlvmData) resolveLlvmData env (lbl, sec, alias, unres) = let (env', static, refs) = resDatas env unres ([], []) - refs' = catMaybes refs struct = Just $ LMStaticStruc static alias label = strCLabel_llvm env lbl link = if (externallyVisibleCLabel lbl) then ExternallyVisible else Internal const = isSecConstant sec glob = LMGlobalVar label alias link Nothing Nothing const - in (env', (refs' ++ [(glob, struct)], [alias])) - + in (env', ((glob,struct):refs, [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 Data = False +isSecConstant UninitialisedData = False isSecConstant (OtherSection _) = False @@ -90,13 +85,13 @@ isSecConstant (OtherSection _) = False -- -- | Resolve data list -resDatas :: LlvmEnv -> [UnresStatic] -> ([LlvmStatic], [Maybe LMGlobal]) - -> (LlvmEnv, [LlvmStatic], [Maybe LMGlobal]) +resDatas :: LlvmEnv -> [UnresStatic] -> ([LlvmStatic], [LMGlobal]) + -> (LlvmEnv, [LlvmStatic], [LMGlobal]) -resDatas env [] (stat, glob) - = (env, stat, glob) +resDatas env [] (stats, glob) + = (env, stats, glob) -resDatas env (cmm : rest) (stats, globs) +resDatas env (cmm:rest) (stats, globs) = let (env', nstat, nglob) = resData env cmm in resDatas env' rest (stats ++ [nstat], globs ++ nglob) @@ -106,9 +101,9 @@ resDatas env (cmm : rest) (stats, globs) -- module. If it has we can retrieve its type and make a pointer, otherwise -- we introduce a generic external definition for the referenced label and -- then make a pointer. -resData :: LlvmEnv -> UnresStatic -> (LlvmEnv, LlvmStatic, [Maybe LMGlobal]) +resData :: LlvmEnv -> UnresStatic -> (LlvmEnv, LlvmStatic, [LMGlobal]) -resData env (Right stat) = (env, stat, [Nothing]) +resData env (Right stat) = (env, stat, []) resData env (Left cmm@(CmmLabel l)) = let label = strCLabel_llvm env l @@ -120,14 +115,14 @@ resData env (Left cmm@(CmmLabel l)) = let glob@(var, _) = genStringLabelRef label env' = funInsert label (pLower $ getVarType var) env ptr = LMStaticPointer var - in (env', LMPtoI ptr lmty, [Just glob]) + in (env', LMPtoI ptr lmty, [glob]) -- Referenced data exists in this module, retrieve type and make -- pointer to it. Just ty' -> let var = LMGlobalVar label (LMPointer ty') ExternallyVisible Nothing Nothing False ptr = LMStaticPointer var - in (env, LMPtoI ptr lmty, [Nothing]) + in (env, LMPtoI ptr lmty, []) resData env (Left (CmmLabelOff label off)) = let (env', var, glob) = resData env (Left (CmmLabel label)) @@ -161,7 +156,6 @@ genData (CmmUninitialised bytes) genData (CmmStaticLit lit) = genStaticLit lit - -- | Generate Llvm code for a static literal. -- -- Will either generate the code or leave it unresolved if it is a 'CLabel' @@ -183,7 +177,6 @@ genStaticLit (CmmBlock b) = Left $ CmmLabel $ infoTblLbl b genStaticLit (CmmHighStackMark) = panic "genStaticLit: CmmHighStackMark unsupported!" - -- ----------------------------------------------------------------------------- -- * Misc -- |