[commit: ghc] ghc-7.2: When specialising recursive functions, mark the specialised function NOINLINE (c669fe8)
Ian Lynagh
igloo at earth.li
Sun Jul 24 20:25:20 CEST 2011
Repository : ssh://darcs.haskell.org//srv/darcs/ghc
On branch : ghc-7.2
http://hackage.haskell.org/trac/ghc/changeset/c669fe8e9ba45c8cc715b46bfb5dade003d20bb9
>---------------------------------------------------------------
commit c669fe8e9ba45c8cc715b46bfb5dade003d20bb9
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Thu Jul 21 12:45:51 2011 +0100
When specialising recursive functions, mark the specialised function NOINLINE
This fixes Trac #4903. See Note [Specialising imported functions] in OccurAnal.
>---------------------------------------------------------------
compiler/deSugar/DsBinds.lhs | 7 +++++--
compiler/specialise/Specialise.lhs | 3 +++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/compiler/deSugar/DsBinds.lhs b/compiler/deSugar/DsBinds.lhs
index 39e7e29..a878e74 100644
--- a/compiler/deSugar/DsBinds.lhs
+++ b/compiler/deSugar/DsBinds.lhs
@@ -517,8 +517,11 @@ dsSpec mb_poly_rhs (L loc (SpecPrag poly_id spec_co spec_inl))
; let spec_id = mkLocalId spec_name spec_ty
`setInlinePragma` inl_prag
`setIdUnfolding` spec_unf
- inl_prag | isDefaultInlinePragma spec_inl = idInlinePragma poly_id
- | otherwise = spec_inl
+ inl_prag | not (isDefaultInlinePragma spec_inl) = spec_inl
+ | not is_local_id -- See Note [Specialising imported functions]
+ -- in OccurAnal
+ , isStrongLoopBreaker (idOccInfo poly_id) = neverInlinePragma
+ | otherwise = idInlinePragma poly_id
-- Get the INLINE pragma from SPECIALISE declaration, or,
-- failing that, from the original Id
diff --git a/compiler/specialise/Specialise.lhs b/compiler/specialise/Specialise.lhs
index c192b3f..7cd4934 100644
--- a/compiler/specialise/Specialise.lhs
+++ b/compiler/specialise/Specialise.lhs
@@ -1138,6 +1138,9 @@ specCalls subst rules_for_me calls_for_me fn rhs
-- Add a suitable unfolding if the spec_inl_prag says so
-- See Note [Inline specialisations]
spec_inl_prag
+ | not is_local && isStrongLoopBreaker (idOccInfo fn)
+ = neverInlinePragma -- See Note [Specialising imported functions] in OccurAnal
+ | otherwise
= case inl_prag of
InlinePragma { inl_inline = Inlinable }
-> inl_prag { inl_inline = EmptyInlineSpec }
More information about the Cvs-ghc
mailing list