summaryrefslogtreecommitdiff
path: root/compiler/codeGen
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2012-08-02 15:20:44 +0100
committerSimon Marlow <marlowsd@gmail.com>2012-08-06 09:47:32 +0100
commit6228e318eabcba88c289d48287abc224fa57901d (patch)
tree240f63628f849643da0d3d8dafceeb052f8cb38c /compiler/codeGen
parent290ec750343a340d5f2cef8bf844f3822c9629e0 (diff)
downloadhaskell-6228e318eabcba88c289d48287abc224fa57901d.tar.gz
Use "ReturnedTo" when generating safe foreign calls
Diffstat (limited to 'compiler/codeGen')
-rw-r--r--compiler/codeGen/StgCmm.hs6
-rw-r--r--compiler/codeGen/StgCmmBind.hs7
-rw-r--r--compiler/codeGen/StgCmmForeign.hs33
-rw-r--r--compiler/codeGen/StgCmmMonad.hs21
4 files changed, 33 insertions, 34 deletions
diff --git a/compiler/codeGen/StgCmm.hs b/compiler/codeGen/StgCmm.hs
index d82b4bc3b1..d8127ab737 100644
--- a/compiler/codeGen/StgCmm.hs
+++ b/compiler/codeGen/StgCmm.hs
@@ -52,7 +52,7 @@ import OrdList
import MkGraph
import Data.IORef
-import Control.Monad (when)
+import Control.Monad (when,void)
import Util
codeGen :: DynFlags
@@ -244,9 +244,9 @@ cgDataCon data_con
do { _ <- ticky_code
; ldvEnter (CmmReg nodeReg)
; tickyReturnOldCon (length arg_things)
- ; _ <- emitReturn [cmmOffsetB (CmmReg nodeReg)
+ ; void $ emitReturn [cmmOffsetB (CmmReg nodeReg)
(tagForCon data_con)]
- ; return () }
+ }
-- The case continuation code expects a tagged pointer
arg_reps :: [(PrimRep, UnaryType)]
diff --git a/compiler/codeGen/StgCmmBind.hs b/compiler/codeGen/StgCmmBind.hs
index 148d53a4e3..861c4e33e1 100644
--- a/compiler/codeGen/StgCmmBind.hs
+++ b/compiler/codeGen/StgCmmBind.hs
@@ -436,8 +436,8 @@ closureCodeBody top_lvl bndr cl_info _cc args arity body fv_details
-- heap check, to reduce live vars over check
; if node_points then load_fvs node lf_info fv_bindings
else return ()
- ; _ <- cgExpr body
- ; return () }}
+ ; void $ cgExpr body
+ }}
}
-- A function closure pointer may be tagged, so we
@@ -503,8 +503,7 @@ thunkCode cl_info fv_details _cc node arity body
; let lf_info = closureLFInfo cl_info
; fv_bindings <- mapM bind_fv fv_details
; load_fvs node lf_info fv_bindings
- ; _ <- cgExpr body
- ; return () }}}
+ ; void $ cgExpr body }}}
------------------------------------------------------------------------
diff --git a/compiler/codeGen/StgCmmForeign.hs b/compiler/codeGen/StgCmmForeign.hs
index a6274662ad..8fec067288 100644
--- a/compiler/codeGen/StgCmmForeign.hs
+++ b/compiler/codeGen/StgCmmForeign.hs
@@ -41,6 +41,7 @@ import Outputable
import BasicTypes
import Control.Monad
+import Prelude hiding( succ )
-----------------------------------------------------------------------------
-- Code generation for Foreign Calls
@@ -88,13 +89,11 @@ cgForeignCall (CCall (CCallSpec target cconv safety)) stg_args res_ty
; sequel <- getSequel
; case sequel of
AssignTo assign_to_these _ ->
- do { emitForeignCall safety assign_to_these call_target
+ emitForeignCall safety assign_to_these call_target
call_args CmmMayReturn
- ; return AssignedDirectly
- }
_something_else ->
- do { emitForeignCall safety res_regs call_target
+ do { _ <- emitForeignCall safety res_regs call_target
call_args CmmMayReturn
; emitReturn (map (CmmReg . CmmLocal) res_regs)
}
@@ -185,7 +184,7 @@ emitCCall :: [(CmmFormal,ForeignHint)]
-> [(CmmActual,ForeignHint)]
-> FCode ()
emitCCall hinted_results fn hinted_args
- = emitForeignCall PlayRisky results target args CmmMayReturn
+ = void $ emitForeignCall PlayRisky results target args CmmMayReturn
where
(args, arg_hints) = unzip hinted_args
(results, result_hints) = unzip hinted_results
@@ -195,7 +194,7 @@ emitCCall hinted_results fn hinted_args
emitPrimCall :: [CmmFormal] -> CallishMachOp -> [CmmActual] -> FCode ()
emitPrimCall res op args
- = emitForeignCall PlayRisky res (PrimTarget op) args CmmMayReturn
+ = void $ emitForeignCall PlayRisky res (PrimTarget op) args CmmMayReturn
-- alternative entry point, used by CmmParse
emitForeignCall
@@ -205,20 +204,34 @@ emitForeignCall
-> [CmmActual] -- arguments
-> CmmReturnInfo -- This can say "never returns"
-- only RTS procedures do this
- -> FCode ()
+ -> FCode ReturnKind
emitForeignCall safety results target args _ret
| not (playSafe safety) = do
let (caller_save, caller_load) = callerSaveVolatileRegs
emit caller_save
emit $ mkUnsafeCall target results args
emit caller_load
+ return AssignedDirectly
| otherwise = do
updfr_off <- getUpdFrameOff
temp_target <- load_target_into_temp target
- emit =<< mkSafeCall temp_target results args updfr_off
- (playInterruptible safety)
-
+ k <- newLabelC
+ let (off, copyout) = copyInOflow NativeReturn (Young k) results
+ -- see Note [safe foreign call convention]
+ emit $
+ ( mkStore (CmmStackSlot (Young k) (widthInBytes wordWidth))
+ (CmmLit (CmmBlock k))
+ <*> mkLast (CmmForeignCall { tgt = temp_target
+ , res = results
+ , args = args
+ , succ = k
+ , updfr = updfr_off
+ , intrbl = playInterruptible safety })
+ <*> mkLabel k
+ <*> copyout
+ )
+ return (ReturnedTo k off)
{-
diff --git a/compiler/codeGen/StgCmmMonad.hs b/compiler/codeGen/StgCmmMonad.hs
index eb6b9a988f..3d34cb9bdd 100644
--- a/compiler/codeGen/StgCmmMonad.hs
+++ b/compiler/codeGen/StgCmmMonad.hs
@@ -30,7 +30,7 @@ module StgCmmMonad (
getCodeR, getCode, getHeapUsage,
mkCmmIfThenElse, mkCmmIfThen, mkCmmIfGoto,
- mkCall, mkCmmCall, mkSafeCall,
+ mkCall, mkCmmCall,
forkClosureBody, forkStatics, forkAlts, forkProc, codeOnly,
@@ -95,6 +95,9 @@ infixr 9 `thenFC`
newtype FCode a = FCode (CgInfoDownwards -> CgState -> (a, CgState))
+instance Functor FCode where
+ fmap f (FCode g) = FCode $ \i s -> let (a,s') = g i s in (f a, s')
+
instance Monad FCode where
(>>=) = thenFC
return = returnFC
@@ -792,22 +795,6 @@ mkCmmCall f results actuals updfr_off
= mkCall f (NativeDirectCall, NativeReturn) results actuals updfr_off (0,[])
-mkSafeCall :: ForeignTarget -> [CmmFormal] -> [CmmActual]
- -> UpdFrameOffset -> Bool
- -> FCode CmmAGraph
-mkSafeCall t fs as upd i = do
- k <- newLabelC
- let (_off, copyout) = copyInOflow NativeReturn (Young k) fs
- -- see Note [safe foreign call convention]
- return
- ( mkStore (CmmStackSlot (Young k) (widthInBytes wordWidth))
- (CmmLit (CmmBlock k))
- <*> mkLast (CmmForeignCall { tgt=t, res=fs, args=as, succ=k
- , updfr=upd, intrbl=i })
- <*> mkLabel k
- <*> copyout
- )
-
-- ----------------------------------------------------------------------------
-- CgStmts