GHC.Stg.FVs

ghc-9.10.0.20240426: The GHC API

Safe Haskell | None
Language | GHC2021

GHC.Stg.FVs

Description

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.

Synopsis

- depSortWithAnnotStgPgm :: Module -> [StgTopBinding] -> [(CgStgTopBinding, ImpFVs)]
- annBindingFreeVars :: Module -> StgBinding -> CgStgBinding

# Documentation

depSortWithAnnotStgPgm :: Module -> [StgTopBinding] -> [(CgStgTopBinding, ImpFVs)] Source #

Dependency sort a STG program, and annotate it with free variables The returned bindings: * Are in dependency order * Each StgRhsClosure is correctly annotated (in its extension field) with the free variables needed in the closure * Each StgCase is correctly annotated (in its extension field) with the variables that must be saved across the case

annBindingFreeVars :: Module -> StgBinding -> CgStgBinding Source #

Dependency analysis on STG terms.

Dependencies of a binding are just free variables in the binding. This includes imported ids and ids in the current module. For recursive groups we just return one set of free variables which is just the union of dependencies of all bindings in the group.

Implementation: pass bound variables (NestedIds) to recursive calls, get free variables (TopFVs) back. We ignore imported TopFVs as they do not change the ordering but it improves performance (see `nameIsExternalFrom` call in `vars_fvs`).