[commit: ghc] wip/kavon-nosplit-llvm: changing funTy so that it returns something. for now it's just a float (ec29bf7)

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


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

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

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

commit ec29bf7e60a5b5f54fcdb5d21a341ca00118eeb3
Author: Kavon Farvardin <kavon at farvard.in>
Date:   Mon May 15 15:43:17 2017 +0100

    changing funTy so that it returns something. for now it's just a float


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

ec29bf7e60a5b5f54fcdb5d21a341ca00118eeb3
 compiler/llvmGen/Llvm.hs                |  3 +--
 compiler/llvmGen/Llvm/Types.hs          |  6 +++++
 compiler/llvmGen/LlvmCodeGen/Base.hs    |  3 ++-
 compiler/llvmGen/LlvmCodeGen/CodeGen.hs | 43 +++++++++++++++++++++------------
 4 files changed, 36 insertions(+), 19 deletions(-)

diff --git a/compiler/llvmGen/Llvm.hs b/compiler/llvmGen/Llvm.hs
index 8104a3a..796c5fc 100644
--- a/compiler/llvmGen/Llvm.hs
+++ b/compiler/llvmGen/Llvm.hs
@@ -45,7 +45,7 @@ module Llvm (
         MetaExpr(..), MetaAnnot(..), MetaDecl(..), MetaId(..),
 
         -- ** Operations on the type system.
-        isGlobal, getLitType, getVarType,
+        isGlobal, getLitType, getVarType, getRetTy,
         getLink, getStatType, pVarLift, pVarLower,
         pLift, pLower, isInt, isFloat, isPointer, isVector, llvmWidthInBits,
 
@@ -61,4 +61,3 @@ import Llvm.AbsSyn
 import Llvm.MetaData
 import Llvm.PpLlvm
 import Llvm.Types
-
diff --git a/compiler/llvmGen/Llvm/Types.hs b/compiler/llvmGen/Llvm/Types.hs
index bf23cd8..6245642 100644
--- a/compiler/llvmGen/Llvm/Types.hs
+++ b/compiler/llvmGen/Llvm/Types.hs
@@ -267,6 +267,12 @@ getLitType (LMVectorLit ls)  = LMVector (length ls) (getLitType (head ls))
 getLitType (LMNullLit    t) = t
 getLitType (LMUndefLit   t) = t
 
+-- | Return the return type of the given function or function pointer type
+getRetTy :: LlvmType -> LlvmType
+getRetTy (LMFunction(LlvmFunctionDecl{decReturnType = t})) = t
+getRetTy (LMPointer(LMFunction(LlvmFunctionDecl{decReturnType = t}))) = t
+getRetTy _ = panic "getRetTy -- not a function or function pointer!"
+
 -- | Return the 'LlvmType' of the 'LlvmStatic'
 getStatType :: LlvmStatic -> LlvmType
 getStatType (LMStaticLit   l  ) = getLitType l
diff --git a/compiler/llvmGen/LlvmCodeGen/Base.hs b/compiler/llvmGen/LlvmCodeGen/Base.hs
index 424891f..8b01da8 100644
--- a/compiler/llvmGen/LlvmCodeGen/Base.hs
+++ b/compiler/llvmGen/LlvmCodeGen/Base.hs
@@ -124,7 +124,8 @@ llvmFunSig' live lbl link
   = do let toParams x | isPointer x = (x, [NoAlias, NoCapture])
                       | otherwise   = (x, [])
        dflags <- getDynFlags
-       return $ LlvmFunctionDecl lbl link (llvmGhcCC dflags) LMVoid FixedArgs
+       let retTy = LMFloat -- TODO: generate the struct that we will return.
+       return $ LlvmFunctionDecl lbl link (llvmGhcCC dflags) retTy FixedArgs
                                  (map (toParams . getVarType) (llvmFunArgs dflags live))
                                  (llvmFunAlign dflags)
 
diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
index 43690e9..97042a6 100644
--- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
+++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs
@@ -126,12 +126,18 @@ stmtToInstrs stmt = case stmt of
     CmmUnsafeForeignCall target res args
         -> genCall target res args
 
-    -- Cmm call
+    -- Cmm tail call
     CmmCall { cml_target = arg,
               cml_args_regs = live,
-              cml_cont = maybeCont } -> case maybeCont of
-                Nothing -> genJump arg live -- Tail call
-                Just cont -> panic "todo: handle non-tail CmmCall"
+              cml_cont = Nothing } -> 
+                genNativeCall Nothing arg live
+                
+    -- Cmm non-tail call
+    CmmCall { cml_target = arg,
+              cml_args_regs = live,
+              cml_cont = Just cont,
+              cml_args = argOffset } -> 
+                genNativeCall (Just (cont, argOffset)) arg live
 
     _ -> panic "Llvm.CodeGen.stmtToInstrs"
 
@@ -761,20 +767,24 @@ cmmPrimOpFunctions mop = do
     MO_AtomicWrite _ -> unsupported
     MO_Cmpxchg _     -> unsupported
 
--- | Tail function calls
-genJump :: CmmExpr -> [GlobalReg] -> LlvmM StmtData
+-- | Native function calls. First arg indicates whether there is a continuation.
+genNativeCall :: Maybe (Label, Int) -> CmmExpr -> [GlobalReg] -> LlvmM StmtData
 
--- Call to known function
-genJump (CmmLit (CmmLabel lbl)) live = do
+-- Native call to a known function
+genNativeCall maybeCont (CmmLit (CmmLabel lbl)) live = do
     (vf, stmts, top) <- getHsFunc live lbl
     (stgRegs, stgStmts) <- funEpilogue live
-    let s1  = Expr $ Call TailCall vf stgRegs llvmStdFunAttrs
-    let s2  = Return Nothing
-    return (stmts `appOL` stgStmts `snocOL` s1 `snocOL` s2, top)
+    let retTy = getRetTy $ getVarType vf
+    case maybeCont of
+        _ -> do -- native tail call
+            (retV, s1) <- doExpr retTy $ Call TailCall vf stgRegs llvmStdFunAttrs
+            let s2  = Return (Just retV)
+            return (stmts `appOL` stgStmts `snocOL` s1 `snocOL` s2, top)
         
+        -- Just (cont, offset) -> panic "kavon, handle non-tail known calls."
     
--- Call to unknown function / address
-genJump expr live = do
+-- Tail call to unknown function / address. TODO: check if the expr is P64[Sp] to gen a ret.
+genNativeCall _ expr live = do
     fty <- llvmFunTy live
     (vf, stmts, top) <- exprToVar expr
     dflags <- getDynFlags
@@ -783,13 +793,14 @@ genJump expr live = do
          ty | isPointer ty -> LM_Bitcast
          ty | isInt ty     -> LM_Inttoptr
 
-         ty -> panic $ "genJump: Expr is of bad type for function call! ("
+         ty -> panic $ "genNativeCall: Expr is of bad type for function call! ("
                      ++ showSDoc dflags (ppr ty) ++ ")"
 
     (v1, s1) <- doExpr (pLift fty) $ Cast cast vf (pLift fty)
     (stgRegs, stgStmts) <- funEpilogue live
-    let s2 = Expr $ Call TailCall v1 stgRegs llvmStdFunAttrs
-    let s3 = Return Nothing
+    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)
 



More information about the ghc-commits mailing list