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

Add constant folding to const functions #870

Merged
merged 5 commits into from Jan 14, 2022
Merged

Conversation

philberty
Copy link
Member

@philberty philberty commented Jan 13, 2022

In Rust the ArrayType has a constant capacity constraint, which means it
allows for bounds checking at compile time as no variable-length arrays are
allowed. In order to typecheck this case we had a constant folding pass as
part of the type checking system which generated gcc tree's for the IR
and enforced the constant checking along the way.

GCC with optimizations turned on is capable of constant folding/propogating
the compilation unit fully, but we need a method that works regardless of
middlle-end optimizations to fold constant expressions at the front-end,
turns out the CPP front-end already does this via its constexpr
mechanism to ensure that these do fold correctly. Another major reason
to do this change is that the original const fold pass was a striped down
copy of what the backend is already doing which is creating a duplication
of the code generation pass. With this all unified into the code generation
pass all we need to do is port over gcc/cp/constexpr.c to enforce the const
rules fully but at the GCC tree level not at the typed HIR level.

Now that we have unified the pass when we hit a const function we can
simply emit a normal GCC function and outside of const expressions GCC
will simply emit a normal CallExpr and depending on optimization level
fully optimize this. If we are in a ConstDecl we will follow the
rust-constexpr.cc and fold the values or error_mark_node with an apropriate
error. By reusing the CPP constexpr code we know it works so reusing it
as much as possible is a good idea in general for this front-end.

Fixes #799

@philberty philberty self-assigned this Jan 13, 2022
@philberty philberty added this to In progress in Control Flow 3 Macros via automation Jan 13, 2022
@philberty philberty added this to the Macro Expansion milestone Jan 13, 2022
@philberty
Copy link
Member Author

bors try

bors bot added a commit that referenced this pull request Jan 13, 2022
@philberty philberty moved this from In progress to Review in progress in Control Flow 3 Macros Jan 13, 2022
@bors
Copy link
Contributor

bors bot commented Jan 13, 2022

try

Build succeeded:

In Rust the ArrayType has a constant capacity constraint, this means it
allows for bounds checking at compile time as no variable length arrays are
allowed. In order to typecheck this case we had a constant folding pass as
part of the typechecking system which generated gcc tree's for the IR
and enforced the constant checking along the way.

Also after doing some testing GCC with optimizations turned on is capable
of constant folding/propogating the compilation unit fully. Which meant we
need a method of doing with regardless of optimization level to be able
to be on par with what the Rust language expects we need a full proof
method. Turns out the CPP front-end already does this via its constexpr
mechanism to ensure that these _do_ fold correclty. Another major reason
to do this change is that the original const fold pass was a striped down
copy of what the backend is _already_ doing which is creating a duplication
of the code generation pass. With this all unified into the code generation
pass all we need to do is port over gcc/cp/constexpr.c to enforce the const
rules fully but at the GCC tree level not at the typed HIR level.

Now that we have unified the pass when we hit a const function we can
simply emit a normal GCC function and outside of const expressions GCC
will simply emit a normal CallExpr and depending on optimization level
fully optimize this. If we are in a ConstDecl we will follow the
rust-constexpr.cc and fold the values or error_mark_node with an apropriate
error. By reusing the CPP constexpr code we _know_ it works so reusing it
as much as possible is a good idea in general for this front-end.

Addresses #799
BlockExpressions are usually evaluated by create a temporary variable to
hold the result of the tail expression in the correctly. Const expressions
do not have a context of a block so we must fold the value to store it
correctly without the need for temporary variables or a stack. To do this
we can leverage the fact that our constexpr code can fold simple CallExpr's
so in this patch we actually generate an implicit artifical function for
the block but do not add it to the translation unit and we then generate
an artifical CallExpr and pass it to the constant folder system, and then
assign the ConstDecl to this folded value thus reusing all of our existing
BlockExpression code instead of a seperate system.

Fixes #799
@philberty
Copy link
Member Author

bors r+

@philberty philberty moved this from Review in progress to Reviewer approved in Control Flow 3 Macros Jan 14, 2022
@bors
Copy link
Contributor

bors bot commented Jan 14, 2022

Build succeeded:

@bors bors bot merged commit b21caeb into master Jan 14, 2022
Control Flow 3 Macros automation moved this from Reviewer approved to Done Jan 14, 2022
@philberty philberty deleted the phil/const-folding-refactor branch January 14, 2022 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

add constant folding to blocks and const fn
1 participant