[commit: ghc] wip/kavon-nosplit-llvm: working on doReturnTo; not much left in there (0bf8300)

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


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

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

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

commit 0bf83005a3df90869c97dabc078c4ff592ba6adc
Author: Kavon Farvardin <kavon at farvard.in>
Date:   Wed May 17 18:44:20 2017 +0100

    working on doReturnTo; not much left in there


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

0bf83005a3df90869c97dabc078c4ff592ba6adc
 compiler/llvmGen/LlvmCodeGen/CodeGen.hs | 53 +++++++++++++++++++++++++--------
 compiler/llvmGen/LlvmCodeGen/Regs.hs    |  2 +-
 2 files changed, 41 insertions(+), 14 deletions(-)

diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
index 65e5a1f..204f2ef 100644
--- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
+++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
@@ -38,8 +38,9 @@ import Control.Monad.Trans.Writer
 import Data.Semigroup   ( Semigroup )
 import qualified Data.Semigroup as Semigroup
 #endif
-import Data.List ( nub )
+import Data.List ( nub, mapAccumL )
 import Data.Maybe ( catMaybes )
+import Control.Monad ( foldM )
 
 type Atomic = Bool
 type LlvmStatements = OrdList LlvmStatement
@@ -136,8 +137,9 @@ stmtToInstrs stmt = case stmt of
     CmmCall { cml_target = arg,
               cml_args_regs = live,
               cml_cont = Just cont,
-              cml_args = argOffset } -> 
-                genNativeCall (Just (cont, argOffset)) arg live
+              cml_args = argOffset,
+              cml_ret_regs = retRegs } -> 
+                genNativeCall (Just (cont, argOffset, retRegs)) arg live
 
     _ -> panic "Llvm.CodeGen.stmtToInstrs"
 
@@ -767,8 +769,12 @@ cmmPrimOpFunctions mop = do
     MO_AtomicWrite _ -> unsupported
     MO_Cmpxchg _     -> unsupported
 
+
+-- block, arg byte off, return regs (not including Sp, etc)
+type ContInfo = (Label, Int, [GlobalReg]) 
+
 -- | Native function calls. First arg indicates whether there is a continuation.
-genNativeCall :: Maybe (Label, Int) -> CmmExpr -> [GlobalReg] -> LlvmM StmtData
+genNativeCall :: Maybe ContInfo -> CmmExpr -> [GlobalReg] -> LlvmM StmtData
 
 -- Native call to a known function
 genNativeCall maybeCont (CmmLit (CmmLabel lbl)) live = do
@@ -783,10 +789,10 @@ genNativeCall maybeCont (CmmLit (CmmLabel lbl)) live = do
             return (stmts `appOL` stgStmts `snocOL` s1 `snocOL` s2, top)
             
         -- non-tail call to a known fun
-        Just (cont, offset) -> do 
+        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 cont retV
+            endStms <- doReturnTo contInfo retV
             return (stmts `appOL` stgStmts `snocOL` s1 `appOL` endStms, top)
     
 -- Tail call to unknown function / address. TODO: check if the expr is P64[Sp] to gen a ret.
@@ -810,13 +816,34 @@ genNativeCall _ expr live = do
     return (stmts `snocOL` s1 `appOL` stgStmts `snocOL` s2 `snocOL` s3,
             top)
             
-doReturnTo :: Label -> LlvmVar -> LlvmM (OrdList LlvmStatement)
-doReturnTo cont retV = panic "handleReturn"
-    -- TODO: we need to know the [GlobalReg] that are live in the continuation,
-    -- aka, what values did the call return?
-    -- todo: extract vals
-    -- todo store vals into reg allocas
-    -- emit a branch
+            
+doReturnTo :: ContInfo -> LlvmVar -> LlvmM LlvmStatements
+doReturnTo (retl, off, retRegs) llRetV = do
+    -- find the struct fields corresponding to each live register 
+    -- according to the return convention.
+    platform <- getDynFlag targetPlatform
+    let regOrder = activeStgRegs platform
+        live = alwaysLive ++ retRegs
+        liveRegs = filter (\x -> x `elem` live) regOrder
+        withIdx i x = (i+1, (x, i))
+        (_, retConv) = mapAccumL withIdx 0 liveRegs
+        
+        -- for each (GlobalReg, Int), we will add to the stms an extract
+        -- from llRetV followed by a store to the alloca backing the reg
+        extract stms (reg, i) = do
+            regAlloca <- getCmmReg $ CmmGlobal reg
+            let (LMPointer ty) = getVarType regAlloca
+            (newVal, s1) <- doExpr ty $ ExtractV llRetV i
+            let s2 = Store newVal regAlloca
+            return (stms `snocOL` s1 `snocOL` s2)
+    
+    -- extract the regs from the struct and update their allocas
+    updateStms <- foldM extract nilOL retConv
+    
+    -- TODO make a branch instr
+
+    -- TODO combine all the LlvmStatements together and return them.
+    return updateStms
 
 
 -- | CmmAssign operation
diff --git a/compiler/llvmGen/LlvmCodeGen/Regs.hs b/compiler/llvmGen/LlvmCodeGen/Regs.hs
index e09ab80..539b2bb 100644
--- a/compiler/llvmGen/LlvmCodeGen/Regs.hs
+++ b/compiler/llvmGen/LlvmCodeGen/Regs.hs
@@ -103,7 +103,7 @@ stgTBAA
     , (heapN,  fsLit "heap",  Just topN)
     , (rxN,    fsLit "rx",    Just heapN)
     , (baseN,  fsLit "base",  Just topN)
-    -- FIX: Not 100% sure if this hierarchy is complete.  I think the big thing
+    -- FIXME(kavon): Not 100% sure if this hierarchy is complete.  I think the big thing
     -- is Sp is never aliased, so might want to change the hierarchy to have Sp
     -- on its own branch that is never aliased (e.g never use top as a TBAA
     -- node).



More information about the ghc-commits mailing list