Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4383fba

Browse files
committed
VN version
1 parent 6f6bfc3 commit 4383fba

File tree

5 files changed

+113
-41
lines changed

5 files changed

+113
-41
lines changed

src/coreclr/jit/assertionprop.cpp

Lines changed: 72 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,6 +2663,60 @@ AssertionIndex Compiler::optAssertionIsSubtype(GenTree* tree, GenTree* methodTab
26632663
return NO_ASSERTION_INDEX;
26642664
}
26652665

2666+
//------------------------------------------------------------------------------
2667+
// optVNStrengthReductionOnTree:
2668+
//
2669+
// Arguments:
2670+
// block - The block containing the tree.
2671+
// parent - The parent node of the tree.
2672+
// tree - The tree node
2673+
//
2674+
// Return Value:
2675+
// Returns a new tree or nullptr if nothing is changed.
2676+
//
2677+
GenTree* Compiler::optVNStrengthReductionOnTree(BasicBlock* block, GenTree* parent, GenTree* tree)
2678+
{
2679+
if (tree->IsHelperCall())
2680+
{
2681+
GenTreeCall* call = tree->AsCall();
2682+
switch (call->GetHelperNum())
2683+
{
2684+
// Fold "cast(cast(obj, cls), cls)" to "cast(obj, cls)"
2685+
case CORINFO_HELP_CHKCASTARRAY:
2686+
case CORINFO_HELP_CHKCASTANY:
2687+
case CORINFO_HELP_CHKCASTINTERFACE:
2688+
case CORINFO_HELP_CHKCASTCLASS:
2689+
case CORINFO_HELP_ISINSTANCEOFARRAY:
2690+
case CORINFO_HELP_ISINSTANCEOFCLASS:
2691+
case CORINFO_HELP_ISINSTANCEOFANY:
2692+
case CORINFO_HELP_ISINSTANCEOFINTERFACE:
2693+
{
2694+
GenTree* clsArg = call->gtArgs.GetUserArgByIndex(0)->GetNode();
2695+
GenTree* objArg = call->gtArgs.GetUserArgByIndex(1)->GetNode();
2696+
ValueNum clsArgVN = clsArg->gtVNPair.GetConservative();
2697+
ValueNum objArgVN = objArg->gtVNPair.GetConservative();
2698+
2699+
VNFuncApp funcApp;
2700+
if (vnStore->GetVNFunc(objArgVN, &funcApp) &&
2701+
((funcApp.m_func == VNF_CastClass) || (funcApp.m_func == VNF_IsInstanceOf)) &&
2702+
(funcApp.m_args[0] == clsArgVN))
2703+
{
2704+
// The outer cast is redundant, remove it and preserve its side effects
2705+
// We do ignoreRoot here because the actual cast node is proven to never any exceptions
2706+
// (namely, InvalidCastException).
2707+
return gtWrapWithSideEffects(objArg, call, GTF_ALL_EFFECT, true);
2708+
}
2709+
}
2710+
break;
2711+
2712+
default:
2713+
break;
2714+
}
2715+
}
2716+
2717+
return nullptr;
2718+
}
2719+
26662720
//------------------------------------------------------------------------------
26672721
// optVNConstantPropOnTree: Substitutes tree with an evaluated constant while
26682722
// managing side-effects.
@@ -5098,41 +5152,30 @@ GenTree* Compiler::optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCal
50985152
(helper == CORINFO_HELP_CHKCASTCLASS) || (helper == CORINFO_HELP_CHKCASTANY) ||
50995153
(helper == CORINFO_HELP_CHKCASTCLASS_SPECIAL))
51005154
{
5101-
GenTree* arg1 = call->gtArgs.GetArgByIndex(1)->GetNode();
5102-
if (arg1->gtOper != GT_LCL_VAR)
5155+
GenTree* objArg = call->gtArgs.GetArgByIndex(1)->GetNode();
5156+
GenTree* clsArg = call->gtArgs.GetArgByIndex(0)->GetNode();
5157+
5158+
if (objArg->gtOper != GT_LCL_VAR)
51035159
{
51045160
return nullptr;
51055161
}
51065162

5107-
GenTree* arg2 = call->gtArgs.GetArgByIndex(0)->GetNode();
5108-
5109-
unsigned index = optAssertionIsSubtype(arg1, arg2, assertions);
5163+
unsigned index = optAssertionIsSubtype(objArg, clsArg, assertions);
51105164
if (index != NO_ASSERTION_INDEX)
51115165
{
5112-
#ifdef DEBUG
5113-
if (verbose)
5114-
{
5115-
printf("\nDid VN based subtype prop for index #%02u in " FMT_BB ":\n", index, compCurBB->bbNum);
5116-
gtDispTree(call, nullptr, nullptr, true);
5117-
}
5118-
#endif
5119-
GenTree* list = nullptr;
5120-
gtExtractSideEffList(call, &list, GTF_SIDE_EFFECT, true);
5121-
if (list != nullptr)
5122-
{
5123-
arg1 = gtNewOperNode(GT_COMMA, call->TypeGet(), list, arg1);
5124-
fgSetTreeSeq(arg1);
5125-
}
5166+
JITDUMP("\nDid VN based subtype prop for index #%02u in " FMT_BB ":\n", index, compCurBB->bbNum);
5167+
DISPTREE(call);
51265168

5127-
return optAssertionProp_Update(arg1, call, stmt);
5169+
objArg = gtWrapWithSideEffects(objArg, call, GTF_SIDE_EFFECT, true);
5170+
return optAssertionProp_Update(objArg, call, stmt);
51285171
}
51295172

51305173
// Leave a hint for fgLateCastExpansion that obj is never null.
51315174
INDEBUG(AssertionIndex nonNullIdx = NO_ASSERTION_INDEX);
51325175
INDEBUG(bool vnBased = false);
51335176
// GTF_CALL_M_CAST_CAN_BE_EXPANDED check is to improve TP
51345177
if (((call->gtCallMoreFlags & GTF_CALL_M_CAST_CAN_BE_EXPANDED) != 0) &&
5135-
optAssertionIsNonNull(arg1, assertions DEBUGARG(&vnBased) DEBUGARG(&nonNullIdx)))
5178+
optAssertionIsNonNull(objArg, assertions DEBUGARG(&vnBased) DEBUGARG(&nonNullIdx)))
51365179
{
51375180
call->gtCallMoreFlags |= GTF_CALL_M_CAST_OBJ_NONNULL;
51385181
return optAssertionProp_Update(call, call, stmt);
@@ -6419,8 +6462,14 @@ Compiler::fgWalkResult Compiler::optVNConstantPropCurStmt(BasicBlock* block,
64196462

64206463
if (newTree == nullptr)
64216464
{
6422-
// Not propagated, keep going.
6423-
return WALK_CONTINUE;
6465+
// If it wasn't a constant, let's see if we can reduce the strength
6466+
// of the tree using VN.
6467+
newTree = optVNStrengthReductionOnTree(block, parent, tree);
6468+
if (newTree == nullptr)
6469+
{
6470+
// Not propagated, keep going.
6471+
return WALK_CONTINUE;
6472+
}
64246473
}
64256474

64266475
// TODO https://github.com/dotnet/runtime/issues/10450:

src/coreclr/jit/compiler.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3515,6 +3515,11 @@ class Compiler
35153515
GenTreeFlags GenTreeFlags = GTF_SIDE_EFFECT,
35163516
bool ignoreRoot = false);
35173517

3518+
GenTree* gtWrapWithSideEffects(GenTree* tree,
3519+
GenTree* sideEffectsSource,
3520+
GenTreeFlags sideEffectsFlags = GTF_ALL_EFFECT,
3521+
bool ignoreRoot = false);
3522+
35183523
bool gtSplitTree(
35193524
BasicBlock* block, Statement* stmt, GenTree* splitPoint, Statement** firstNewStmt, GenTree*** splitPointUse);
35203525

@@ -7713,6 +7718,7 @@ class Compiler
77137718
fgWalkResult optVNConstantPropCurStmt(BasicBlock* block, Statement* stmt, GenTree* parent, GenTree* tree);
77147719
GenTree* optVNConstantPropOnJTrue(BasicBlock* block, GenTree* test);
77157720
GenTree* optVNConstantPropOnTree(BasicBlock* block, GenTree* parent, GenTree* tree);
7721+
GenTree* optVNStrengthReductionOnTree(BasicBlock* block, GenTree* parent, GenTree* tree);
77167722
GenTree* optExtractSideEffListFromConst(GenTree* tree);
77177723

77187724
AssertionIndex GetAssertionCount()

src/coreclr/jit/gentree.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17063,6 +17063,38 @@ bool Compiler::gtSplitTree(
1706317063
return splitter.MadeChanges;
1706417064
}
1706517065

17066+
//------------------------------------------------------------------------
17067+
// gtExtractSideEffList: Extracts side effects from sideEffectSource (if any)
17068+
// and wraps the input tree with a COMMA node with them.
17069+
//
17070+
// Arguments:
17071+
// tree - the expression tree to wrap with side effects (if any)
17072+
// sideEffectSource - the expression tree to extract side effects from
17073+
// flags - side effect flags to be considered
17074+
// ignoreRoot - ignore side effects on the expression root node
17075+
//
17076+
// Return Value:
17077+
// The original tree wrapped with a COMMA node that contains the side effects
17078+
// or just the tree itself if sideEffectSource has no side effects.
17079+
//
17080+
GenTree* Compiler::gtWrapWithSideEffects(GenTree* tree,
17081+
GenTree* sideEffectSource,
17082+
GenTreeFlags sideEffectsFlags,
17083+
bool ignoreRoot)
17084+
{
17085+
GenTree* sideEffects = nullptr;
17086+
gtExtractSideEffList(sideEffectSource, &sideEffects, sideEffectsFlags, ignoreRoot);
17087+
if (sideEffects != nullptr)
17088+
{
17089+
tree = gtNewOperNode(GT_COMMA, tree->TypeGet(), sideEffects, tree);
17090+
if (fgNodeThreading == NodeThreading::AllTrees)
17091+
{
17092+
fgSetTreeSeq(tree);
17093+
}
17094+
}
17095+
return tree;
17096+
}
17097+
1706617098
//------------------------------------------------------------------------
1706717099
// gtExtractSideEffList: Extracts side effects from the given expression.
1706817100
//

src/coreclr/jit/importer.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,8 +1677,7 @@ GenTree* Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken
16771677
return slotPtrTree;
16781678
}
16791679

1680-
slotPtrTree = gtNewIndir(TYP_I_IMPL, slotPtrTree, GTF_IND_NONFAULTING);
1681-
slotPtrTree->gtFlags &= ~GTF_GLOB_REF; // TODO-Bug?: this is a quirk. Can we mark this indirection invariant?
1680+
slotPtrTree = gtNewIndir(TYP_I_IMPL, slotPtrTree, GTF_IND_NONFAULTING | GTF_IND_INVARIANT);
16821681

16831682
return slotPtrTree;
16841683
}

src/coreclr/jit/morph.cpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9653,22 +9653,8 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA
96539653
}
96549654
else
96559655
{
9656-
GenTree* op1SideEffects = nullptr;
9657-
gtExtractSideEffList(op1, &op1SideEffects, GTF_ALL_EFFECT);
9658-
if (op1SideEffects != nullptr)
9659-
{
9660-
DEBUG_DESTROY_NODE(tree);
9661-
// Keep side-effects of op1
9662-
tree = gtNewOperNode(GT_COMMA, TYP_INT, op1SideEffects, gtNewIconNode(0));
9663-
JITDUMP("false with side effects:\n")
9664-
DISPTREE(tree);
9665-
}
9666-
else
9667-
{
9668-
JITDUMP("false\n");
9669-
DEBUG_DESTROY_NODE(tree, op1);
9670-
tree = gtNewIconNode(0);
9671-
}
9656+
JITDUMP("false\n");
9657+
tree = gtWrapWithSideEffects(gtNewIconNode(0), op1);
96729658
}
96739659
INDEBUG(tree->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);
96749660
return tree;

0 commit comments

Comments
 (0)