Skip to content

Unrolling generates massive functions #1104

Description

@DaniPopes

As an example, MontConfig::into_bigint generates some 6000 lines of rust code, which expand into 40000 lines of LLVM IR. This is due to the loop unrolling macro which unrolls a nested loop. this single function can take up to 500ms to codegen and optimize alone, multiplied by each MontConfig implementation. This applies to all functions using the unroll macro as far as I can tell, which all use nested loops.
The problem is exacerbated by inner calls being marked #[inline(always)], which happens regardless of caller or callee size.

I would suggest not doing that, or figuring out a better way to get good codegen than unrolling source code 144 times. For example, extracting the body of the loop into a non-inline-always function which still gets inlined by llvm but not by rust frontend (avoiding evaluating and generating gigantic functions), or unrolling only one of the inner/outer loops instead of both.

Here's an example cargo llvm-lines output:

  Lines                 Copies              Function name
  -----                 ------              -------------
  141625                1401                (TOTAL)
   34765 (24.5%, 24.5%)    1 (0.1%,  0.1%)  <ark_bn254[1508b4c01d874b3e]::fields::fq::FqConfig as ark_ff[412259b66fc872b]::fields::models::fp::montgomery_backend::MontConfig<4usize>>::into_bigint
   34765 (24.5%, 49.1%)    1 (0.1%,  0.1%)  <ark_bn254[1508b4c01d874b3e]::fields::fr::FrConfig as ark_ff[412259b66fc872b]::fields::models::fp::montgomery_backend::MontConfig<4usize>>::into_bigint

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions