The LegacyPassManager was storing an instance of AnalysisUsage for each instance of each pass. In practice, most instances of a single pass class share the same dependencies. We can't rely on this because passes can (and some do) have dynamic dependencies based on instance options.
We can exploit the likely commonality by uniqueing the usage information after querying the pass, but before storing it into the pass manager. This greatly reduces memory consumption by the AnalysisUsage objects. For a long pass pipeline, I measured a decrease in memory consumption for this storage of about 50%. I have not measured on the default O3 pipeline, but I suspect it will see some benefit as well since many passes are repeated (e.g. InstCombine).
I believe this enhancement does not apply to the new pass manager; please correct me if I'm wrong.
Once this is in, I also plan to re-examine the use of SmallVectors in AnalysisUsage and their default size of 32 elements. Given most passes have only a few direct dependencies, this seems likely to be rather wasteful of memory.