diff options
author | Jonas Scholl <anselm.scholl@tu-harburg.de> | 2016-01-22 16:21:57 +0100 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2016-01-22 18:50:27 +0100 |
commit | 4d51bfc8975f9c6c3ab6d293c48f98da85210d5f (patch) | |
tree | 08bf0c69dc58ece3f09055a2f2dbbc54d3a72ab5 /compiler/codeGen/StgCmmClosure.hs | |
parent | 6e5f8285005895fe4f1915ddea99b72f8ee91834 (diff) | |
download | haskell-4d51bfc8975f9c6c3ab6d293c48f98da85210d5f.tar.gz |
Do not count void arguments when considering a function for loopification.
This fixes #11372 by omitting arguments with a void-type when checking
whether a self-recursive tail call can be optimized to a local jump.
Previously, a function taking a real argument and a State# token
would report an arity of 1 in the SelfLoopInfo in getCallMethod,
but a self-recursive call would apply it to 2 arguments, one of them
being the State# token, thus no local jump would be generated.
As the State# token is not represented by anything at runtime, we can
ignore it and thus trigger the loopification optimization.
Test Plan: ./validate
Reviewers: austin, bgamari, simonmar
Reviewed By: bgamari
Subscribers: simonmar, thomie
Differential Revision: https://phabricator.haskell.org/D1767
GHC Trac Issues: #11372
Diffstat (limited to 'compiler/codeGen/StgCmmClosure.hs')
-rw-r--r-- | compiler/codeGen/StgCmmClosure.hs | 29 |
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 |