In optimizeModule (lib/Language/PureScript/Backend/IR/Optimizer.hs), withBinding decides whether a Standalone binding is used exactly once via uberModuleFreeRefs, which runs countFreeRefs over every expression in the module. That map is recomputed from scratch for each binding that reaches the isUsedOnce check, so a single optimizeModule run costs O(bindings × module size), and the whole thing re-runs on every idempotently iteration.
Fix direction: count free references once per optimizeModule run and update the counts incrementally as substitutions are applied (each substitution's effect on counts is known: the inlined expression's refs multiply by the number of substituted occurrences, and the substituted name's count drops to zero).
Found during the 2026-07-02 backend audit.
In
optimizeModule(lib/Language/PureScript/Backend/IR/Optimizer.hs),withBindingdecides whether aStandalonebinding is used exactly once viauberModuleFreeRefs, which runscountFreeRefsover every expression in the module. That map is recomputed from scratch for each binding that reaches theisUsedOncecheck, so a singleoptimizeModulerun costs O(bindings × module size), and the whole thing re-runs on everyidempotentlyiteration.Fix direction: count free references once per
optimizeModulerun and update the counts incrementally as substitutions are applied (each substitution's effect on counts is known: the inlined expression's refs multiply by the number of substituted occurrences, and the substituted name's count drops to zero).Found during the 2026-07-02 backend audit.