diff options
author | simonpj@microsoft.com <unknown> | 2009-03-18 10:59:11 +0000 |
---|---|---|
committer | simonpj@microsoft.com <unknown> | 2009-03-18 10:59:11 +0000 |
commit | 4bc25e8c30559b7a6a87b39afcc79340ae778788 (patch) | |
tree | 3748224610d91cc835c08e55967d08808637c4ba /compiler/deSugar | |
parent | bd78c94a3b41f8d2097efc0415fa26e0cd1140ef (diff) | |
download | haskell-4bc25e8c30559b7a6a87b39afcc79340ae778788.tar.gz |
Add the notion of "constructor-like" Ids for rule-matching
This patch adds an optional CONLIKE modifier to INLINE/NOINLINE pragmas,
{-# NOINLINE CONLIKE [1] f #-}
The effect is to allow applications of 'f' to be expanded in a potential
rule match. Example
{-# RULE "r/f" forall v. r (f v) = f (v+1) #-}
Consider the term
let x = f v in ..x...x...(r x)...
Normally the (r x) would not match the rule, because GHC would be scared
about duplicating the redex (f v). However the CONLIKE modifier says to
treat 'f' like a constructor in this situation, and "look through" the
unfolding for x. So (r x) fires, yielding (f (v+1)).
The main changes are:
- Syntax
- The inlinePragInfo field of an IdInfo has a RuleMatchInfo
component, which records whether or not the Id is CONLIKE.
Of course, this needs to be serialised in interface files too.
- The occurrence analyser (OccAnal) and simplifier (Simplify) treat
CONLIKE thing like constructors, by ANF-ing them
- New function coreUtils.exprIsExpandable is like exprIsCheap, but
additionally spots applications of CONLIKE functions
- A CoreUnfolding has a field that caches exprIsExpandable
- The rule matcher consults this field. See
Note [Expanding variables] in Rules.lhs.
On the way I fixed a lurking variable bug in the way variables are
expanded. See Note [Do not expand locally-bound variables] in
Rule.lhs. I also did a bit of reformatting and refactoring in
Rules.lhs, so the module has more lines changed than are really
different.
Diffstat (limited to 'compiler/deSugar')
-rw-r--r-- | compiler/deSugar/DsBinds.lhs | 10 | ||||
-rw-r--r-- | compiler/deSugar/DsForeign.lhs | 2 |
2 files changed, 6 insertions, 6 deletions
diff --git a/compiler/deSugar/DsBinds.lhs b/compiler/deSugar/DsBinds.lhs index 4c144b8e50..80a7cf66ef 100644 --- a/compiler/deSugar/DsBinds.lhs +++ b/compiler/deSugar/DsBinds.lhs @@ -516,12 +516,12 @@ addInlinePrags prags bndr rhs (inl:_) -> addInlineInfo inl bndr rhs addInlineInfo :: InlineSpec -> Id -> CoreExpr -> (Id,CoreExpr) -addInlineInfo (Inline phase is_inline) bndr rhs - = (attach_phase bndr phase, wrap_inline is_inline rhs) +addInlineInfo (Inline prag is_inline) bndr rhs + = (attach_pragma bndr prag, wrap_inline is_inline rhs) where - attach_phase bndr phase - | isAlwaysActive phase = bndr -- Default phase - | otherwise = bndr `setInlinePragma` phase + attach_pragma bndr prag + | isDefaultInlinePragma prag = bndr + | otherwise = bndr `setInlinePragma` prag wrap_inline True body = mkInlineMe body wrap_inline False body = body diff --git a/compiler/deSugar/DsForeign.lhs b/compiler/deSugar/DsForeign.lhs index 0c40318a1f..7071ab7ef4 100644 --- a/compiler/deSugar/DsForeign.lhs +++ b/compiler/deSugar/DsForeign.lhs @@ -387,7 +387,7 @@ dsFExportDynamic id cconv = do , Lam stbl_value ccall_adj ] - fed = (id `setInlinePragma` NeverActive, io_app) + fed = (id `setInlineActivation` NeverActive, io_app) -- Never inline the f.e.d. function, because the litlit -- might not be in scope in other modules. |