-
-
Notifications
You must be signed in to change notification settings - Fork 308
Add support for sending "assume" hints to compilers #1808
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
base: develop
Are you sure you want to change the base?
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThe changes made in this pull request enhance the error handling and validation mechanisms in the deflate compression algorithm. Modifications include the introduction of assertions in the Changes
Possibly related PRs
Suggested labels
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (2)
zbuild.h (2)
214-229: LGTM! Consider enhancing documentation.The implementation correctly handles different compiler capabilities for optimization hints. The macro is well-structured with appropriate fallbacks.
Consider adding a code example in the documentation to demonstrate proper usage, as this is a new feature that developers will need to understand:
/* The Assume() macro provides hints to compiler and static analyzers about what value range is valid for a variable, helping them optimize for real use. To ensure this does not hide bugs, compilation in debug mode will cause it to check the assumption and throw an error if it fails. + + Example: + void process_buffer(char* buf, size_t len) { + Assume(len <= 1024); // Hint to compiler about maximum size + ... + } */
Line range hint
214-257: Consider documenting optimization impact guidelines.The introduction of compiler hints through
Assumeand modifiedAssertis a powerful feature for optimization. To ensure proper usage:
- Consider adding documentation about when to use
AssumevsAssert- Document guidelines for measuring performance impact
- Add examples of common optimization patterns
Would you like me to help draft this documentation?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (3)
deflate_p.h(0 hunks)inffast_tpl.h(1 hunks)zbuild.h(2 hunks)
💤 Files with no reviewable changes (1)
- deflate_p.h
🔇 Additional comments (2)
zbuild.h (1)
257-257: Verify impact of Assert behavior change in release builds.
The modification to use Assume instead of removing Assert calls in release builds is a significant change that could affect existing code.
Let's analyze the impact:
✅ Verification successful
Based on the results, I can now generate the final response:
Assert macro change appears safe for release builds
The codebase analysis shows that Assert is primarily used for:
- Input validation and invariant checks (e.g., buffer sizes, value ranges)
- Boundary checks in memory operations
- Parameter validation in low-level functions
All observed Assert usages:
- Are not in tight loops that would impact performance
- Validate critical conditions that should hold true for correct operation
- Check invariants that compilers can use for optimization
The change to use Assume in release builds is actually beneficial as it:
- Provides optimization hints to the compiler about valid conditions
- Maintains safety checks in debug builds
- Doesn't introduce overhead in performance-critical paths
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Find all Assert usage in the codebase to evaluate impact
# Search for Assert usage
echo "Analyzing Assert usage patterns..."
rg "Assert\(" --type cpp -B 2 -A 2
# Look for potential performance-critical sections
echo "Checking Assert usage in tight loops..."
ast-grep --pattern 'while($_) { $$$ Assert($_, $_) $$$ }'
ast-grep --pattern 'for($_; $_; $_) { $$$ Assert($_, $_) $$$ }'
Length of output: 4812
inffast_tpl.h (1)
119-125: Well-placed assumptions that match documented invariants!
The added Assume statements effectively translate the documented entry assumptions into compiler hints, which can help with optimizations while maintaining runtime checks in debug builds.
Let's verify that callers maintain these invariants:
✅ Verification successful
Assumptions are well-defined and correctly enforced by callers
The verification shows that:
- Constants
INFLATE_FAST_MIN_HAVE(15) andINFLATE_FAST_MIN_LEFT(260) are properly defined ininflate_p.h - Callers in
inflate.candinfback.cexplicitly check these minimum requirements before invokingINFLATE_FAST - The assumptions align with the documented requirements and runtime checks
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if callers maintain the required invariants before calling INFLATE_FAST
# Search for all calls to INFLATE_FAST
echo "Searching for INFLATE_FAST callers..."
rg -l "INFLATE_FAST" | while read -r file; do
echo "=== Analyzing $file ==="
# Look for setup code before INFLATE_FAST calls
rg -B 10 "INFLATE_FAST\s*\(" "$file"
done
# Verify the constants are properly defined
echo "Checking for INFLATE_FAST_MIN_HAVE and INFLATE_FAST_MIN_LEFT definitions..."
rg "INFLATE_FAST_MIN_(HAVE|LEFT)\b"
Length of output: 3826
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #1808 +/- ##
===========================================
- Coverage 80.44% 80.36% -0.09%
===========================================
Files 139 139
Lines 11176 11170 -6
Branches 2867 2898 +31
===========================================
- Hits 8991 8977 -14
- Misses 1221 1225 +4
- Partials 964 968 +4 ☔ View full report in Codecov by Sentry. |
09b74f3 to
ad20a13
Compare
ad20a13 to
bfa8e5e
Compare
|
MSVC had support for this before the stated version, but I found some references to bugs, so ended up setting VS 2012 as lower end. It is possible to emulate this using unreachable attributes in older GCC versions, however the semantics for that differ a little, therefore I chose to only use the proper assume hint at this time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (1)
zbuild.h (1)
225-233: Consider adding support for additional compilers.The implementation is solid and safely handles Clang, GCC, and MSVC. Consider extending support to:
- Intel compiler using
__builtin_assume- ARM compiler using
__builtin_assumeThis would broaden the optimization benefits across more platforms.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
inffast_tpl.h(1 hunks)zbuild.h(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- inffast_tpl.h
🔇 Additional comments (3)
zbuild.h (3)
214-224: LGTM! Well-documented feature with clear example.
The documentation clearly explains the purpose, behavior, and usage of the Assume macro, with a practical example that demonstrates its application for providing size hints to the compiler.
234-238: LGTM! Clean and safe implementation.
The Assume macro implementation properly handles both debug and release modes, with appropriate error reporting in debug builds and optimization hints in release builds.
261-261: Verify impact on existing Assert usage.
The modification to use Assume in release builds is correct and aligns with the PR objectives. However, let's verify the impact on existing Assert calls in the codebase.
✅ Verification successful
Based on the analysis of Assert usage patterns in the codebase, I can generate the final response:
Assert usage verification completed - safe to proceed
All Assert calls in the codebase are used for invariant checking and validation with simple conditions. No instances found where:
- Assertions contain function calls that could have side effects
- Assertions are used for control flow
- Assertions contain complex expressions that need to be evaluated
The conditions are primarily:
- Boundary checks (e.g.,
len <= UINT8_MAX) - Null pointer checks (e.g.,
buf != NULL) - Size validations (e.g.,
s->w_size <= UINT16_MAX) - State invariants (e.g.,
state->pending == 0)
These patterns are compatible with the change to use Assume in release builds.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Analyze Assert usage patterns to ensure compatibility with new behavior
# Find all Assert calls in the codebase
echo "Analyzing Assert usage patterns..."
rg -p 'Assert\((.*?)\)' --type c --type h
# Look for potential issues like Assert calls with side effects
echo -e "\nChecking for Assert calls that might have side effects..."
rg -p 'Assert\((.*?[+\-*/%=].*?)\)' --type c --type h
Length of output: 8572
|
I'll have to redo this PR, as I had initially suspected, not all the asserts are in fact usable as assume hints (some variables do not exist in release builds, so those cause failures). I need to consider whether to add all Assume hints separately, or whether to introduce another Assert() that does Assume in release builds, while the normal one does not (name suggestions?). Thoughts? We could possibly do it like this if it looks clean, not sure. |
Something like |
zbuild.h
Outdated
| } | ||
| */ | ||
| #if defined(__clang__) && __clang_major__ >= 4 | ||
| #define z_assume(...) do { __builtin_assume(__VA_ARGS__); } while(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#define -> # define
Not sure what you mean |
Just suggesting names... Maybe use Verify() for Debug builds and Assume() for Release builds. |
value ranges of variables, allowing them to better optimize the code. Adds Assume() and AssertHint() macros.
useful hints to compiler and static analyzers.
bfa8e5e to
932c615
Compare
Just letting existing Asserts() calls go to Assume() reduces compiled code size by 104 bytes on x86-64.
Performance seems to be unchanged with these hints (within 0.01%).
The intentions behind adding this:
Summary by CodeRabbit
New Features
z_assumeandAssume.Bug Fixes
Documentation