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

Function inlining #463

Merged
merged 22 commits into from
Apr 26, 2024
Merged

Function inlining #463

merged 22 commits into from
Apr 26, 2024

Conversation

kirstenmg
Copy link
Collaborator

@kirstenmg kirstenmg commented Apr 17, 2024

Implementation of function inlining for DAG-in-context.
I had to carefully manipulate the schedule to make substitution go deep enough without continuing forever on infinitely recursive functions. This is bad, and things may get too slow again once other optimizations are in. However, I don't know what alternative there is other than adding phi nodes.

Note that the majority of function_inlining.egg is a copy-pasted Subst, renamed to FunctionInliningSubst. The actual inlining rule is at the end, since it uses FunctionInliningSubst.

Copy link
Member

@oflatt oflatt left a comment

Choose a reason for hiding this comment

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

Looks pretty good to me, but concerned about the schedule. Lets chat about that

(repeat 4 function-inlining-subst))

;; We don't want to inline too many layers
function-inlining
Copy link
Member

Choose a reason for hiding this comment

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

does it work to run function-inlining-subst here, but for more iterations?
I think that would make more sense- run function inlining, then immediately run the substitution rules for a while.

switch_rewrite
loop-simplify
;; Substitution should go for a few iterations but not saturate
(repeat 4 function-inlining-subst))
Copy link
Member

Choose a reason for hiding this comment

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

4 is quite few, we should talk about this

v6: int = call @inc v3;
print v6;
v10: int = call @double v1;
print v10;
Copy link
Member

Choose a reason for hiding this comment

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

neat!

@kirstenmg
Copy link
Collaborator Author

Rewriting this PR to do function inlining in Rust.

@kirstenmg kirstenmg marked this pull request as draft April 23, 2024 06:10
@kirstenmg kirstenmg force-pushed the kirstenmg-function-inlining branch 3 times, most recently from e780737 to 35cacac Compare April 24, 2024 18:40
@kirstenmg kirstenmg marked this pull request as ready for review April 24, 2024 23:10
Copy link
Collaborator

@yihozhang yihozhang left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Member

@oflatt oflatt left a comment

Choose a reason for hiding this comment

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

Great job! Some small things

dag_in_context/src/lib.rs Outdated Show resolved Hide resolved

// Gets a list of all the calls in the program
// and pairs them with an inlined body
fn get_calls_and_subst(
Copy link
Member

Choose a reason for hiding this comment

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

I think you should separate concerns- make a get_calls function and use the resulting set to do the inlining

calls
}

// Generates a ruleset with pairs of (call, inlined body) to union
Copy link
Member

Choose a reason for hiding this comment

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

I think this comment is out of date

Rc::new(Expr::If(
new_pred.clone(),
new_input.clone(),
then.clone(),
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't we add more context to then?
you can use replace context

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Using replace_ctx for if/switch branches or loop bodies is much slower. To generate egglog for fib_recursive.bril, it's < 1 s without replacing vs. > 1 min with replacing. This is because replacing context creates more calls to inline. Previously-inlined calls in branches and loop bodies are not equivalent to the context-replaced calls, so the context-replaced calls will also have their corresponding bodies substituted and added to the inlining unions.

If it is still correct to not replace the context, I think it is better to not replace the context and make inlining run in a reasonable time at the expense of losing some opportunities for optimization.

}
Expr::DoWhile(input, body) => {
let new_input = Self::subst_with_cache(arg, arg_ty, arg_ctx, input, subst_cache);
Rc::new(Expr::DoWhile(new_input.clone(), body.clone()))
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't we add more context to body?

@kirstenmg
Copy link
Collaborator Author

Function inlining only runs for 2 iterations right now (see #494 ), so some bril programs, like simple_recursive.bril, do not have their calls optimized away.

Copy link
Member

@oflatt oflatt left a comment

Choose a reason for hiding this comment

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

Really great work! Fix snapshots and I'll merge this

@@ -95,12 +104,72 @@ pub(crate) fn print_with_intermediate_vars(termdag: &TermDag, term: Term) -> Str
printed
}

// Takes in a termdag and a shared cache referencing the termdag, which can be re-used for multiple exprs
fn global_cached_print_expr_with_intermediate_helper(
Copy link
Member

Choose a reason for hiding this comment

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

This has a pretty confusing name- I think you should inline this function so it doesn't exist

@@ -3,7 +3,7 @@ source: tests/files.rs
expression: visualization.result
---
@main(v0: int) {
v3: bool = const true;
v3: bool = const false;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

🤔 I've seen that change before, it probably doesn't matter for some reason

@oflatt oflatt merged commit 3c4a5da into main Apr 26, 2024
4 checks passed
@oflatt oflatt deleted the kirstenmg-function-inlining branch April 26, 2024 23:15
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.

3 participants