Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: let Function::inlined take a should_inline_call function #7149

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

asterite
Copy link
Collaborator

@asterite asterite commented Jan 22, 2025

Description

Problem

Part of #7148

Summary

Additional Context

Documentation

Check one:

  • No documentation needed.
  • Documentation included in this PR.
  • [For Experimental Features] Documentation to be submitted in a separate PR.

PR Checklist

  • I have tested the changes locally.
  • I have formatted the changes with Prettier and/or cargo fmt on default settings.

@asterite asterite requested a review from a team January 22, 2025 19:26
@TomAFrench
Copy link
Member

If we're marking this as resolving #7148, can you break out issues for all the extra inlining conditions it specifies?

@asterite
Copy link
Collaborator Author

I changed it to be "part of".

Regarding the extra inlining conditions, are those to be done in preprocess_fns.rs?

@asterite
Copy link
Collaborator Author

(if yes, I can try to implement those in this PR, or at least the first two which seem simpler than the last one)

compiler/noirc_evaluator/src/ssa/opt/inlining.rs Outdated Show resolved Hide resolved
Comment on lines 108 to 110
if called_func_id == self.id() {
return false;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that these checks should be enforced even if we're passing a different inlining condition in as the closure as theyre important safety checks. Can you pull them out of this function and ensure they're always enforced?

Comment on lines 125 to 127
if self.runtime().is_acir() {
// We never inline a brillig function into an ACIR function.
return false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto here and for inlining ACIR into brillig.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and for inlining ACIR into brillig

Is that a new check that should be added?

}

/// Generic function that determines whether a function should inline a call.
pub(super) fn should_inline_call(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to enshrine this as the only way of determining whether a function call should be inlined or not (quite the opposite) so I don't think it should be defined as a method on Function.

@TomAFrench
Copy link
Member

at least the first two which seem simpler than the last one

This should be able to be calculated using compute_times_called.

@TomAFrench
Copy link
Member

Regarding the extra inlining conditions, are those to be done in preprocess_fns.rs?

I don't think so as preprocess_fns is at risk of becoming a mega-pass which does too much. These early inlining passes can be done prior to this.

@asterite
Copy link
Collaborator Author

I addressed all the comments (I think). To avoid a double lookup in ssa.functions I changed the callback to receive &Function, and now it doesn't need to take an &Ssa anymore (and for the future optimizations I think that'll also remain like that, as we can check what's in a function without going through Ssa). Let me know if that's okay, otherwise we can revert the last commit.

Comment on lines 889 to 902
match callee.runtime() {
RuntimeType::Acir(inline_type) => {
// If the called function is acir, we inline if it's not an entry point
if inline_type.is_entry_point() {
return None;
}
}
RuntimeType::Brillig(_) => {
if self.source_function.runtime().is_acir() {
// We never inline a brillig function into an ACIR function.
return None;
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we seperate the runtimes at SSAgen time we can simplify this to enforcing that the caller and callee runtimes are the same (up to the inlining type).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! I couldn't easily check that the two runtime types match (because of InlineType) so I compared the bools of is_acir().

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Execution Memory'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.

Benchmark suite Current: f8ab025 Previous: 7f9525d Ratio
rollup-block-root 4280 MB 1250 MB 3.42
rollup-base-public 1180 MB 730.82 MB 1.61
rollup-base-private 803.26 MB 591.22 MB 1.36
private-kernel-reset 346.48 MB 245.61 MB 1.41

This comment was automatically generated by workflow using github-action-benchmark.

CC: @TomAFrench

@asterite
Copy link
Collaborator Author

There's clearly something wrong but I can't tell what. I'll continue debugging this tomorrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants