[commit: ghc] wip/kavon-llvm-improve: proposed patch for T14251 (800ecdb)
git at git.haskell.org
git at git.haskell.org
Fri Sep 28 00:05:06 UTC 2018
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/kavon-llvm-improve
Link : http://ghc.haskell.org/trac/ghc/changeset/800ecdb5badd0968b8422b7ab23fa404fdc55ece/ghc
>---------------------------------------------------------------
commit 800ecdb5badd0968b8422b7ab23fa404fdc55ece
Author: Kavon Farvardin <kavon at farvard.in>
Date: Thu Sep 27 18:56:17 2018 -0500
proposed patch for T14251
>---------------------------------------------------------------
800ecdb5badd0968b8422b7ab23fa404fdc55ece
compiler/llvmGen/LlvmCodeGen/Base.hs | 66 ++++++++++++++++++++++++++++-----
compiler/llvmGen/LlvmCodeGen/CodeGen.hs | 15 +++++---
2 files changed, 67 insertions(+), 14 deletions(-)
diff --git a/compiler/llvmGen/LlvmCodeGen/Base.hs b/compiler/llvmGen/LlvmCodeGen/Base.hs
index 6e20da4..0e3e1b9 100644
--- a/compiler/llvmGen/LlvmCodeGen/Base.hs
+++ b/compiler/llvmGen/LlvmCodeGen/Base.hs
@@ -26,7 +26,7 @@ module LlvmCodeGen.Base (
cmmToLlvmType, widthToLlvmFloat, widthToLlvmInt, llvmFunTy,
llvmFunSig, llvmFunArgs, llvmStdFunAttrs, llvmFunAlign, llvmInfAlign,
- llvmPtrBits, tysToParams, llvmFunSection,
+ llvmPtrBits, tysToParams, llvmFunSection, padLiveArgs, sortSSERegs,
strCLabel_llvm, strDisplayName_llvm, strProcedureName_llvm,
getGlobalPtr, generateExternDecls,
@@ -58,6 +58,7 @@ import ErrUtils
import qualified Stream
import Control.Monad (ap)
+import Data.List (sortBy)
-- ----------------------------------------------------------------------------
-- * Some Data Types
@@ -147,16 +148,63 @@ llvmFunSection dflags lbl
-- | A Function's arguments
llvmFunArgs :: DynFlags -> LiveGlobalRegs -> [LlvmVar]
llvmFunArgs dflags live =
- map (lmGlobalRegArg dflags) (filter isPassed (activeStgRegs platform))
+ map (lmGlobalRegArg dflags) (filter isPassed allRegs)
where platform = targetPlatform dflags
- isLive r = not (isSSE r) || r `elem` alwaysLive || r `elem` live
+ allRegs = sortSSERegs $ activeStgRegs platform
+ paddedLive = map (\(_,r) -> r) $ padLiveArgs live
+ isLive r = not (isSSE r) || r `elem` alwaysLive || r `elem` paddedLive
isPassed r = not (isSSE r) || isLive r
- isSSE (FloatReg _) = True
- isSSE (DoubleReg _) = True
- isSSE (XmmReg _) = True
- isSSE (YmmReg _) = True
- isSSE (ZmmReg _) = True
- isSSE _ = False
+ isSSE r
+ | Just _ <- sseRegNum r = True
+ | otherwise = False
+
+
+sseRegNum :: GlobalReg -> Maybe Int
+sseRegNum (FloatReg i) = Just i
+sseRegNum (DoubleReg i) = Just i
+sseRegNum (XmmReg i) = Just i
+sseRegNum (YmmReg i) = Just i
+sseRegNum (ZmmReg i) = Just i
+sseRegNum _ = Nothing
+
+-- Only sorts regs that will end up in SSE registers
+-- such that the ones which are assigned to the same
+-- register will be adjacent in the list. Other elements
+-- are not reordered.
+sortSSERegs :: [GlobalReg] -> [GlobalReg]
+sortSSERegs regs = sortBy sseOrd regs
+ where
+ sseOrd a b = case (sseRegNum a, sseRegNum b) of
+ (Just x, Just y) -> compare x y
+ _ -> EQ
+
+-- assumes that the live list is sorted by Ord GlobalReg's compare function.
+-- the bool indicates whether the global reg was added as padding.
+padLiveArgs :: LiveGlobalRegs -> [(Bool, GlobalReg)]
+padLiveArgs live = reverse padded
+ where
+ (_, padded) = foldl assignSlots (1, []) $ sortSSERegs live
+
+ assignSlots (i, acc) r
+ | Just k <- sseRegNum r
+ , i < k
+ = let -- add k-i slots of padding
+ diff = k-i
+ acc' = genPad i diff ++ (False, r) : acc
+ i' = i + diff
+ in
+ (i', acc')
+
+ | otherwise = (i, (False, r):acc)
+
+ genPad start n =
+ take n $ flip map (iterate (+1) start) (\i ->
+ (True, FloatReg i))
+ -- FIXME: perhaps we should obtain the original type,
+ -- instead of just picking Float here? It should be fine
+ -- since this argument is not live anyways,
+ -- and Float aliases with all the other F/D regs.
+
-- | Llvm standard fun attributes
llvmStdFunAttrs :: [LlvmFuncAttr]
diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
index 3a56b33..9159493 100644
--- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
+++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
@@ -1815,8 +1815,10 @@ funPrologue live cmmBlocks = do
funEpilogue :: LiveGlobalRegs -> LlvmM ([LlvmVar], LlvmStatements)
funEpilogue live = do
- -- Have information and liveness optimisation is enabled?
- let liveRegs = alwaysLive ++ live
+ -- the bool indicates whether the register is padding.
+ let alwaysNeeded = map (\r -> (False, r)) alwaysLive
+ livePadded = alwaysNeeded ++ padLiveArgs live
+
isSSE (FloatReg _) = True
isSSE (DoubleReg _) = True
isSSE (XmmReg _) = True
@@ -1834,9 +1836,12 @@ funEpilogue live = do
let ty = (pLower . getVarType $ lmGlobalRegVar dflags r)
return (Just $ LMLitVar $ LMUndefLit ty, nilOL)
platform <- getDynFlag targetPlatform
- loads <- flip mapM (activeStgRegs platform) $ \r -> case () of
- _ | r `elem` liveRegs -> loadExpr r
- | not (isSSE r) -> loadUndef r
+ let allRegs = sortSSERegs $ activeStgRegs platform
+ loads <- flip mapM allRegs $ \r -> case () of
+ _ | (False, r) `elem` livePadded
+ -> loadExpr r -- if r is not padding, load it
+ | not (isSSE r) || (True, r) `elem` livePadded
+ -> loadUndef r
| otherwise -> return (Nothing, nilOL)
let (vars, stmts) = unzip loads
More information about the ghc-commits
mailing list