[commit: ghc] wip/kavon-nosplit-llvm: native calls are done (639178f)

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


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

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

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

commit 639178f62bae716a7369996d48d4341dcf68b8bc
Author: Kavon Farvardin <kavon at farvard.in>
Date:   Fri May 19 13:58:35 2017 +0100

    native calls are done


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

639178f62bae716a7369996d48d4341dcf68b8bc
 compiler/llvmGen/LlvmCodeGen/CodeGen.hs | 58 ++++++++++++++++++++++++++-------
 1 file changed, 47 insertions(+), 11 deletions(-)

diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
index 13f7258..506ed72 100644
--- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
+++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
@@ -776,27 +776,32 @@ type ContInfo = (Label, Int, [GlobalReg])
 -- | Native function calls. First arg indicates whether there is a continuation.
 genNativeCall :: Maybe ContInfo -> CmmExpr -> [GlobalReg] -> LlvmM StmtData
 
+-- FIXME(kavon): the only difference I can see between these two cases is
+-- whether we need to cast the function pointer or not. We could combine the
+-- two cases of this function otherwise.
+
 -- Native call to a known function 
 genNativeCall maybeCont (CmmLit (CmmLabel lbl)) live = do
+    dflags <- getDynFlags
     (vf, stmts, top) <- getHsFunc live lbl
     (stgRegs, stgStmts) <- funEpilogue live
     let retTy = getRetTy $ getVarType vf
+        before = stmts `appOL` stgStmts
     case maybeCont of
         -- tail call to a known fun
         Nothing -> do 
             (retV, s1) <- doExpr retTy $ Call TailCall vf stgRegs llvmStdFunAttrs
             let s2  = Return (Just retV)
-            return (stmts `appOL` stgStmts `snocOL` s1 `snocOL` s2, top)
+            return (before `snocOL` s1 `snocOL` s2, top)
             
         -- non-tail call to a known fun
         Just contInfo -> do
-            -- TODO add metadata to this StdCall with the offset and label name
-            (retV, s1) <- doExpr retTy $ Call StdCall vf stgRegs llvmStdFunAttrs
-            endStms <- doReturnTo contInfo retV
-            return (stmts `appOL` stgStmts `snocOL` s1 `appOL` endStms, top)
+            after <- mkNonTailCall dflags contInfo retTy vf stgRegs
+            return (before `appOL` after, top)
+            
     
--- Tail call to unknown function / address. TODO: check if the expr is P64[Sp] to gen a ret.
-genNativeCall _ expr live = do
+-- Native call to unknown function / address.
+genNativeCall maybeCont expr live = do
     fty <- llvmFunTy live
     (vf, stmts, top) <- exprToVar expr
     dflags <- getDynFlags
@@ -811,10 +816,41 @@ genNativeCall _ expr live = do
     (v1, s1) <- doExpr (pLift fty) $ Cast cast vf (pLift fty)
     (stgRegs, stgStmts) <- funEpilogue live
     let retTy = getRetTy fty
-    (retV, s2) <- doExpr retTy $ Call TailCall v1 stgRegs llvmStdFunAttrs
-    let s3 = Return (Just retV)
-    return (stmts `snocOL` s1 `appOL` stgStmts `snocOL` s2 `snocOL` s3,
-            top)
+        before = stmts `snocOL` s1 `appOL` stgStmts
+    case maybeCont of
+        Nothing -> do
+            (retV, s2) <- doExpr retTy $ Call TailCall v1 stgRegs llvmStdFunAttrs
+            let s3 = Return (Just retV)
+            return (before `snocOL` s2 `snocOL` s3,
+                top)
+        Just contInfo -> do
+            after <- mkNonTailCall dflags contInfo retTy v1 stgRegs
+            return (before `appOL` after, top)
+             
+mkNonTailCall :: DynFlags -> ContInfo -> LlvmType -> LlvmVar -> [LlvmVar] -> LlvmM LlvmStatements
+mkNonTailCall dflags contInfo retTy vf stgRegs = do
+    (retV, callStm) <- doExpr retTy $ Call StdCall vf stgRegs llvmStdFunAttrs
+    let s1 = withReturnMeta dflags contInfo callStm
+    endStms <- doReturnTo contInfo retV
+    return $ s1 `consOL` endStms
+            
+cps_retpt :: LMString
+cps_retpt = fsLit "cps.retpt" 
+            
+withReturnMeta :: DynFlags -> ContInfo -> LlvmStatement -> LlvmStatement
+withReturnMeta dflags (retl, argOff, _) stm = let 
+        -- some unique name for the mangler corresponding to retl
+        name = MetaStr $ fsLit "todo" -- TODO(kavon)
+        
+        -- offset into the Sp where the return address should be written
+        wordBytes = widthInBytes $ wordWidth dflags
+        offInt = argOff - wordBytes
+        off = MetaStr $ mkFastString $ show offInt
+        
+        expr = MetaStruct [name, off]
+    in
+        MetaStmt [MetaAnnot cps_retpt expr] stm
+    
             
             
 doReturnTo :: ContInfo -> LlvmVar -> LlvmM LlvmStatements



More information about the ghc-commits mailing list