Skip to content

Commit ed8df42

Browse files
authored
Code clean up in AP for NonNull* (#112027)
1 parent 109c946 commit ed8df42

File tree

3 files changed

+51
-229
lines changed

3 files changed

+51
-229
lines changed

src/coreclr/jit/assertionprop.cpp

Lines changed: 26 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -4962,140 +4962,63 @@ GenTree* Compiler::optAssertionProp_Ind(ASSERT_VALARG_TP assertions, GenTree* tr
49624962
// Arguments:
49634963
// op - tree to check
49644964
// assertions - set of live assertions
4965-
// pVnBased - [out] set to true if value numbers were used
4966-
// pIndex - [out] the assertion used in the proof
49674965
//
49684966
// Return Value:
49694967
// true if the tree's value will be non-null
49704968
//
4971-
// Notes:
4972-
// Sets "pVnBased" if the assertion is value number based. If no matching
4973-
// assertions are found from the table, then returns "NO_ASSERTION_INDEX."
4974-
//
4975-
// If both VN and assertion table yield a matching assertion, "pVnBased"
4976-
// is only set and the return value is "NO_ASSERTION_INDEX."
4977-
//
4978-
bool Compiler::optAssertionIsNonNull(GenTree* op,
4979-
ASSERT_VALARG_TP assertions DEBUGARG(bool* pVnBased)
4980-
DEBUGARG(AssertionIndex* pIndex))
4969+
bool Compiler::optAssertionIsNonNull(GenTree* op, ASSERT_VALARG_TP assertions)
49814970
{
49824971
if (op->OperIs(GT_ADD) && op->AsOp()->gtGetOp2()->IsCnsIntOrI() &&
49834972
!fgIsBigOffset(op->AsOp()->gtGetOp2()->AsIntCon()->IconValue()))
49844973
{
49854974
op = op->AsOp()->gtGetOp1();
49864975
}
49874976

4988-
bool vnBased = (!optLocalAssertionProp && vnStore->IsKnownNonNull(op->gtVNPair.GetConservative()));
4989-
#ifdef DEBUG
4990-
*pIndex = NO_ASSERTION_INDEX;
4991-
*pVnBased = vnBased;
4992-
#endif
4993-
4994-
if (vnBased)
4977+
// Fast path when we have a VN
4978+
if (!optLocalAssertionProp && vnStore->IsKnownNonNull(op->gtVNPair.GetConservative()))
49954979
{
49964980
return true;
49974981
}
49984982

4999-
op = op->gtEffectiveVal();
5000-
5001-
if (!op->OperIs(GT_LCL_VAR))
4983+
if (!optCanPropNonNull || BitVecOps::MayBeUninit(assertions))
50024984
{
50034985
return false;
50044986
}
50054987

5006-
AssertionIndex index = optAssertionIsNonNullInternal(op, assertions DEBUGARG(pVnBased));
5007-
#ifdef DEBUG
5008-
*pIndex = index;
5009-
#endif
5010-
return index != NO_ASSERTION_INDEX;
5011-
}
5012-
5013-
//------------------------------------------------------------------------
5014-
// optAssertionIsNonNullInternal: see if we can prove a tree's value will
5015-
// be non-null based on assertions
5016-
//
5017-
// Arguments:
5018-
// op - tree to check
5019-
// assertions - set of live assertions
5020-
// pVnBased - [out] set to true if value numbers were used
5021-
//
5022-
// Return Value:
5023-
// index of assertion, or NO_ASSERTION_INDEX
5024-
//
5025-
AssertionIndex Compiler::optAssertionIsNonNullInternal(GenTree* op,
5026-
ASSERT_VALARG_TP assertions DEBUGARG(bool* pVnBased))
5027-
{
5028-
5029-
#ifdef DEBUG
5030-
// Initialize the out param
5031-
//
5032-
*pVnBased = false;
5033-
#endif
5034-
5035-
if (!optCanPropNonNull)
4988+
op = op->gtEffectiveVal();
4989+
if (!op->OperIs(GT_LCL_VAR))
50364990
{
5037-
return NO_ASSERTION_INDEX;
4991+
return false;
50384992
}
50394993

50404994
// If local assertion prop use lcl comparison, else use VN comparison.
50414995
if (!optLocalAssertionProp)
50424996
{
5043-
if (BitVecOps::MayBeUninit(assertions) || BitVecOps::IsEmpty(apTraits, assertions))
5044-
{
5045-
return NO_ASSERTION_INDEX;
5046-
}
5047-
50484997
// Look at both the top-level vn, and
50494998
// the vn we get by stripping off any constant adds.
50504999
//
5051-
ValueNum vn = vnStore->VNConservativeNormalValue(op->gtVNPair);
5052-
ValueNum vnBase = vn;
5053-
VNFuncApp funcAttr;
5054-
5055-
while (vnStore->GetVNFunc(vnBase, &funcAttr) && (funcAttr.m_func == (VNFunc)GT_ADD))
5000+
ValueNum vn = vnStore->VNConservativeNormalValue(op->gtVNPair);
5001+
if (vn == ValueNumStore::NoVN)
50565002
{
5057-
if (vnStore->IsVNConstant(funcAttr.m_args[1]) && varTypeIsIntegral(vnStore->TypeOfVN(funcAttr.m_args[1])))
5058-
{
5059-
vnBase = funcAttr.m_args[0];
5060-
}
5061-
else if (vnStore->IsVNConstant(funcAttr.m_args[0]) &&
5062-
varTypeIsIntegral(vnStore->TypeOfVN(funcAttr.m_args[0])))
5063-
{
5064-
vnBase = funcAttr.m_args[1];
5065-
}
5066-
else
5067-
{
5068-
break;
5069-
}
5003+
return false;
50705004
}
50715005

5006+
ValueNum vnBase = vn;
5007+
target_ssize_t offset = 0;
5008+
vnStore->PeelOffsets(&vnBase, &offset);
5009+
50725010
// Check each assertion to find if we have a vn != null assertion.
50735011
//
50745012
BitVecOps::Iter iter(apTraits, assertions);
50755013
unsigned index = 0;
50765014
while (iter.NextElem(&index))
50775015
{
50785016
AssertionIndex assertionIndex = GetAssertionIndex(index);
5079-
if (assertionIndex > optAssertionCount)
5080-
{
5081-
break;
5082-
}
5083-
AssertionDsc* curAssertion = optGetAssertion(assertionIndex);
5084-
if (!curAssertion->CanPropNonNull())
5085-
{
5086-
continue;
5087-
}
5088-
5089-
if ((curAssertion->op1.vn != vn) && (curAssertion->op1.vn != vnBase))
5017+
AssertionDsc* curAssertion = optGetAssertion(assertionIndex);
5018+
if (curAssertion->CanPropNonNull() && ((curAssertion->op1.vn == vn) || (curAssertion->op1.vn == vnBase)))
50905019
{
5091-
continue;
5020+
return true;
50925021
}
5093-
5094-
#ifdef DEBUG
5095-
*pVnBased = true;
5096-
#endif
5097-
5098-
return assertionIndex;
50995022
}
51005023
}
51015024
else
@@ -5119,11 +5042,11 @@ AssertionIndex Compiler::optAssertionIsNonNullInternal(GenTree*
51195042
(curAssertion->op2.kind == O2K_CONST_INT) && // op2
51205043
(curAssertion->op1.lcl.lclNum == lclNum) && (curAssertion->op2.u1.iconVal == 0))
51215044
{
5122-
return assertionIndex;
5045+
return true;
51235046
}
51245047
}
51255048
}
5126-
return NO_ASSERTION_INDEX;
5049+
return false;
51275050
}
51285051

51295052
//------------------------------------------------------------------------
@@ -5177,20 +5100,10 @@ GenTree* Compiler::optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions, Gen
51775100
GenTree* op1 = call->gtArgs.GetThisArg()->GetNode();
51785101
noway_assert(op1 != nullptr);
51795102

5180-
#ifdef DEBUG
5181-
bool vnBased = false;
5182-
AssertionIndex index = NO_ASSERTION_INDEX;
5183-
#endif
5184-
if (optAssertionIsNonNull(op1, assertions DEBUGARG(&vnBased) DEBUGARG(&index)))
5103+
if (optAssertionIsNonNull(op1, assertions))
51855104
{
5186-
#ifdef DEBUG
5187-
if (verbose)
5188-
{
5189-
(vnBased) ? printf("\nVN based non-null prop in " FMT_BB ":\n", compCurBB->bbNum)
5190-
: printf("\nNon-null prop for index #%02u in " FMT_BB ":\n", index, compCurBB->bbNum);
5191-
gtDispTree(call, nullptr, nullptr, true);
5192-
}
5193-
#endif
5105+
JITDUMP("Non-null assertion prop for tree [%06d] in " FMT_BB ":\n", dspTreeID(op1), compCurBB->bbNum);
5106+
51945107
call->gtFlags &= ~GTF_CALL_NULLCHECK;
51955108
call->gtFlags &= ~GTF_EXCEPT;
51965109
noway_assert(call->gtFlags & GTF_SIDE_EFFECT);
@@ -5219,20 +5132,10 @@ bool Compiler::optNonNullAssertionProp_Ind(ASSERT_VALARG_TP assertions, GenTree*
52195132
return false;
52205133
}
52215134

5222-
#ifdef DEBUG
5223-
bool vnBased = false;
5224-
AssertionIndex index = NO_ASSERTION_INDEX;
5225-
#endif
5226-
if (optAssertionIsNonNull(indir->AsIndir()->Addr(), assertions DEBUGARG(&vnBased) DEBUGARG(&index)))
5135+
if (optAssertionIsNonNull(indir->AsIndir()->Addr(), assertions))
52275136
{
5228-
#ifdef DEBUG
5229-
if (verbose)
5230-
{
5231-
(vnBased) ? printf("\nVN based non-null prop in " FMT_BB ":\n", compCurBB->bbNum)
5232-
: printf("\nNon-null prop for index #%02u in " FMT_BB ":\n", index, compCurBB->bbNum);
5233-
gtDispTree(indir, nullptr, nullptr, true);
5234-
}
5235-
#endif
5137+
JITDUMP("Non-null assertion prop for indirection [%06d] in " FMT_BB ":\n", dspTreeID(indir), compCurBB->bbNum);
5138+
52365139
indir->gtFlags &= ~GTF_EXCEPT;
52375140
indir->gtFlags |= GTF_IND_NONFAULTING;
52385141

@@ -5429,11 +5332,9 @@ GenTree* Compiler::optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCal
54295332
}
54305333

54315334
// Leave a hint for fgLateCastExpansion that obj is never null.
5432-
INDEBUG(AssertionIndex nonNullIdx = NO_ASSERTION_INDEX);
5433-
INDEBUG(bool vnBased = false);
54345335
// GTF_CALL_M_CAST_CAN_BE_EXPANDED check is to improve TP
54355336
if (((call->gtCallMoreFlags & GTF_CALL_M_CAST_CAN_BE_EXPANDED) != 0) &&
5436-
optAssertionIsNonNull(objArg, assertions DEBUGARG(&vnBased) DEBUGARG(&nonNullIdx)))
5337+
optAssertionIsNonNull(objArg, assertions))
54375338
{
54385339
call->gtCallMoreFlags |= GTF_CALL_M_CAST_OBJ_NONNULL;
54395340
return optAssertionProp_Update(call, call, stmt);

src/coreclr/jit/compiler.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8247,10 +8247,8 @@ class Compiler
82478247
// Used for respective assertion propagations.
82488248
AssertionIndex optAssertionIsSubrange(GenTree* tree, IntegralRange range, ASSERT_VALARG_TP assertions);
82498249
AssertionIndex optAssertionIsSubtype(GenTree* tree, GenTree* methodTableArg, ASSERT_VALARG_TP assertions);
8250-
AssertionIndex optAssertionIsNonNullInternal(GenTree* op, ASSERT_VALARG_TP assertions DEBUGARG(bool* pVnBased));
82518250
bool optAssertionVNIsNonNull(ValueNum vn, ASSERT_VALARG_TP assertions);
8252-
bool optAssertionIsNonNull(GenTree* op,
8253-
ASSERT_VALARG_TP assertions DEBUGARG(bool* pVnBased) DEBUGARG(AssertionIndex* pIndex));
8251+
bool optAssertionIsNonNull(GenTree* op, ASSERT_VALARG_TP assertions);
82548252

82558253
AssertionIndex optGlobalAssertionIsEqualOrNotEqual(ASSERT_VALARG_TP assertions, GenTree* op1, GenTree* op2);
82568254
AssertionIndex optGlobalAssertionIsEqualOrNotEqualZero(ASSERT_VALARG_TP assertions, GenTree* op1);

0 commit comments

Comments
 (0)