From 0c66cc56ac4d42d91bfd9beedabcb988d40d7735 Mon Sep 17 00:00:00 2001 From: "simonpj@microsoft.com" Date: Fri, 18 Dec 2009 16:43:16 +0000 Subject: [PATCH] Always expose the unfolding of something with an InlineRule Previously a bottoming function with a strictness wrapper had a hidden inlining, and that was Very Bad, because in f x = if ... then bot_fun x else x+1 we really want to pass the *unboxed* x to bot_fun. This happens quite a bit in error handling code, eg for array indexing. --- compiler/main/TidyPgm.lhs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/compiler/main/TidyPgm.lhs b/compiler/main/TidyPgm.lhs index 41d9234..d8bacd8 100644 --- a/compiler/main/TidyPgm.lhs +++ b/compiler/main/TidyPgm.lhs @@ -686,7 +686,7 @@ addExternal expose_all id = (new_needed_ids, show_unfold) (varSetElems spec_ids) -- XXX non-det ordering idinfo = idInfo id - dont_inline = isNeverActive (inlinePragmaActivation (inlinePragInfo idinfo)) + never_active = isNeverActive (inlinePragmaActivation (inlinePragInfo idinfo)) loop_breaker = isNonRuleLoopBreaker (occInfo idinfo) bottoming_fn = isBottomingSig (strictnessInfo idinfo `orElse` topSig) spec_ids = specInfoFreeVars (specInfo idinfo) @@ -699,16 +699,23 @@ addExternal expose_all id = (new_needed_ids, show_unfold) mb_unfold_ids :: Maybe (IdSet, [Id]) -- Nothing => don't unfold mb_unfold_ids = case unfoldingInfo idinfo of - CoreUnfolding { uf_tmpl = unf_rhs, uf_guidance = guide } - | expose_all || -- expose_all says to expose all - -- unfoldings willy-nilly - not (bottoming_fn -- No need to inline bottom functions - || dont_inline -- Or ones that say not to - || loop_breaker -- Or that are loop breakers - || neverUnfoldGuidance guide) + CoreUnfolding { uf_tmpl = unf_rhs, uf_src = src, uf_guidance = guide } + | show_unfolding src guide -> Just (exprFvsInOrder unf_rhs) DFunUnfolding _ ops -> Just (exprsFvsInOrder ops) - _ -> Nothing + _ -> Nothing + + show_unfolding unf_source unf_guidance + = expose_all -- 'expose_all' says to expose all + -- unfoldings willy-nilly + + || isInlineRuleSource unf_source -- Always expose things whose + -- source is an inline rule + + || not (bottoming_fn -- No need to inline bottom functions + || never_active -- Or ones that say not to + || loop_breaker -- Or that are loop breakers + || neverUnfoldGuidance unf_guidance) -- We want a deterministic free-variable list. exprFreeVars gives us -- a VarSet, which is in a non-deterministic order when converted to a -- 1.7.10.4