diff options
author | Ömer Sinan Ağacan <omeragacan@gmail.com> | 2020-01-16 16:09:33 +0300 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-01-20 15:32:13 -0500 |
commit | a661df91da5d867ab3e6a912e03a9e1756e59cb6 (patch) | |
tree | 83e75f1c17f49746b2986ebaae0da7f16b97a12f | |
parent | 0499e3bcd0ea04b7371cee56a8aea1781e9e371f (diff) | |
download | haskell-a661df91da5d867ab3e6a912e03a9e1756e59cb6.tar.gz |
Document Stg.FVs module
Fixes #17662
[ci skip]
-rw-r--r-- | compiler/GHC/Stg/FVs.hs | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/compiler/GHC/Stg/FVs.hs b/compiler/GHC/Stg/FVs.hs index 65f80d97af..f878124a18 100644 --- a/compiler/GHC/Stg/FVs.hs +++ b/compiler/GHC/Stg/FVs.hs @@ -1,4 +1,42 @@ --- | Free variable analysis on STG terms. +{- | +Non-global free variable analysis on STG terms. This pass annotates +non-top-level closure bindings with captured variables. Global variables are not +captured. For example, in a top-level binding like (pseudo-STG) + + f = \[x,y] . + let g = \[p] . reverse (x ++ p) + in g y + +In g, `reverse` and `(++)` are global variables so they're not considered free. +`p` is an argument, so `x` is the only actual free variable here. The annotated +version is thus: + + f = \[x,y] . + let g = [x] \[p] . reverse (x ++ p) + in g y + +Note that non-top-level recursive bindings are also considered free within the +group: + + map = {} \r [f xs0] + let { + Rec { + go = {f, go} \r [xs1] + case xs1 of { + [] -> [] []; + : x xs2 -> + let { xs' = {go, xs2} \u [] go xs2; } in + let { x' = {f, x} \u [] f x; } in + : [x' xs']; + }; + end Rec } + } in go xs0; + +Here go is free in its RHS. + +Top-level closure bindings never capture variables as all of their free +variables are global. +-} module GHC.Stg.FVs ( annTopBindingsFreeVars, annBindingFreeVars |