| ... |
... |
@@ -1618,6 +1618,101 @@ in this (which it previously was): |
|
1618
|
1618
|
in g
|
|
1619
|
1619
|
False -> \x. x
|
|
1620
|
1620
|
in \w. v True
|
|
|
1621
|
+
|
|
|
1622
|
+Note [isCheapApp: bottoming functions]
|
|
|
1623
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
1624
|
+I'm not sure why we have a special case for bottoming
|
|
|
1625
|
+functions in isCheapApp. Maybe we don't need it.
|
|
|
1626
|
+
|
|
|
1627
|
+Note [exprIsExpandable]
|
|
|
1628
|
+~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
1629
|
+An expression is "expandable" if we are willing to duplicate it, if doing
|
|
|
1630
|
+so might make a RULE or case-of-constructor fire. Consider
|
|
|
1631
|
+ let x = (a,b)
|
|
|
1632
|
+ y = build g
|
|
|
1633
|
+ in ....(case x of (p,q) -> rhs)....(foldr k z y)....
|
|
|
1634
|
+
|
|
|
1635
|
+We don't inline 'x' or 'y' (see Note [Lone variables] in GHC.Core.Unfold),
|
|
|
1636
|
+but we do want
|
|
|
1637
|
+
|
|
|
1638
|
+ * the case-expression to simplify
|
|
|
1639
|
+ (via exprIsConApp_maybe, exprIsLiteral_maybe)
|
|
|
1640
|
+
|
|
|
1641
|
+ * the foldr/build RULE to fire
|
|
|
1642
|
+ (by expanding the unfolding during rule matching)
|
|
|
1643
|
+
|
|
|
1644
|
+So we classify the unfolding of a let-binding as "expandable" (via the
|
|
|
1645
|
+uf_expandable field) if we want to do this kind of on-the-fly
|
|
|
1646
|
+expansion. Specifically:
|
|
|
1647
|
+
|
|
|
1648
|
+* True of constructor applications (K a b)
|
|
|
1649
|
+
|
|
|
1650
|
+* True of applications of a "CONLIKE" Id; see Note [CONLIKE pragma] in GHC.Types.Basic.
|
|
|
1651
|
+ (NB: exprIsCheap might not be true of this)
|
|
|
1652
|
+
|
|
|
1653
|
+* False of case-expressions. If we have
|
|
|
1654
|
+ let x = case ... in ...(case x of ...)...
|
|
|
1655
|
+ we won't simplify. We have to inline x. See #14688.
|
|
|
1656
|
+
|
|
|
1657
|
+* False of let-expressions (same reason); and in any case we
|
|
|
1658
|
+ float lets out of an RHS if doing so will reveal an expandable
|
|
|
1659
|
+ application (see SimplEnv.doFloatFromRhs).
|
|
|
1660
|
+
|
|
|
1661
|
+* Take care: exprIsExpandable should /not/ be true of primops. I
|
|
|
1662
|
+ found this in test T5623a:
|
|
|
1663
|
+ let q = /\a. Ptr a (a +# b)
|
|
|
1664
|
+ in case q @ Float of Ptr v -> ...q...
|
|
|
1665
|
+
|
|
|
1666
|
+ q's inlining should not be expandable, else exprIsConApp_maybe will
|
|
|
1667
|
+ say that (q @ Float) expands to (Ptr a (a +# b)), and that will
|
|
|
1668
|
+ duplicate the (a +# b) primop, which we should not do lightly.
|
|
|
1669
|
+ (It's quite hard to trigger this bug, but T13155 does so for GHC 8.0.)
|
|
|
1670
|
+
|
|
|
1671
|
+NB: exprIsWorkFree implies exprIsExpandable.
|
|
|
1672
|
+
|
|
|
1673
|
+Note [isExpandableApp: bottoming functions]
|
|
|
1674
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
1675
|
+It's important that isExpandableApp does not respond True to bottoming
|
|
|
1676
|
+functions. Recall undefined :: HasCallStack => a
|
|
|
1677
|
+Suppose isExpandableApp responded True to (undefined d), and we had:
|
|
|
1678
|
+
|
|
|
1679
|
+ x = undefined <dict-expr>
|
|
|
1680
|
+
|
|
|
1681
|
+Then Simplify.prepareRhs would ANF the RHS:
|
|
|
1682
|
+
|
|
|
1683
|
+ d = <dict-expr>
|
|
|
1684
|
+ x = undefined d
|
|
|
1685
|
+
|
|
|
1686
|
+This is already bad: we gain nothing from having x bound to (undefined
|
|
|
1687
|
+var), unlike the case for data constructors. Worse, we get the
|
|
|
1688
|
+simplifier loop described in OccurAnal Note [Cascading inlines].
|
|
|
1689
|
+Suppose x occurs just once; OccurAnal.occAnalNonRecRhs decides x will
|
|
|
1690
|
+certainly_inline; so we end up inlining d right back into x; but in
|
|
|
1691
|
+the end x doesn't inline because it is bottom (preInlineUnconditionally);
|
|
|
1692
|
+so the process repeats.. We could elaborate the certainly_inline logic
|
|
|
1693
|
+some more, but it's better just to treat bottoming bindings as
|
|
|
1694
|
+non-expandable, because ANFing them is a bad idea in the first place.
|
|
|
1695
|
+
|
|
|
1696
|
+Note [Record selection]
|
|
|
1697
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
1698
|
+I'm experimenting with making record selection
|
|
|
1699
|
+look cheap, so we will substitute it inside a
|
|
|
1700
|
+lambda. Particularly for dictionary field selection.
|
|
|
1701
|
+
|
|
|
1702
|
+BUT: Take care with (sel d x)! The (sel d) might be cheap, but
|
|
|
1703
|
+there's no guarantee that (sel d x) will be too. Hence (n_val_args == 1)
|
|
|
1704
|
+
|
|
|
1705
|
+Note [Expandable overloadings]
|
|
|
1706
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
1707
|
+Suppose the user wrote this
|
|
|
1708
|
+ {-# RULE forall x. foo (negate x) = h x #-}
|
|
|
1709
|
+ f x = ....(foo (negate x))....
|
|
|
1710
|
+They'd expect the rule to fire. But since negate is overloaded, we might
|
|
|
1711
|
+get this:
|
|
|
1712
|
+ f = \d -> let n = negate d in \x -> ...foo (n x)...
|
|
|
1713
|
+So we treat the application of a function (negate in this case) to a
|
|
|
1714
|
+*dictionary* as expandable. In effect, every function is CONLIKE when
|
|
|
1715
|
+it's applied only to dictionaries.
|
|
1621
|
1716
|
-}
|
|
1622
|
1717
|
|
|
1623
|
1718
|
-------------------------------------
|
| ... |
... |
@@ -1690,6 +1785,10 @@ isWorkFreeApp fn n_val_args |
|
1690
|
1785
|
_ -> False
|
|
1691
|
1786
|
|
|
1692
|
1787
|
isCheapApp :: CheapAppFun
|
|
|
1788
|
+-- Like isWorkFreeApp, but add:
|
|
|
1789
|
+-- - bottoming applications
|
|
|
1790
|
+-- - cheap (rather than just work-free) primops
|
|
|
1791
|
+-- - record selectors applied to just the record
|
|
1693
|
1792
|
isCheapApp fn n_val_args
|
|
1694
|
1793
|
| isWorkFreeApp fn n_val_args = True
|
|
1695
|
1794
|
| isDeadEndId fn = True -- See Note [isCheapApp: bottoming functions]
|
| ... |
... |
@@ -1706,6 +1805,10 @@ isCheapApp fn n_val_args |
|
1706
|
1805
|
-- to bother to check the number of args
|
|
1707
|
1806
|
|
|
1708
|
1807
|
isExpandableApp :: CheapAppFun
|
|
|
1808
|
+-- Like isWorkFreeApp, but add:
|
|
|
1809
|
+-- - record selectors applied to just the record
|
|
|
1810
|
+-- - ConLike Ids (if not bottoming)
|
|
|
1811
|
+-- - a function applied to dictionaries
|
|
1709
|
1812
|
isExpandableApp fn n_val_args
|
|
1710
|
1813
|
| isWorkFreeApp fn n_val_args = True
|
|
1711
|
1814
|
| otherwise
|
| ... |
... |
@@ -1737,101 +1840,6 @@ isExpandableApp fn n_val_args |
|
1737
|
1840
|
| otherwise
|
|
1738
|
1841
|
= False
|
|
1739
|
1842
|
|
|
1740
|
|
-{- Note [isCheapApp: bottoming functions]
|
|
1741
|
|
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
1742
|
|
-I'm not sure why we have a special case for bottoming
|
|
1743
|
|
-functions in isCheapApp. Maybe we don't need it.
|
|
1744
|
|
-
|
|
1745
|
|
-Note [exprIsExpandable]
|
|
1746
|
|
-~~~~~~~~~~~~~~~~~~~~~~~
|
|
1747
|
|
-An expression is "expandable" if we are willing to duplicate it, if doing
|
|
1748
|
|
-so might make a RULE or case-of-constructor fire. Consider
|
|
1749
|
|
- let x = (a,b)
|
|
1750
|
|
- y = build g
|
|
1751
|
|
- in ....(case x of (p,q) -> rhs)....(foldr k z y)....
|
|
1752
|
|
-
|
|
1753
|
|
-We don't inline 'x' or 'y' (see Note [Lone variables] in GHC.Core.Unfold),
|
|
1754
|
|
-but we do want
|
|
1755
|
|
-
|
|
1756
|
|
- * the case-expression to simplify
|
|
1757
|
|
- (via exprIsConApp_maybe, exprIsLiteral_maybe)
|
|
1758
|
|
-
|
|
1759
|
|
- * the foldr/build RULE to fire
|
|
1760
|
|
- (by expanding the unfolding during rule matching)
|
|
1761
|
|
-
|
|
1762
|
|
-So we classify the unfolding of a let-binding as "expandable" (via the
|
|
1763
|
|
-uf_expandable field) if we want to do this kind of on-the-fly
|
|
1764
|
|
-expansion. Specifically:
|
|
1765
|
|
-
|
|
1766
|
|
-* True of constructor applications (K a b)
|
|
1767
|
|
-
|
|
1768
|
|
-* True of applications of a "CONLIKE" Id; see Note [CONLIKE pragma] in GHC.Types.Basic.
|
|
1769
|
|
- (NB: exprIsCheap might not be true of this)
|
|
1770
|
|
-
|
|
1771
|
|
-* False of case-expressions. If we have
|
|
1772
|
|
- let x = case ... in ...(case x of ...)...
|
|
1773
|
|
- we won't simplify. We have to inline x. See #14688.
|
|
1774
|
|
-
|
|
1775
|
|
-* False of let-expressions (same reason); and in any case we
|
|
1776
|
|
- float lets out of an RHS if doing so will reveal an expandable
|
|
1777
|
|
- application (see SimplEnv.doFloatFromRhs).
|
|
1778
|
|
-
|
|
1779
|
|
-* Take care: exprIsExpandable should /not/ be true of primops. I
|
|
1780
|
|
- found this in test T5623a:
|
|
1781
|
|
- let q = /\a. Ptr a (a +# b)
|
|
1782
|
|
- in case q @ Float of Ptr v -> ...q...
|
|
1783
|
|
-
|
|
1784
|
|
- q's inlining should not be expandable, else exprIsConApp_maybe will
|
|
1785
|
|
- say that (q @ Float) expands to (Ptr a (a +# b)), and that will
|
|
1786
|
|
- duplicate the (a +# b) primop, which we should not do lightly.
|
|
1787
|
|
- (It's quite hard to trigger this bug, but T13155 does so for GHC 8.0.)
|
|
1788
|
|
-
|
|
1789
|
|
-NB: exprIsWorkFree implies exprIsExpandable.
|
|
1790
|
|
-
|
|
1791
|
|
-Note [isExpandableApp: bottoming functions]
|
|
1792
|
|
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
1793
|
|
-It's important that isExpandableApp does not respond True to bottoming
|
|
1794
|
|
-functions. Recall undefined :: HasCallStack => a
|
|
1795
|
|
-Suppose isExpandableApp responded True to (undefined d), and we had:
|
|
1796
|
|
-
|
|
1797
|
|
- x = undefined <dict-expr>
|
|
1798
|
|
-
|
|
1799
|
|
-Then Simplify.prepareRhs would ANF the RHS:
|
|
1800
|
|
-
|
|
1801
|
|
- d = <dict-expr>
|
|
1802
|
|
- x = undefined d
|
|
1803
|
|
-
|
|
1804
|
|
-This is already bad: we gain nothing from having x bound to (undefined
|
|
1805
|
|
-var), unlike the case for data constructors. Worse, we get the
|
|
1806
|
|
-simplifier loop described in OccurAnal Note [Cascading inlines].
|
|
1807
|
|
-Suppose x occurs just once; OccurAnal.occAnalNonRecRhs decides x will
|
|
1808
|
|
-certainly_inline; so we end up inlining d right back into x; but in
|
|
1809
|
|
-the end x doesn't inline because it is bottom (preInlineUnconditionally);
|
|
1810
|
|
-so the process repeats.. We could elaborate the certainly_inline logic
|
|
1811
|
|
-some more, but it's better just to treat bottoming bindings as
|
|
1812
|
|
-non-expandable, because ANFing them is a bad idea in the first place.
|
|
1813
|
|
-
|
|
1814
|
|
-Note [Record selection]
|
|
1815
|
|
-~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
1816
|
|
-I'm experimenting with making record selection
|
|
1817
|
|
-look cheap, so we will substitute it inside a
|
|
1818
|
|
-lambda. Particularly for dictionary field selection.
|
|
1819
|
|
-
|
|
1820
|
|
-BUT: Take care with (sel d x)! The (sel d) might be cheap, but
|
|
1821
|
|
-there's no guarantee that (sel d x) will be too. Hence (n_val_args == 1)
|
|
1822
|
|
-
|
|
1823
|
|
-Note [Expandable overloadings]
|
|
1824
|
|
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
1825
|
|
-Suppose the user wrote this
|
|
1826
|
|
- {-# RULE forall x. foo (negate x) = h x #-}
|
|
1827
|
|
- f x = ....(foo (negate x))....
|
|
1828
|
|
-They'd expect the rule to fire. But since negate is overloaded, we might
|
|
1829
|
|
-get this:
|
|
1830
|
|
- f = \d -> let n = negate d in \x -> ...foo (n x)...
|
|
1831
|
|
-So we treat the application of a function (negate in this case) to a
|
|
1832
|
|
-*dictionary* as expandable. In effect, every function is CONLIKE when
|
|
1833
|
|
-it's applied only to dictionaries.
|
|
1834
|
|
--}
|
|
1835
|
1843
|
|
|
1836
|
1844
|
isUnaryClassId :: Id -> Bool
|
|
1837
|
1845
|
-- True of (a) the method selector (classop)
|
| ... |
... |
@@ -3265,8 +3273,8 @@ So: |
|
3265
|
3273
|
* When we make an AbsVars list, we close over the free vars of the unfoldings
|
|
3266
|
3274
|
of any tyvars in it. So if `b{=Maybe a}` is in the list then so is `a`
|
|
3267
|
3275
|
|
|
3268
|
|
-* `mkCoreAbsLams` (more generally `mkPolyAbsLams`) forms a lambda abstraction pushing
|
|
3269
|
|
- the tyvar bindings into the body:
|
|
|
3276
|
+* `mkCoreAbsLams` (more generally `mkPolyAbsLams`) forms a lambda abstraction
|
|
|
3277
|
+ pushing the tyvar bindings into the body:
|
|
3270
|
3278
|
mkCoreAbsLams [a, b=[a], x:b] body
|
|
3271
|
3279
|
= \a. \(x:[a]). let @b = [a] in
|
|
3272
|
3280
|
let x:b = x in -- See (AFV1)
|
| ... |
... |
@@ -3301,8 +3309,10 @@ type TaggedAbsVars t = [TaggedBndr t] |
|
3301
|
3309
|
|
|
3302
|
3310
|
mkPolyAbsLams :: forall b. (b -> AbsVar, Var -> b -> b)
|
|
3303
|
3311
|
-> [b] -> Expr b -> Expr b
|
|
3304
|
|
--- `mkPolyAbsLams` is polymorphic in (get,set) so that we can
|
|
3305
|
|
--- use it for both CoreExpr and LevelledExpr
|
|
|
3312
|
+-- `mkPolyAbsLams` is polymorphic in (get,set) so that we
|
|
|
3313
|
+-- can use it for both CoreExpr and LevelledExpr. See
|
|
|
3314
|
+-- - mkCoreAbsLams
|
|
|
3315
|
+-- - mkTaggedAbsLams
|
|
3306
|
3316
|
{-# INLINE mkPolyAbsLams #-}
|
|
3307
|
3317
|
mkPolyAbsLams (getter,setter) bndrs body
|
|
3308
|
3318
|
= go emptyVarSet [] bndrs
|