diff options
author | Simon Marlow <marlowsd@gmail.com> | 2013-11-28 09:43:58 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2013-11-28 12:52:23 +0000 |
commit | 4d1ea482885481073d2fee0ea0355848b9d853a1 (patch) | |
tree | 776e0632c929fdcfbf9b045308edfde390eb3115 /compiler/codeGen | |
parent | 1df2116c221941ef40a0f6f8fb7dcc42c56738e7 (diff) | |
download | haskell-4d1ea482885481073d2fee0ea0355848b9d853a1.tar.gz |
Implement shortcuts for slow calls (#6084)
Diffstat (limited to 'compiler/codeGen')
-rw-r--r-- | compiler/codeGen/StgCmmLayout.hs | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/compiler/codeGen/StgCmmLayout.hs b/compiler/codeGen/StgCmmLayout.hs index 08f4e296b8..9a7349111d 100644 --- a/compiler/codeGen/StgCmmLayout.hs +++ b/compiler/codeGen/StgCmmLayout.hs @@ -176,16 +176,52 @@ directCall conv lbl arity stg_args slowCall :: CmmExpr -> [StgArg] -> FCode ReturnKind -- (slowCall fun args) applies fun to args, returning the results to Sequel slowCall fun stg_args - = do { dflags <- getDynFlags - ; argsreps <- getArgRepsAmodes stg_args - ; let (rts_fun, arity) = slowCallPattern (map fst argsreps) - ; r <- direct_call "slow_call" NativeNodeCall + = do dflags <- getDynFlags + argsreps <- getArgRepsAmodes stg_args + let (rts_fun, arity) = slowCallPattern (map fst argsreps) + + (r, slow_code) <- getCodeR $ do + r <- direct_call "slow_call" NativeNodeCall (mkRtsApFastLabel rts_fun) arity ((P,Just fun):argsreps) - ; emitComment $ mkFastString ("slow_call for " ++ + emitComment $ mkFastString ("slow_call for " ++ showSDoc dflags (ppr fun) ++ " with pat " ++ unpackFS rts_fun) - ; return r - } + return r + + let n_args = length stg_args + if n_args > arity && optLevel dflags >= 2 + then do + fast_code <- getCode $ + emitCall (NativeNodeCall, NativeReturn) + (entryCode dflags (closureInfoPtr dflags fun)) + (nonVArgs ((P,Just fun):argsreps)) + + slow_lbl <- newLabelC + fast_lbl <- newLabelC + is_tagged_lbl <- newLabelC + end_lbl <- newLabelC + + funv <- (CmmReg . CmmLocal) `fmap` assignTemp fun + + let correct_arity = cmmEqWord dflags (funInfoArity dflags funv) + (mkIntExpr dflags n_args) + + pprTrace "fast call" (int n_args) $ return () + + emit (mkCbranch (cmmIsTagged dflags funv) is_tagged_lbl slow_lbl + <*> mkLabel is_tagged_lbl + <*> mkCbranch correct_arity fast_lbl slow_lbl + <*> mkLabel fast_lbl + <*> fast_code + <*> mkBranch end_lbl + <*> mkLabel slow_lbl + <*> slow_code + <*> mkLabel end_lbl) + return r + + else do + emit slow_code + return r -------------- |