-
Notifications
You must be signed in to change notification settings - Fork 4.5k
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
JIT: Remove JTRUE(relop) invariant in the backend #82766
Changes from 8 commits
dd46020
8996239
e6e2be0
0e30f7e
c86cb43
32cb893
091bc1a
cd38ea4
13a5c89
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 |
---|---|---|
|
@@ -1131,9 +1131,9 @@ bool LIR::Range::TryGetUse(GenTree* node, Use* use) | |
} | ||
|
||
//------------------------------------------------------------------------ | ||
// LIR::Range::GetTreeRange: Computes the subrange that includes all nodes | ||
// in the dataflow trees rooted at a particular | ||
// set of nodes. | ||
// LIR::Range::GetMarkedRange: | ||
// Computes the subrange that includes all nodes in the dataflow trees rooted | ||
// at a particular set of nodes. | ||
// | ||
// This method logically uses the following algorithm to compute the | ||
// range: | ||
|
@@ -1164,14 +1164,26 @@ bool LIR::Range::TryGetUse(GenTree* node, Use* use) | |
// occurring before uses). | ||
// | ||
// Arguments: | ||
// root - The root of the dataflow tree. | ||
// isClosed - An output parameter that is set to true if the returned | ||
// range contains only nodes in the dataflow tree and false | ||
// otherwise. | ||
// markFlagsOperands - Whether the dataflow algorithm should also try to | ||
// mark operands that are defining flags. For example, | ||
// GT_JCC implicitly consumes the flags defined by the | ||
// previous node in linear order. If this argument is | ||
// true, then the algorithm will also include the flags | ||
// definition (which is e.g. a CMP node) in the returned | ||
// range. | ||
// This works on a best-effort basis; the user should not | ||
// rely on all flags defs to be found. | ||
// root - The root of the dataflow tree. | ||
// isClosed - An output parameter that is set to true if the returned | ||
// range contains only nodes in the dataflow tree and false | ||
// otherwise. | ||
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. While you're here, can you fix this? |
||
// | ||
// Type arguments: | ||
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. Call this "Template arguments:" instead? |
||
// | ||
// Returns: | ||
// The computed subrange. | ||
// | ||
template <bool markFlagsOperands> | ||
LIR::ReadOnlyRange LIR::Range::GetMarkedRange(unsigned markCount, | ||
GenTree* start, | ||
bool* isClosed, | ||
|
@@ -1182,6 +1194,12 @@ LIR::ReadOnlyRange LIR::Range::GetMarkedRange(unsigned markCount, | |
assert(isClosed != nullptr); | ||
assert(sideEffects != nullptr); | ||
|
||
#ifndef DEBUG | ||
// The treatment of flags definitions is on a best-effort basis; it should | ||
// be used for debug purposes only. | ||
static_assert_no_msg(!markFlagsOperands); | ||
#endif | ||
|
||
bool sawUnmarkedNode = false; | ||
unsigned sideEffectsInRange = 0; | ||
|
||
|
@@ -1203,6 +1221,17 @@ LIR::ReadOnlyRange LIR::Range::GetMarkedRange(unsigned markCount, | |
return GenTree::VisitResult::Continue; | ||
}); | ||
|
||
if (markFlagsOperands && firstNode->OperConsumesFlags()) | ||
{ | ||
GenTree* prev = firstNode->gtPrev; | ||
if ((prev != nullptr) && ((prev->gtFlags & GTF_SET_FLAGS) != 0) && | ||
((prev->gtLIRFlags & LIR::Flags::Mark) == 0)) | ||
{ | ||
prev->gtLIRFlags |= LIR::Flags::Mark; | ||
markCount++; | ||
} | ||
} | ||
|
||
// Unmark the node and update `firstNode` | ||
firstNode->gtLIRFlags &= ~LIR::Flags::Mark; | ||
markCount--; | ||
|
@@ -1282,6 +1311,34 @@ LIR::ReadOnlyRange LIR::Range::GetTreeRange(GenTree* root, bool* isClosed, unsig | |
return GetMarkedRange(markCount, root, isClosed, sideEffects); | ||
} | ||
|
||
#ifdef DEBUG | ||
//------------------------------------------------------------------------ | ||
// LIR::Range::GetTreeRangeWithFlags: | ||
// Computes the subrange that includes all nodes in the dataflow tree rooted at | ||
// a particular node, taking into account that the nodes may also implicitly | ||
// consume flags defined by non-operands. | ||
// | ||
// Arguments: | ||
// root - The root of the dataflow tree range of nodes. | ||
// isClosed - An output parameter that is set to true if the returned | ||
// range contains only nodes in the dataflow tree and false | ||
// otherwise. | ||
// sideEffects - An output parameter that summarizes the side effects | ||
// contained in the returned range. | ||
// | ||
// Returns: | ||
// The computed subrange. | ||
LIR::ReadOnlyRange LIR::Range::GetTreeRangeWithFlags(GenTree* root, bool* isClosed, unsigned* sideEffects) const | ||
{ | ||
assert(root != nullptr); | ||
|
||
unsigned markCount = 1; | ||
root->gtLIRFlags |= LIR::Flags::Mark; | ||
|
||
return GetMarkedRange<true>(markCount, root, isClosed, sideEffects); | ||
} | ||
#endif | ||
|
||
//------------------------------------------------------------------------ | ||
// LIR::Range::GetTreeRange: Computes the subrange that includes all nodes | ||
// in the dataflow trees rooted by the operands | ||
|
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.
Move this down to "Template arguments"?