-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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] Allow side-effects for the first test in switch recognition #106988
Changes from 1 commit
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 |
---|---|---|
|
@@ -50,17 +50,19 @@ PhaseStatus Compiler::optSwitchRecognition() | |
// constant test? e.g. JTRUE(EQ/NE(X, CNS)). | ||
// | ||
// Arguments: | ||
// block - The block to check | ||
// trueEdge - [out] The successor edge taken if X == CNS | ||
// falseEdge - [out] The successor edge taken if X != CNS | ||
// isReversed - [out] True if the condition is reversed (GT_NE) | ||
// variableNode - [out] The variable node (X in the example above) | ||
// cns - [out] The constant value (CNS in the example above) | ||
// block - The block to check | ||
// allowSideEffects - is variableNode allowed to have side-effects (COMMA)? | ||
// trueEdge - [out] The successor edge taken if X == CNS | ||
// falseEdge - [out] The successor edge taken if X != CNS | ||
// isReversed - [out] True if the condition is reversed (GT_NE) | ||
// variableNode - [out] The variable node (X in the example above) | ||
// cns - [out] The constant value (CNS in the example above) | ||
// | ||
// Return Value: | ||
// True if the block represents a constant test, false otherwise | ||
// | ||
bool IsConstantTestCondBlock(const BasicBlock* block, | ||
bool allowSideEffects, | ||
BasicBlock** trueTarget, | ||
BasicBlock** falseTarget, | ||
bool* isReversed, | ||
|
@@ -89,7 +91,15 @@ bool IsConstantTestCondBlock(const BasicBlock* block, | |
if ((op1->IsCnsIntOrI() && !op1->IsIconHandle()) ^ (op2->IsCnsIntOrI() && !op2->IsIconHandle())) | ||
{ | ||
// TODO: relax this to support any side-effect free expression | ||
if (!op1->OperIs(GT_LCL_VAR) && !op2->OperIs(GT_LCL_VAR)) | ||
|
||
if (allowSideEffects) | ||
{ | ||
if (!op1->gtEffectiveVal()->OperIs(GT_LCL_VAR) && !op2->gtEffectiveVal()->OperIs(GT_LCL_VAR)) | ||
{ | ||
return false; | ||
} | ||
} | ||
else if (!op1->OperIs(GT_LCL_VAR) && !op2->OperIs(GT_LCL_VAR)) | ||
{ | ||
return false; | ||
} | ||
|
@@ -148,7 +158,7 @@ bool Compiler::optSwitchDetectAndConvert(BasicBlock* firstBlock) | |
// and then try to accumulate as many constant test blocks as possible. Once we hit | ||
// a block that doesn't match the pattern, we start processing the accumulated blocks. | ||
bool isReversed = false; | ||
if (IsConstantTestCondBlock(firstBlock, &trueTarget, &falseTarget, &isReversed, &variableNode, &cns)) | ||
if (IsConstantTestCondBlock(firstBlock, true, &trueTarget, &falseTarget, &isReversed, &variableNode, &cns)) | ||
{ | ||
if (isReversed) | ||
{ | ||
|
@@ -185,16 +195,16 @@ bool Compiler::optSwitchDetectAndConvert(BasicBlock* firstBlock) | |
} | ||
|
||
// Inspect secondary blocks | ||
if (IsConstantTestCondBlock(currBb, &currTrueTarget, &currFalseTarget, &isReversed, &currVariableNode, | ||
&currCns)) | ||
if (IsConstantTestCondBlock(currBb, false, &currTrueTarget, &currFalseTarget, &isReversed, | ||
&currVariableNode, &currCns)) | ||
{ | ||
if (currTrueTarget != trueTarget) | ||
{ | ||
// This blocks jumps to a different target, stop searching and process what we already have. | ||
return optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode); | ||
} | ||
|
||
if (!GenTree::Compare(currVariableNode, variableNode)) | ||
if (!GenTree::Compare(currVariableNode, variableNode->gtEffectiveVal())) | ||
{ | ||
// A different variable node is used, stop searching and process what we already have. | ||
return optSwitchConvert(firstBlock, testValueIndex, testValues, falseLikelihood, variableNode); | ||
|
@@ -324,7 +334,7 @@ bool Compiler::optSwitchConvert( | |
BasicBlock* blockIfTrue = nullptr; | ||
BasicBlock* blockIfFalse = nullptr; | ||
bool isReversed = false; | ||
const bool isTest = IsConstantTestCondBlock(lastBlock, &blockIfTrue, &blockIfFalse, &isReversed); | ||
const bool isTest = IsConstantTestCondBlock(lastBlock, false, &blockIfTrue, &blockIfFalse, &isReversed); | ||
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. Why do we clone 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 think this clone was an artifact from the initial impl, I have removed it in the latest commit. |
||
assert(isTest); | ||
|
||
assert(firstBlock->TrueTargetIs(blockIfTrue)); | ||
|
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.
Is there any more side effect to support other than COMMA? If not, please remove the TODO comment becasue this PR will support COMMA side-effect.
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.
Removed