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
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
philberty
force-pushed
the
phil/const-folding-refactor
branch
from
January 13, 2022 22:37
6368e84
to
6cdec9b
Compare
bors try |
tryBuild 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
force-pushed
the
phil/const-folding-refactor
branch
from
January 14, 2022 12:38
6cdec9b
to
93554f3
Compare
bors r+ |
philberty
moved this from Review in progress
to Reviewer approved
in Control Flow 3 Macros
Jan 14, 2022
Build succeeded: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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