summaryrefslogtreecommitdiff
path: root/compiler/codeGen/StgCmmClosure.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/codeGen/StgCmmClosure.hs')
-rw-r--r--compiler/codeGen/StgCmmClosure.hs29
1 files changed, 17 insertions, 12 deletions
diff --git a/compiler/codeGen/StgCmmClosure.hs b/compiler/codeGen/StgCmmClosure.hs
index d3b9fac34a..97224c6660 100644
--- a/compiler/codeGen/StgCmmClosure.hs
+++ b/compiler/codeGen/StgCmmClosure.hs
@@ -496,6 +496,7 @@ getCallMethod :: DynFlags
-- itself
-> LambdaFormInfo -- Its info
-> RepArity -- Number of available arguments
+ -> RepArity -- Number of them being void arguments
-> CgLoc -- Passed in from cgIdApp so that we can
-- handle let-no-escape bindings and self-recursive
-- tail calls using the same data constructor,
@@ -504,30 +505,34 @@ getCallMethod :: DynFlags
-> Maybe SelfLoopInfo -- can we perform a self-recursive tail call?
-> CallMethod
-getCallMethod dflags _ id _ n_args _cg_loc (Just (self_loop_id, block_id, args))
- | gopt Opt_Loopification dflags, id == self_loop_id, n_args == length args
+getCallMethod dflags _ id _ n_args v_args _cg_loc
+ (Just (self_loop_id, block_id, args))
+ | gopt Opt_Loopification dflags
+ , id == self_loop_id
+ , n_args - v_args == length args
-- If these patterns match then we know that:
-- * loopification optimisation is turned on
-- * function is performing a self-recursive call in a tail position
- -- * number of parameters of the function matches functions arity.
- -- See Note [Self-recursive tail calls] in StgCmmExpr for more details
+ -- * number of non-void parameters of the function matches functions arity.
+ -- See Note [Self-recursive tail calls] and Note [Void arguments in
+ -- self-recursive tail calls] in StgCmmExpr for more details
= JumpToIt block_id args
-getCallMethod dflags name id (LFReEntrant _ arity _ _) n_args _cg_loc
+getCallMethod dflags name id (LFReEntrant _ arity _ _) n_args _v_args _cg_loc
_self_loop_info
| n_args == 0 = ASSERT( arity /= 0 )
ReturnIt -- No args at all
| n_args < arity = SlowCall -- Not enough args
| otherwise = DirectEntry (enterIdLabel dflags name (idCafInfo id)) arity
-getCallMethod _ _name _ LFUnLifted n_args _cg_loc _self_loop_info
+getCallMethod _ _name _ LFUnLifted n_args _v_args _cg_loc _self_loop_info
= ASSERT( n_args == 0 ) ReturnIt
-getCallMethod _ _name _ (LFCon _) n_args _cg_loc _self_loop_info
+getCallMethod _ _name _ (LFCon _) n_args _v_args _cg_loc _self_loop_info
= ASSERT( n_args == 0 ) ReturnIt
getCallMethod dflags name id (LFThunk _ _ updatable std_form_info is_fun)
- n_args _cg_loc _self_loop_info
+ n_args _v_args _cg_loc _self_loop_info
| is_fun -- it *might* be a function, so we must "call" it (which is always safe)
= SlowCall -- We cannot just enter it [in eval/apply, the entry code
-- is the fast-entry code]
@@ -558,18 +563,18 @@ getCallMethod dflags name id (LFThunk _ _ updatable std_form_info is_fun)
DirectEntry (thunkEntryLabel dflags name (idCafInfo id) std_form_info
updatable) 0
-getCallMethod _ _name _ (LFUnknown True) _n_arg _cg_locs _self_loop_info
+getCallMethod _ _name _ (LFUnknown True) _n_arg _v_args _cg_locs _self_loop_info
= SlowCall -- might be a function
-getCallMethod _ name _ (LFUnknown False) n_args _cg_loc _self_loop_info
+getCallMethod _ name _ (LFUnknown False) n_args _v_args _cg_loc _self_loop_info
= ASSERT2( n_args == 0, ppr name <+> ppr n_args )
EnterIt -- Not a function
-getCallMethod _ _name _ LFLetNoEscape _n_args (LneLoc blk_id lne_regs)
+getCallMethod _ _name _ LFLetNoEscape _n_args _v_args (LneLoc blk_id lne_regs)
_self_loop_info
= JumpToIt blk_id lne_regs
-getCallMethod _ _ _ _ _ _ _ = panic "Unknown call method"
+getCallMethod _ _ _ _ _ _ _ _ = panic "Unknown call method"
-----------------------------------------------------------------------------
-- staticClosureRequired