[commit: ghc] wip/kavon-nosplit-llvm: partial fix for type error with SSE reg values (5994a51)

git at git.haskell.org git at git.haskell.org
Tue Jun 27 09:16:44 UTC 2017


Repository : ssh://git@git.haskell.org/ghc

On branch  : wip/kavon-nosplit-llvm
Link       : http://ghc.haskell.org/trac/ghc/changeset/5994a511c8ae406c09c2d7c95b75344de4b5292c/ghc

>---------------------------------------------------------------

commit 5994a511c8ae406c09c2d7c95b75344de4b5292c
Author: Kavon Farvardin <kavon at farvard.in>
Date:   Fri Jun 9 17:35:52 2017 +0100

    partial fix for type error with SSE reg values


>---------------------------------------------------------------

5994a511c8ae406c09c2d7c95b75344de4b5292c
 compiler/llvmGen/LlvmCodeGen/Base.hs    | 42 +++++++++++++++++++++++----------
 compiler/llvmGen/LlvmCodeGen/CodeGen.hs |  5 ++--
 2 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/compiler/llvmGen/LlvmCodeGen/Base.hs b/compiler/llvmGen/LlvmCodeGen/Base.hs
index d34aaed..14e9ca2 100644
--- a/compiler/llvmGen/LlvmCodeGen/Base.hs
+++ b/compiler/llvmGen/LlvmCodeGen/Base.hs
@@ -27,6 +27,7 @@ module LlvmCodeGen.Base (
         cmmToLlvmType, widthToLlvmFloat, widthToLlvmInt, llvmFunTy,
         llvmFunSig, llvmFunArgs, llvmStdFunAttrs, llvmFunAlign, llvmInfAlign,
         llvmPtrBits, tysToParams, llvmFunSection, llvmStdConv, llvmStdFunDefAttrs,
+        llvmStdRetConv,
 
         strCLabel_llvm, strDisplayName_llvm, strProcedureName_llvm,
         getGlobalPtr, generateExternDecls,
@@ -125,10 +126,13 @@ llvmFunSig' live lbl link
                       | otherwise   = (x, [])
        dflags <- getDynFlags
        -- the standard set of argument types passed/returned.
-       let stdConvention = map getVarType (llvmFunArgs dflags live)
-       let retTy = LMStructU $ stdConvention -- TODO(kavon): introduce a type alias to reduce bytes output
+       let regToTy = getVarType . (lmGlobalRegArg dflags)
+           callConv = map getVarType (llvmFunArgs dflags live)
+           retConv = map regToTy (llvmStdRetConv dflags)
+       -- TODO(kavon): introduce a type alias for the ret struct to reduce bytes output
+           retTy = LMStructU $ retConv
        return $ LlvmFunctionDecl lbl link (llvmGhcCC dflags) retTy FixedArgs
-                                 (map toParams stdConvention)
+                                 (map toParams callConv)
                                  (llvmFunAlign dflags)
 
 -- | Alignment to use for functions
@@ -146,19 +150,33 @@ llvmFunSection dflags lbl
     | otherwise                     = Nothing
 
 -- | The full set of Cmm registers passed to a function, in the correct order,
---   given the live argument registers. This is used for both call and return.
+--   given the live argument registers.
 llvmStdConv :: DynFlags -> LiveGlobalRegs -> [GlobalReg]
 llvmStdConv dflags live = 
     filter isPassed (activeStgRegs platform)
     where platform = targetPlatform dflags
-          isLive r = not (isSSE r) || r `elem` alwaysLive || r `elem` live
-          isPassed r = not (isSSE r) || isLive r
-          isSSE (FloatReg _)  = True
-          isSSE (DoubleReg _) = True
-          isSSE (XmmReg _)    = True
-          isSSE (YmmReg _)    = True
-          isSSE (ZmmReg _)    = True
-          isSSE _             = False
+          isLive r = r `elem` alwaysLive || r `elem` live
+          isPassed r = not (isFloatReg r || isVectorReg r) || isLive r
+          
+-- | The full set of Cmm registers returned from a function, in the correct order.
+llvmStdRetConv :: DynFlags -> [GlobalReg]
+llvmStdRetConv dflags = 
+    -- NB: the return type of all LLVM fuctions must match up for tail-call optimization,
+    --     so we pick a safe superset of all return types here.
+    filter isPassed (activeStgRegs platform)
+    where platform = targetPlatform dflags
+          isPassed r = not $ isVectorReg r -- TODO(kavon): I see no reason why we can't return a vector reg
+          
+isFloatReg :: GlobalReg -> Bool
+isFloatReg (FloatReg _)  = True
+isFloatReg (DoubleReg _) = True
+isFloatReg _             = False
+          
+isVectorReg :: GlobalReg -> Bool
+isVectorReg (XmmReg _) = True
+isVectorReg (YmmReg _) = True
+isVectorReg (ZmmReg _) = True
+isVectorReg _          = False
 
 -- | A Function's arguments
 llvmFunArgs :: DynFlags -> LiveGlobalRegs -> [LlvmVar]
diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
index eee57a3..ab09516 100644
--- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
+++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
@@ -865,8 +865,9 @@ doReturnTo (retl, _, retArgs) llRetV = do
         -- we could avoid emitting those extracts by slimming down the retRegs list.
         
         -- retRegs is a subset of allRegs, with the _same relative ordering_
-        retRegs = llvmStdConv dflags retArgs
-        allRegs = activeStgRegs $ targetPlatform dflags
+        allRegs = llvmStdRetConv dflags
+        isPassed r = r `elem` retArgs || r `elem` alwaysLive
+        retRegs = filter isPassed allRegs
         
         extract (z@(_, [], _)) _ = return z -- no more slots needed
         extract (i, x:xs, stms) reg



More information about the ghc-commits mailing list