[commit: ghc] wip/kavon-nosplit-llvm: now properly using cpscall intrinsic. need to update mangler next (5378d06)

git at git.haskell.org git at git.haskell.org
Tue Jun 27 09:15:55 UTC 2017


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

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

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

commit 5378d06eb75acabd0fec5fe3a72b1dfa7732ec9e
Author: Kavon Farvardin <kavon at farvard.in>
Date:   Thu Jun 1 16:23:44 2017 +0100

    now properly using cpscall intrinsic. need to update mangler next


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

5378d06eb75acabd0fec5fe3a72b1dfa7732ec9e
 compiler/llvmGen/Llvm/Types.hs          |  7 -----
 compiler/llvmGen/LlvmCodeGen/Base.hs    | 17 +++++++++++-
 compiler/llvmGen/LlvmCodeGen/CodeGen.hs | 47 ++++++++++++++++++++-------------
 3 files changed, 45 insertions(+), 26 deletions(-)

diff --git a/compiler/llvmGen/Llvm/Types.hs b/compiler/llvmGen/Llvm/Types.hs
index 03c404d..45c68af 100644
--- a/compiler/llvmGen/Llvm/Types.hs
+++ b/compiler/llvmGen/Llvm/Types.hs
@@ -583,13 +583,6 @@ data LlvmCallType
   = StdCall
   -- | Tail call, perform the call in the current stack frame.
   | TailCall
-  -- | A non-tail call in continuation-passing style,
-  -- which is described with the intrinsic @llvm.experimental.cpscall
-  | CPSCall {
-        info_id :: Int64,    -- an ID used by the mangler 
-        ra_off :: Int32,     -- byte offset from Sp for the return address
-        sp_argnum :: Int16   -- indicates the Sp arg passed to callee
-    }
   deriving (Eq,Show)
 
 -- | Different calling conventions a function can use.
diff --git a/compiler/llvmGen/LlvmCodeGen/Base.hs b/compiler/llvmGen/LlvmCodeGen/Base.hs
index ac49c0c..47db6c4 100644
--- a/compiler/llvmGen/LlvmCodeGen/Base.hs
+++ b/compiler/llvmGen/LlvmCodeGen/Base.hs
@@ -31,7 +31,7 @@ module LlvmCodeGen.Base (
         strCLabel_llvm, strDisplayName_llvm, strProcedureName_llvm,
         getGlobalPtr, generateExternDecls,
 
-        aliasify,
+        aliasify, cpsCallOf,
     ) where
 
 #include "HsVersions.h"
@@ -501,6 +501,21 @@ aliasify (LMGlobal var val) = do
            , LMGlobal aliasVar (Just aliasVal)
            ]
 
+cpsCallOf :: LlvmType -> LlvmType
+cpsCallOf givenFn = LMFunction $
+    LlvmFunctionDecl {
+        -- NB skipping type mangling because of current assumptions
+        decName = fsLit "llvm.experimental.cpscall.x",
+        funcLinkage = ExternallyVisible,
+        funcCc = CC_Ghc,
+        decReturnType = getRetTy givenFn,
+        decVarargs = VarArgs,
+        decParams = map noAttr [givenFn, i64, i32, i16],
+        funcAlign = Nothing
+    }
+    where
+        noAttr ty = (ty, [])
+
 -- Note [Llvm Forward References]
 --
 -- The issue here is that LLVM insists on being strongly typed at
diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
index 6353355..4b8d4ae 100644
--- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
+++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
@@ -779,8 +779,8 @@ genNativeCall :: Maybe ContInfo -> CmmExpr -> [GlobalReg] -> LlvmM StmtData
 -- Native call to a known Cmm function 
 genNativeCall maybeCont (CmmLit (CmmLabel lbl)) live = do
     (vf, stmts, top) <- getHsFunc live lbl
-    rest <- genNativeCall' maybeCont vf live
-    return (stmts `appOL` rest, top)
+    (rest, top2) <- genNativeCall' maybeCont vf live
+    return (stmts `appOL` rest, top ++ top2)
     
 -- Native call to unknown Cmm function / address.
 genNativeCall maybeCont expr live = do
@@ -796,12 +796,12 @@ genNativeCall maybeCont expr live = do
                      ++ showSDoc dflags (ppr ty) ++ ")"
                      
     (v1, s1) <- doExpr (pLift fty) $ Cast cast vf (pLift fty)
-    rest <- genNativeCall' maybeCont v1 live
-    return (stmts `snocOL` s1 `appOL` rest, top)
+    (rest, top2) <- genNativeCall' maybeCont v1 live
+    return (stmts `snocOL` s1 `appOL` rest, top ++ top2)
 
 -- now that we have the function we want to call as an LlvmVar, actually
 -- build the statements needed to do so.
-genNativeCall' :: Maybe ContInfo -> LlvmVar -> [GlobalReg] -> LlvmM LlvmStatements
+genNativeCall' :: Maybe ContInfo -> LlvmVar -> [GlobalReg] -> LlvmM StmtData
 genNativeCall' maybeCont fv live = do
     dflags <- getDynFlags
     (stgRegs, stgStmts) <- funEpilogue live
@@ -811,37 +811,48 @@ genNativeCall' maybeCont fv live = do
         Nothing -> do 
             (retV, s1) <- doExpr retTy $ Call TailCall fv stgRegs llvmStdFunAttrs
             let s2  = Return (Just retV)
-            return (stgStmts `snocOL` s1 `snocOL` s2)
+            return (stgStmts `snocOL` s1 `snocOL` s2, [])
             
         -- non-tail call
         Just contInfo -> do
-            ntCallStms <- mkNonTailCall dflags contInfo retTy fv stgRegs
-            return (stgStmts `appOL` ntCallStms)
+            (ntCallStms, top) <- mkNonTailCall dflags contInfo retTy fv stgRegs
+            return (stgStmts `appOL` ntCallStms, top)
 
 
-mkNonTailCall :: DynFlags -> ContInfo -> LlvmType -> LlvmVar -> [LlvmVar] -> LlvmM LlvmStatements
+mkNonTailCall :: DynFlags -> ContInfo -> LlvmType -> LlvmVar -> [LlvmVar] -> LlvmM StmtData
 mkNonTailCall dflags contInfo retTy vf stgRegs = do
-    let ct = getCallType dflags contInfo
-    (retV, callStm) <- doExpr retTy $ Call ct vf stgRegs llvmStdFunAttrs
+    -- fetch the intrinsic.
+    let cpscallTy @ (LMFunction decl) = cpsCallOf $ getVarType vf
+    (intFun, intStm, top) <- getInstrinct2 (decName decl) cpscallTy
+    
+    -- collect the args to the intrinsic
+    let consts = cpsCallConsts dflags contInfo
+        args = vf : consts ++ stgRegs
+    
+    (retV, callStm) <- doExpr retTy $ Call StdCall intFun args llvmStdFunAttrs
     endStms <- doReturnTo contInfo retV
-    return $ callStm `consOL` endStms
+    return (intStm `snocOL` callStm `appOL` endStms, top)
     
             
-getCallType :: DynFlags -> ContInfo -> LlvmCallType
-getCallType dflags (retl, argOff, _) = let
+cpsCallConsts :: DynFlags -> ContInfo -> [LlvmVar]
+cpsCallConsts dflags (retl, argOff, _) = let
         -- mangler will look for this unique number
-        info64 = fromIntegral $ getKey $ getUnique retl
+        info64 = toInteger $ getKey $ getUnique retl
         
         -- offset into the Sp where the return address should be written
         wordBytes = widthInBytes $ wordWidth dflags
-        ra32 = fromIntegral $ argOff - wordBytes
+        ra32 = toInteger $ argOff - wordBytes
         
         -- get argument number of Sp in our calling convention
         allRegs = activeStgRegs $ targetPlatform dflags
         Just spArgnum = elemIndex Sp allRegs
-        argnum16 = fromIntegral spArgnum
+        argnum16 = toInteger spArgnum
+        
+        mk ty val = LMLitVar $ LMIntLit val ty
     in
-        CPSCall {info_id = info64, ra_off = ra32, sp_argnum = argnum16}
+        [mk i64 info64,
+         mk i32 ra32,
+         mk i16 argnum16]
     
             
             



More information about the ghc-commits mailing list