summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÖmer Sinan Ağacan <omeragacan@gmail.com>2020-01-16 16:09:33 +0300
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-01-20 15:32:13 -0500
commita661df91da5d867ab3e6a912e03a9e1756e59cb6 (patch)
tree83e75f1c17f49746b2986ebaae0da7f16b97a12f
parent0499e3bcd0ea04b7371cee56a8aea1781e9e371f (diff)
downloadhaskell-a661df91da5d867ab3e6a912e03a9e1756e59cb6.tar.gz
Document Stg.FVs module
Fixes #17662 [ci skip]
-rw-r--r--compiler/GHC/Stg/FVs.hs40
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