Codegen: don't use init check for consts that are declared before read #9801
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.
The way constant work crystal is:
The problem is that this prevents LLVM from inlining the second group of constants, which is a shame. You'd also expect constants to be inlined whenever possible.
The reason why all constants are lazily initialized is because of hoisting. This works:
This works fine. The above is a simple example but
puts A
could be some initialization done by a library where constants that are defined in other files are used.This PR changes the codegen part to track whenever a constant is read. When we reach a constant declaration and it hasn't been read yet, it means that it's safe to initialize it right away, not lazily. This makes startup a bit slower, but accessing a constant is much faster (about 3 times) and we don't pay this price on every access.
For instance, a Gameboy Advance emulator used constants in a very tight loop and it resulted in very poor frames per second (FPS), something like 30. When using a compiler with this PR the FPS doubled for me.
Here's another benchmark:
Before:
After:
We can do a similar optimization for class variables, but I'll send it as a separate PR if this PR is merged.