Skip to content

Commit adc7dde

Browse files
Refactored optRemoveRangeCheck to handle top-level standalone range check nodes
1 parent 9c628c3 commit adc7dde

File tree

2 files changed

+79
-20
lines changed

2 files changed

+79
-20
lines changed

src/coreclr/jit/compiler.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6007,7 +6007,9 @@ class Compiler
60076007
public:
60086008
void optInit();
60096009

6010-
void optRemoveRangeCheck(GenTree* tree, Statement* stmt);
6010+
GenTree* Compiler::optRemoveRangeCheck(GenTreeBoundsChk* check, GenTree* comma, Statement* stmt);
6011+
GenTree* Compiler::optRemoveStandaloneRangeCheck(GenTreeBoundsChk* check, Statement* stmt);
6012+
void Compiler::optRemoveCommaBasedRangeCheck(GenTree* comma, Statement* stmt);
60116013
bool optIsRangeCheckRemovable(GenTree* tree);
60126014

60136015
protected:
@@ -7286,7 +7288,7 @@ class Compiler
72867288
GenTree* optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, Statement* stmt);
72877289
GenTree* optAssertionProp_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, Statement* stmt);
72887290
GenTree* optAssertionProp_Comma(ASSERT_VALARG_TP assertions, GenTree* tree, Statement* stmt);
7289-
GenTree* optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, GenTree* tree);
7291+
GenTree* optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, GenTree* tree, Statement* stmt);
72907292
GenTree* optAssertionPropGlobal_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, Statement* stmt);
72917293
GenTree* optAssertionPropLocal_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, Statement* stmt);
72927294
GenTree* optAssertionProp_Update(GenTree* newTree, GenTree* tree, Statement* stmt);

src/coreclr/jit/optimizer.cpp

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5068,7 +5068,7 @@ void Compiler::optPerformStaticOptimizations(unsigned loopNum, LoopCloneContext*
50685068
{
50695069
LcJaggedArrayOptInfo* arrIndexInfo = optInfo->AsLcJaggedArrayOptInfo();
50705070
compCurBB = arrIndexInfo->arrIndex.useBlock;
5071-
optRemoveRangeCheck(arrIndexInfo->arrIndex.bndsChks[arrIndexInfo->dim], arrIndexInfo->stmt);
5071+
optRemoveCommaBasedRangeCheck(arrIndexInfo->arrIndex.bndsChks[arrIndexInfo->dim], arrIndexInfo->stmt);
50725072
DBEXEC(dynamicPath, optDebugLogLoopCloning(arrIndexInfo->arrIndex.useBlock, arrIndexInfo->stmt));
50735073
}
50745074
break;
@@ -8211,24 +8211,34 @@ void Compiler::AddModifiedElemTypeAllContainingLoops(unsigned lnum, CORINFO_CLAS
82118211
}
82128212

82138213
//------------------------------------------------------------------------------
8214-
// optRemoveRangeCheck : Given an array index node, mark it as not needing a range check.
8214+
// optRemoveRangeCheck : Given an indexing node, mark it as not needing a range check.
82158215
//
82168216
// Arguments:
8217-
// tree - Range check tree
8218-
// stmt - Statement the tree belongs to
8219-
8220-
void Compiler::optRemoveRangeCheck(GenTree* tree, Statement* stmt)
8217+
// check - Range check tree, the raw CHECK node (ARRAY, SIMD or HWINTRINSIC).
8218+
// comma - GT_COMMA to which the "check" belongs, "nullptr" if the check is a standalone one.
8219+
// stmt - Statement the indexing nodes belongs to.
8220+
//
8221+
// Return Value:
8222+
// Rewritten "check" - no-op if it has no side effects or the tree that contains them.
8223+
//
8224+
// Assumptions:
8225+
// This method is capable of removing checks of two kinds: COMMA-based and standalone top-level ones.
8226+
// In case of a COMMA-based check, "check" must be a non-null first operand of a non-null COMMA.
8227+
// If case of a standalone check, "comma" must be null and "check" - "stmt"'s root.
8228+
//
8229+
GenTree* Compiler::optRemoveRangeCheck(GenTreeBoundsChk* check, GenTree* comma, Statement* stmt)
82218230
{
82228231
#if !REARRANGE_ADDS
82238232
noway_assert(!"can't remove range checks without REARRANGE_ADDS right now");
82248233
#endif
82258234

8226-
noway_assert(tree->gtOper == GT_COMMA);
8227-
8228-
GenTree* bndsChkTree = tree->AsOp()->gtOp1;
8229-
8230-
noway_assert(bndsChkTree->OperIsBoundsCheck());
8235+
noway_assert(stmt != nullptr);
8236+
noway_assert((comma != nullptr && comma->OperIs(GT_COMMA) && comma->gtGetOp1() == check) ||
8237+
(check != nullptr && check->OperIsBoundsCheck() && comma == nullptr));
8238+
noway_assert(check->OperIsBoundsCheck());
82318239

8240+
GenTree* tree = comma != nullptr ? comma : check;
8241+
82328242
#ifdef DEBUG
82338243
if (verbose)
82348244
{
@@ -8239,19 +8249,40 @@ void Compiler::optRemoveRangeCheck(GenTree* tree, Statement* stmt)
82398249

82408250
// Extract side effects
82418251
GenTree* sideEffList = nullptr;
8242-
gtExtractSideEffList(bndsChkTree, &sideEffList, GTF_ASG);
8252+
gtExtractSideEffList(check, &sideEffList, GTF_ASG);
8253+
8254+
if (sideEffList != nullptr)
8255+
{
8256+
// We've got some side effects.
8257+
if (tree->OperIs(GT_COMMA))
8258+
{
8259+
// Make the comma handle them.
8260+
tree->AsOp()->gtOp1 = sideEffList;
8261+
}
8262+
else
8263+
{
8264+
// Make the statement execute them instead of the check.
8265+
stmt->SetRootNode(sideEffList);
8266+
tree = sideEffList;
8267+
}
8268+
}
8269+
else
8270+
{
8271+
check->gtBashToNOP();
8272+
}
82438273

8244-
// Just replace the bndsChk with a NOP as an operand to the GT_COMMA, if there are no side effects.
8245-
tree->AsOp()->gtOp1 = (sideEffList != nullptr) ? sideEffList : gtNewNothingNode();
8246-
// TODO-CQ: We should also remove the GT_COMMA, but in any case we can no longer CSE the GT_COMMA.
8247-
tree->gtFlags |= GTF_DONT_CSE;
8274+
if (tree->OperIs(GT_COMMA))
8275+
{
8276+
// TODO-CQ: We should also remove the GT_COMMA, but in any case we can no longer CSE the GT_COMMA.
8277+
tree->gtFlags |= GTF_DONT_CSE;
8278+
}
82488279

82498280
gtUpdateSideEffects(stmt, tree);
82508281

8251-
/* Recalculate the GetCostSz(), etc... */
8282+
// Recalculate the GetCostSz(), etc...
82528283
gtSetStmtInfo(stmt);
82538284

8254-
/* Re-thread the nodes if necessary */
8285+
// Re-thread the nodes if necessary
82558286
if (fgStmtListThreaded)
82568287
{
82578288
fgSetStmtSeq(stmt);
@@ -8264,6 +8295,32 @@ void Compiler::optRemoveRangeCheck(GenTree* tree, Statement* stmt)
82648295
gtDispTree(tree);
82658296
}
82668297
#endif
8298+
8299+
return check;
8300+
}
8301+
8302+
//------------------------------------------------------------------------------
8303+
// optRemoveStandaloneRangeCheck : A thin wrapper over optRemoveRangeCheck that removes standalone checks.
8304+
//
8305+
GenTree* Compiler::optRemoveStandaloneRangeCheck(GenTreeBoundsChk* check, Statement* stmt)
8306+
{
8307+
assert(check != nullptr);
8308+
assert(stmt != nullptr);
8309+
assert(check == stmt->GetRootNode());
8310+
8311+
return optRemoveRangeCheck(check, nullptr, stmt);
8312+
}
8313+
8314+
//------------------------------------------------------------------------------
8315+
// optRemoveCommaBasedRangeCheck : A thin wrapper over optRemoveRangeCheck that removes COMMA-based checks.
8316+
//
8317+
void Compiler::optRemoveCommaBasedRangeCheck(GenTree* comma, Statement* stmt)
8318+
{
8319+
assert(comma != nullptr);
8320+
assert(stmt != nullptr);
8321+
assert(comma->gtGetOp1()->OperIsBoundsCheck());
8322+
8323+
optRemoveRangeCheck(comma->gtGetOp1()->AsBoundsChk(), comma, stmt);
82678324
}
82688325

82698326
/*****************************************************************************

0 commit comments

Comments
 (0)