-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Add RTCHECK node for compiler-inserted runtime check code #114369
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7632,6 +7632,44 @@ struct GenTreeBoundsChk : public GenTreeOp | |
| } | ||
| }; | ||
|
|
||
| // GenTreeRTCheck - wraps an expression with a runtime check. The runtime check is a | ||
| // function of the value being wrapped. For example: | ||
| // value => GT_LCL_VAR | ||
| // check => GT_EQ(value, GT_CNS_INT(0)) | ||
| // kind => SCK_DIV_BY_ZERO | ||
| // would be the parameter set required to implement a divide-by-zero check on some | ||
| // local value. | ||
| // CodeGen for this node should produce a compare-and-branch to the throw helper in | ||
| // gtThrowKind when the check evaluates to true. | ||
| // | ||
| struct GenTreeRTCheck : public GenTreeOp | ||
| { | ||
| SpecialCodeKind gtThrowKind; // Kind of throw block to branch to on failure | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think using this pattern for the overflow check is going to come with any benefits? Optimizing multiple of those checks will generally require both the dividend and divisor to be equal, but in that case the whole division operation is also equal and can be CSE'd on its own.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wrote it this way partly thinking about making it easier to add new checks in future. Having a common framework for |
||
|
|
||
| GenTreeRTCheck(GenTree* value, GenTree* check, SpecialCodeKind kind) | ||
| : GenTreeOp(GT_RTCHECK, value->TypeGet(), value, check) | ||
| , gtThrowKind(kind) | ||
| { | ||
| gtFlags |= GTF_EXCEPT; | ||
| } | ||
| #if DEBUGGABLE_GENTREE | ||
| GenTreeRTCheck() | ||
| : GenTreeOp() | ||
| { | ||
| } | ||
| #endif | ||
|
|
||
| GenTree* GetValue() const | ||
| { | ||
| return gtOp1; | ||
| } | ||
|
|
||
| GenTree* GetCheck() const | ||
| { | ||
| return gtOp2; | ||
| } | ||
| }; | ||
|
|
||
| // GenTreeArrElem - bounds checked address (byref) of a general array element, | ||
| // for multidimensional arrays, or 1-d arrays with non-zero lower bounds. | ||
| // | ||
|
|
||
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.
It's not legal to clone the divisor tree like this since it can have side effects. I would just remove this and call
gtNewRTCheckNodedirectly from the importer, where we can ensure the proper side effect handling.