diff options
author | Joachim Breitner <mail@joachim-breitner.de> | 2014-03-12 15:48:21 +0100 |
---|---|---|
committer | Joachim Breitner <mail@joachim-breitner.de> | 2014-03-14 09:13:42 +0100 |
commit | 797da5c5e0e13a66b55ae7fce85df4f5bee39ca8 (patch) | |
tree | 2033991ae30e3d88cd07093a12ad41223097f0e1 | |
parent | 337bac31648a1b1261fe241286cf93cb5f09aa12 (diff) | |
download | haskell-797da5c5e0e13a66b55ae7fce85df4f5bee39ca8.tar.gz |
Call Arity : Note about fakeBoringCalls
-rw-r--r-- | compiler/simplCore/CallArity.hs | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/compiler/simplCore/CallArity.hs b/compiler/simplCore/CallArity.hs index db0406d077..85e555ec63 100644 --- a/compiler/simplCore/CallArity.hs +++ b/compiler/simplCore/CallArity.hs @@ -304,6 +304,19 @@ called, i.e. variables bound in a pattern match. So interesting are variables th * top-level or let bound * and possibly functions (typeArity > 0) +Note [Information about boring variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If we decide that the variable bound in `let x = e1 in e2` is not interesting, +the analysis of `e2` will not report anything about `x`. To ensure that +`callArityBind` does still do the right thing we have to extend the result from +`e2` with a safe approximation. + +This is done using `fakeBoringCalls` and has the effect of analysing + x `seq` x `seq` e2 +instead, i.e. with `both` the result from `e2` with the most conservative +result about the uninteresting value. + Note [Recursion and fixpointing] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -348,7 +361,7 @@ callArityTopLvl exported int1 (b:bs) exported' = filter isExportedId int2 ++ exported int' = int1 `addInterestingBinds` b (ae1, bs') = callArityTopLvl exported' int' bs - ae1' = fakeBoringCalls int' b ae1 + ae1' = fakeBoringCalls int' b ae1 -- See Note [Information about boring variables] (ae2, b') = callArityBind ae1' int1 b @@ -435,7 +448,7 @@ callArityAnal arity int (Let bind e) where int_body = int `addInterestingBinds` bind (ae_body, e') = callArityAnal arity int_body e - ae_body' = fakeBoringCalls int_body bind ae_body + ae_body' = fakeBoringCalls int_body bind ae_body -- See Note [Information about boring variables] (final_ae, bind') = callArityBind ae_body' int bind -- This is a variant of callArityAnal that is additionally told whether @@ -470,14 +483,14 @@ addInterestingBinds int bind = int `delVarSetList` bindersOf bind -- Possible shadowing `extendVarSetList` interestingBinds bind --- For every boring variable in the binder, this amends the CallArityRes to --- report safe information about them (co-called with everything else, arity 0). +-- For every boring variable in the binder, add a safe approximation +-- See Note [Information about boring variables] fakeBoringCalls :: VarSet -> CoreBind -> CallArityRes -> CallArityRes -fakeBoringCalls int bind res - = addCrossCoCalls (domRes boring) (domRes res) $ (boring `lubRes` res) +fakeBoringCalls int bind res = boring `both` res where - boring = ( emptyUnVarGraph - , mkVarEnv [ (v, 0) | v <- bindersOf bind, not (v `elemVarSet` int)]) + boring = calledMultipleTimes $ + ( emptyUnVarGraph + , mkVarEnv [ (v, 0) | v <- bindersOf bind, not (v `elemVarSet` int)]) -- Used for both local and top-level binds |