Add -fspec-inline-join-points to SpecConstr
authorsimonpj@microsoft.com <unknown>
Thu, 17 Jan 2008 15:03:25 +0000 (15:03 +0000)
committersimonpj@microsoft.com <unknown>
Thu, 17 Jan 2008 15:03:25 +0000 (15:03 +0000)
commit44d4bf2c3eff873d18e683c0629f17a228e9dfe0
tree462a4571ab30f5c4b9d3d41fae4107629a21c2f6
parent448873c017b64b4343f695925b4470fa21e216f5
Add -fspec-inline-join-points to SpecConstr

This patch addresses a problem that Roman found in SpecConstr.  Consider:

foo :: Maybe Int -> Maybe Int -> Int
foo a b = let j b = foo a b
           in
           case b of
             Nothing -> ...
             Just n  -> case a of
                          Just m  -> ... j (Just (n+1)) ...
                          Nothing -> ... j (Just (n-1)) ...

We want to make specialised versions for 'foo' for the patterns
Nothing  (Just v)
(Just a) (Just b)

Two problems, caused by the join point j.  First, j does not
scrutinise b, so j won't be specialised f for the (Just v) pattern.
Second, j is defined where the free var 'a' is not evaluated.

Both are solved by brutally inlining j at its call sites.  This risks
major code bloat, but it's relatively quick to implement.  The flag
-fspec-inline-join-points
causes brutal inlining for a
non-recursive binding
of a function
whose RHS contains calls
of a recursive function

The (experimental) flag is static for now, and I have not even
documented it properly.
compiler/main/StaticFlags.hs
compiler/specialise/SpecConstr.lhs