-
-
Save kavon/566fc6c21ff51803538884b79dc1d841 to your computer and use it in GitHub Desktop.
working on T14251 so that we add padding during LLVM codegen
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/compiler/llvmGen/LlvmCodeGen/Base.hs b/compiler/llvmGen/LlvmCodeGen/Base.hs | |
index 6e20da4..e1b7e76 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,59 @@ 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)) | |
+ | |
-- | Llvm standard fun attributes | |
llvmStdFunAttrs :: [LlvmFuncAttr] | |
diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs | |
index 584d90c..6dd1fc3 100644 | |
--- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs | |
+++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs | |
@@ -1732,8 +1732,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 | |
@@ -1751,9 +1753,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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment