From 5ed66aa2c8ee97d1f370dc719c09cba2a15d5ac3 Mon Sep 17 00:00:00 2001 From: "simonpj@microsoft.com" Date: Mon, 21 Jan 2008 13:59:09 +0000 Subject: [PATCH] Do not worker/wrapper INLINE things, even if they are in a recursive group This patch stops the worker/wrapper transform working on an INLINE thing, even if it's in a recursive group. It might not be the loop breaker. Indeed a recursive group might have no loop breaker, if the only recursion is through rules. Again, this change was provoked by one of Roman's NDP libraries. Specifically the Rec { splitD, splitJoinD } group in Data.Array.Parallel.Unlifted.Distributed.Arrays Simon --- compiler/stranal/WorkWrap.lhs | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/compiler/stranal/WorkWrap.lhs b/compiler/stranal/WorkWrap.lhs index 3667da8..4f95edd 100644 --- a/compiler/stranal/WorkWrap.lhs +++ b/compiler/stranal/WorkWrap.lhs @@ -197,6 +197,27 @@ reason), then we don't w-w it. The only reason this is monadised is for the unique supply. +Note [Don't w/w inline things] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It's very important to refrain from w/w-ing an INLINE function +If we do so by mistake we transform + f = __inline (\x -> E) +into + f = __inline (\x -> case x of (a,b) -> fw E) + fw = \ab -> (__inline (\x -> E)) (a,b) +and the original __inline now vanishes, so E is no longer +inside its __inline wrapper. Death! Disaster! + +Furthermore, if the programmer has marked something as INLINE, +we may lose by w/w'ing it. + +If the strictness analyser is run twice, this test also prevents +wrappers (which are INLINEd) from being re-done. + +Notice that we refrain from w/w'ing an INLINE function even if it is +in a recursive group. It might not be the loop breaker. (We could +test for loop-breaker-hood, but I'm not sure that ever matters.) + \begin{code} tryWW :: RecFlag -> Id -- The fn binder @@ -208,20 +229,8 @@ tryWW :: RecFlag -- if two, then a worker and a -- wrapper. tryWW is_rec fn_id rhs - | isNonRec is_rec && certainlyWillInline unfolding - -- No point in worker/wrappering a function that is going to be - -- INLINEd wholesale anyway. If the strictness analyser is run - -- twice, this test also prevents wrappers (which are INLINEd) - -- from being re-done. - -- - -- It's very important to refrain from w/w-ing an INLINE function - -- If we do so by mistake we transform - -- f = __inline (\x -> E) - -- into - -- f = __inline (\x -> case x of (a,b) -> fw E) - -- fw = \ab -> (__inline (\x -> E)) (a,b) - -- and the original __inline now vanishes, so E is no longer - -- inside its __inline wrapper. Death! Disaster! + | -- isNonRec is_rec && -- Now omitted: see Note [Don't w/w inline things] + certainlyWillInline unfolding || isNeverActive inline_prag -- No point in worker/wrappering if the thing is never inlined! -- 1.7.10.4