Skip to content

Reduce memory usage of the specialization and inline passes #1010

Description

@yorickpeterse

Description

Type specialization and method inlining are the two most memory hungry stages of our compiler, before we enter the LLVM stage at least. In both cases the cause is broadly speaking the same: these stages copy a lot of methods and types around and then modify those copies.

For example, type specialization may copy a method to specialize it, meanwhile the original version has to be kept around until specialization is complete.

For inlining the memory usage is relative to how large methods are and how many times they are inlined. For example, a method that takes B bytes of space and is inlined 10 times will thus (at peak) increase memory usage by 10 * B bytes.

Of course optimizations and such will reduce this (though our current MIR optimizations are rather basic), but they all take place in separate stages and thus don't do much to reduce the peak memory usage.

To give an example, compiling a release build of Inko's test suite requires about 800 MiB of memory (according to heaptrack) at peak with code generation disabled. You can expect this to grow rather quickly as projects get larger.

I currently don't have any good ideas on how to approach this for the type specialization stage.

For the inliner I think we need to take a more general approach such as by optimizing the data structures used for MIR graphs. For example, a single basic block already needs 72 bytes of space plus additional heap space for the instructions, successors and predecessors. The real minimum will likely hover somewhere around 150 bytes per basic block.

The size of certain MIR instructions could probably also be reduced, though it remains to be seen if it will make much of an impact. For example, the various call instructions use a Vec for their arguments but the number of arguments never changes. Using a Box<[RegisterId]> instead of Vec<RegisterId> would shave off 8 bytes per such instruction.

I expect this work to be a case of a dozen or so smaller improvements that work together/build upon each other, rather than one or two big improvements.

Related work

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    accepting contributionsIssues that are suitable to be worked on by anybody, not just maintainerscompilerChanges related to the compilerperformanceChanges related to improving performance

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions