@@ -298,8 +298,8 @@ bool Compiler::optCSE_canSwap(GenTree* op1, GenTree* op2)
298
298
/* static */
299
299
bool Compiler::optCSEcostCmpEx::operator ()(const CSEdsc* dsc1, const CSEdsc* dsc2)
300
300
{
301
- GenTree* exp1 = dsc1->csdTree ;
302
- GenTree* exp2 = dsc2->csdTree ;
301
+ GenTree* exp1 = dsc1->csdTreeList . tslTree ;
302
+ GenTree* exp2 = dsc2->csdTreeList . tslTree ;
303
303
304
304
auto expCost1 = exp1->GetCostEx ();
305
305
auto expCost2 = exp2->GetCostEx ();
@@ -334,8 +334,8 @@ bool Compiler::optCSEcostCmpEx::operator()(const CSEdsc* dsc1, const CSEdsc* dsc
334
334
/* static */
335
335
bool Compiler::optCSEcostCmpSz::operator ()(const CSEdsc* dsc1, const CSEdsc* dsc2)
336
336
{
337
- GenTree* exp1 = dsc1->csdTree ;
338
- GenTree* exp2 = dsc2->csdTree ;
337
+ GenTree* exp1 = dsc1->csdTreeList . tslTree ;
338
+ GenTree* exp2 = dsc2->csdTreeList . tslTree ;
339
339
340
340
auto expCost1 = exp1->GetCostSz ();
341
341
auto expCost2 = exp2->GetCostSz ();
@@ -434,7 +434,7 @@ void CSEdsc::ComputeNumLocals(Compiler* compiler)
434
434
};
435
435
436
436
LocalCountingVisitor lcv (compiler);
437
- lcv.WalkTree (&csdTree , nullptr );
437
+ lcv.WalkTree (&csdTreeList. tslTree , nullptr );
438
438
439
439
numDistinctLocals = lcv.m_count ;
440
440
numLocalOccurrences = lcv.m_occurrences ;
@@ -615,99 +615,85 @@ unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt)
615
615
616
616
for (hashDsc = optCSEhash[hval]; hashDsc; hashDsc = hashDsc->csdNextInBucket )
617
617
{
618
- if (hashDsc->csdHashKey = = key)
618
+ if (hashDsc->csdHashKey ! = key)
619
619
{
620
- // Check for mismatched types on GT_CNS_INT nodes
621
- if ((tree->OperGet () == GT_CNS_INT) && (tree->TypeGet () != hashDsc->csdTree ->TypeGet ()))
622
- {
623
- continue ;
624
- }
620
+ continue ;
621
+ }
622
+
623
+ assert (hashDsc->csdTreeList .tslTree != nullptr );
625
624
626
- treeStmtLst* newElem;
625
+ // Check for mismatched types on GT_CNS_INT nodes
626
+ if ((tree->OperGet () == GT_CNS_INT) && (tree->TypeGet () != hashDsc->csdTreeList .tslTree ->TypeGet ()))
627
+ {
628
+ continue ;
629
+ }
627
630
628
- // Have we started the list of matching nodes?
631
+ // Have we started the list of matching nodes?
629
632
630
- if (hashDsc->csdTreeList == nullptr )
633
+ if (hashDsc->csdTreeList .tslNext == nullptr )
634
+ {
635
+ // This is the second time we see this value. Handle cases
636
+ // where the first value dominates the second one and we can
637
+ // already prove that the first one is _not_ going to be a
638
+ // valid def for the second one, due to the second one having
639
+ // more exceptions. This happens for example in code like
640
+ // CASTCLASS(x, y) where the "CASTCLASS" just adds exceptions
641
+ // on top of "x". In those cases it is always better to let the
642
+ // second value be the def.
643
+ // It also happens for GT_COMMA, but that one is special cased
644
+ // above; this handling is a less special-casey version of the
645
+ // GT_COMMA handling above. However, it is quite limited since
646
+ // it only handles the def/use being in the same block.
647
+ if (compCurBB == hashDsc->csdTreeList .tslBlock )
631
648
{
632
- // This is the second time we see this value. Handle cases
633
- // where the first value dominates the second one and we can
634
- // already prove that the first one is _not_ going to be a
635
- // valid def for the second one, due to the second one having
636
- // more exceptions. This happens for example in code like
637
- // CASTCLASS(x, y) where the "CASTCLASS" just adds exceptions
638
- // on top of "x". In those cases it is always better to let the
639
- // second value be the def.
640
- // It also happens for GT_COMMA, but that one is special cased
641
- // above; this handling is a less special-casey version of the
642
- // GT_COMMA handling above. However, it is quite limited since
643
- // it only handles the def/use being in the same block.
644
- if (compCurBB == hashDsc->csdBlock )
649
+ GenTree* prevTree = hashDsc->csdTreeList .tslTree ;
650
+ ValueNum prevVnLib = prevTree->GetVN (VNK_Liberal);
651
+ if (prevVnLib != vnLib)
645
652
{
646
- GenTree* prevTree = hashDsc->csdTree ;
647
- ValueNum prevVnLib = prevTree->GetVN (VNK_Liberal);
648
- if (prevVnLib != vnLib)
653
+ ValueNum prevExceptionSet = vnStore->VNExceptionSet (prevVnLib);
654
+ ValueNum curExceptionSet = vnStore->VNExceptionSet (vnLib);
655
+ if ((prevExceptionSet != curExceptionSet) &&
656
+ vnStore->VNExcIsSubset (curExceptionSet, prevExceptionSet))
649
657
{
650
- ValueNum prevExceptionSet = vnStore->VNExceptionSet (prevVnLib);
651
- ValueNum curExceptionSet = vnStore->VNExceptionSet (vnLib);
652
- if ((prevExceptionSet != curExceptionSet) &&
653
- vnStore->VNExcIsSubset (curExceptionSet, prevExceptionSet))
654
- {
655
- JITDUMP (" Skipping CSE candidate for tree [%06u]; tree [%06u] is a better candidate with "
656
- " more exceptions\n " ,
657
- prevTree->gtTreeID , tree->gtTreeID );
658
- prevTree->gtCSEnum = 0 ;
659
- hashDsc->csdStmt = stmt;
660
- hashDsc->csdTree = tree;
661
- tree->gtCSEnum = (signed char )hashDsc->csdIndex ;
662
- return hashDsc->csdIndex ;
663
- }
658
+ JITDUMP (" Skipping CSE candidate for tree [%06u]; tree [%06u] is a better candidate with "
659
+ " more exceptions\n " ,
660
+ prevTree->gtTreeID , tree->gtTreeID );
661
+ prevTree->gtCSEnum = 0 ;
662
+ hashDsc->csdTreeList .tslStmt = stmt;
663
+ hashDsc->csdTreeList .tslTree = tree;
664
+ tree->gtCSEnum = (signed char )hashDsc->csdIndex ;
665
+ return hashDsc->csdIndex ;
664
666
}
665
667
}
666
-
667
- // Create the new element based upon the matching hashDsc element.
668
-
669
- newElem = new (this , CMK_TreeStatementList) treeStmtLst;
670
-
671
- newElem->tslTree = hashDsc->csdTree ;
672
- newElem->tslStmt = hashDsc->csdStmt ;
673
- newElem->tslBlock = hashDsc->csdBlock ;
674
- newElem->tslNext = nullptr ;
675
-
676
- /* Start the list with the first CSE candidate recorded */
677
-
678
- hashDsc->csdTreeList = newElem;
679
- hashDsc->csdTreeLast = newElem;
680
-
681
- hashDsc->csdIsSharedConst = isSharedConst;
682
668
}
683
669
684
- noway_assert (hashDsc->csdTreeList );
670
+ hashDsc->csdIsSharedConst = isSharedConst;
671
+ }
685
672
686
- /* Append this expression to the end of the list */
673
+ // Append this expression to the end of the list
687
674
688
- newElem = new (this , CMK_TreeStatementList) treeStmtLst;
675
+ treeStmtLst* newElem = new (this , CMK_TreeStatementList) treeStmtLst;
689
676
690
- newElem->tslTree = tree;
691
- newElem->tslStmt = stmt;
692
- newElem->tslBlock = compCurBB;
693
- newElem->tslNext = nullptr ;
677
+ newElem->tslTree = tree;
678
+ newElem->tslStmt = stmt;
679
+ newElem->tslBlock = compCurBB;
680
+ newElem->tslNext = nullptr ;
694
681
695
- hashDsc->csdTreeLast ->tslNext = newElem;
696
- hashDsc->csdTreeLast = newElem;
682
+ hashDsc->csdTreeLast ->tslNext = newElem;
683
+ hashDsc->csdTreeLast = newElem;
697
684
698
- optDoCSE = true ; // Found a duplicate CSE tree
685
+ optDoCSE = true ; // Found a duplicate CSE tree
699
686
700
- /* Have we assigned a CSE index? */
701
- if (hashDsc->csdIndex == 0 )
702
- {
703
- newCSE = true ;
704
- break ;
705
- }
706
-
707
- assert (FitsIn<signed char >(hashDsc->csdIndex ));
708
- tree->gtCSEnum = ((signed char )hashDsc->csdIndex );
709
- return hashDsc->csdIndex ;
687
+ /* Have we assigned a CSE index? */
688
+ if (hashDsc->csdIndex == 0 )
689
+ {
690
+ newCSE = true ;
691
+ break ;
710
692
}
693
+
694
+ assert (FitsIn<signed char >(hashDsc->csdIndex ));
695
+ tree->gtCSEnum = ((signed char )hashDsc->csdIndex );
696
+ return hashDsc->csdIndex ;
711
697
}
712
698
713
699
if (!newCSE)
@@ -763,10 +749,12 @@ unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt)
763
749
hashDsc->defExcSetPromise = vnStore->VNForEmptyExcSet ();
764
750
hashDsc->defExcSetCurrent = vnStore->VNForNull (); // uninit value
765
751
766
- hashDsc->csdTree = tree;
767
- hashDsc->csdStmt = stmt;
768
- hashDsc->csdBlock = compCurBB;
769
- hashDsc->csdTreeList = nullptr ;
752
+ hashDsc->csdTreeList .tslTree = tree;
753
+ hashDsc->csdTreeList .tslStmt = stmt;
754
+ hashDsc->csdTreeList .tslBlock = compCurBB;
755
+ hashDsc->csdTreeList .tslNext = nullptr ;
756
+
757
+ hashDsc->csdTreeLast = &hashDsc->csdTreeList ;
770
758
771
759
/* Append the entry to the hash bucket */
772
760
@@ -801,11 +789,11 @@ unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt)
801
789
hashDsc->csdIndex = CSEindex;
802
790
803
791
/* Update the gtCSEnum field in the original tree */
804
- noway_assert (hashDsc->csdTreeList -> tslTree ->gtCSEnum == 0 );
792
+ noway_assert (hashDsc->csdTreeList . tslTree ->gtCSEnum == 0 );
805
793
assert (FitsIn<signed char >(CSEindex));
806
794
807
- hashDsc->csdTreeList -> tslTree ->gtCSEnum = ((signed char )CSEindex);
808
- noway_assert (((unsigned )hashDsc->csdTreeList -> tslTree ->gtCSEnum ) == CSEindex);
795
+ hashDsc->csdTreeList . tslTree ->gtCSEnum = ((signed char )CSEindex);
796
+ noway_assert (((unsigned )hashDsc->csdTreeList . tslTree ->gtCSEnum ) == CSEindex);
809
797
810
798
tree->gtCSEnum = ((signed char )CSEindex);
811
799
@@ -975,7 +963,7 @@ void Compiler::optValnumCSE_InitDataFlow()
975
963
{
976
964
CSEdsc* dsc = optCSEtab[inx];
977
965
unsigned CSEindex = dsc->csdIndex ;
978
- treeStmtLst* lst = dsc->csdTreeList ;
966
+ treeStmtLst* lst = & dsc->csdTreeList ;
979
967
noway_assert (lst);
980
968
981
969
while (lst != nullptr )
@@ -1101,13 +1089,13 @@ void Compiler::optValnumCSE_SetUpAsyncByrefKills()
1101
1089
CSEdsc* dsc = optCSEtab[inx - 1 ];
1102
1090
assert (dsc->csdIndex == inx);
1103
1091
bool isByRef = false ;
1104
- if (dsc->csdTree ->TypeIs (TYP_BYREF))
1092
+ if (dsc->csdTreeList . tslTree ->TypeIs (TYP_BYREF))
1105
1093
{
1106
1094
isByRef = true ;
1107
1095
}
1108
- else if (dsc->csdTree ->TypeIs (TYP_STRUCT))
1096
+ else if (dsc->csdTreeList . tslTree ->TypeIs (TYP_STRUCT))
1109
1097
{
1110
- ClassLayout* layout = dsc->csdTree ->GetLayout (this );
1098
+ ClassLayout* layout = dsc->csdTreeList . tslTree ->GetLayout (this );
1111
1099
isByRef = layout->HasGCByRef ();
1112
1100
}
1113
1101
@@ -2528,14 +2516,14 @@ void CSE_HeuristicParameterized::GetFeatures(CSEdsc* cse, double* features)
2528
2516
return ;
2529
2517
}
2530
2518
2531
- const unsigned char costEx = cse->csdTree ->GetCostEx ();
2519
+ const unsigned char costEx = cse->csdTreeList . tslTree ->GetCostEx ();
2532
2520
const double deMinimis = 1e-3 ;
2533
2521
const double deMinimusAdj = -log (deMinimis);
2534
2522
2535
2523
features[0 ] = costEx;
2536
2524
features[1 ] = deMinimusAdj + log (max (deMinimis, cse->csdUseWtCnt ));
2537
2525
features[2 ] = deMinimusAdj + log (max (deMinimis, cse->csdDefWtCnt ));
2538
- features[3 ] = cse->csdTree ->GetCostSz ();
2526
+ features[3 ] = cse->csdTreeList . tslTree ->GetCostSz ();
2539
2527
features[4 ] = cse->csdUseCount ;
2540
2528
features[5 ] = cse->csdDefCount ;
2541
2529
@@ -2545,9 +2533,9 @@ void CSE_HeuristicParameterized::GetFeatures(CSEdsc* cse, double* features)
2545
2533
const bool isLiveAcrossCall = cse->csdLiveAcrossCall ;
2546
2534
2547
2535
features[6 ] = booleanScale * isLiveAcrossCall;
2548
- features[7 ] = booleanScale * varTypeUsesIntReg (cse->csdTree ->TypeGet ());
2536
+ features[7 ] = booleanScale * varTypeUsesIntReg (cse->csdTreeList . tslTree ->TypeGet ());
2549
2537
2550
- const bool isConstant = cse->csdTree ->OperIsConst ();
2538
+ const bool isConstant = cse->csdTreeList . tslTree ->OperIsConst ();
2551
2539
const bool isSharedConstant = cse->csdIsSharedConst ;
2552
2540
2553
2541
features[8 ] = booleanScale * (isConstant & !isSharedConstant);
@@ -2573,7 +2561,7 @@ void CSE_HeuristicParameterized::GetFeatures(CSEdsc* cse, double* features)
2573
2561
unsigned maxPostorderNum = 0 ;
2574
2562
BasicBlock* minPostorderBlock = nullptr ;
2575
2563
BasicBlock* maxPostorderBlock = nullptr ;
2576
- for (treeStmtLst* treeList = cse->csdTreeList ; treeList != nullptr ; treeList = treeList->tslNext )
2564
+ for (treeStmtLst* treeList = & cse->csdTreeList ; treeList != nullptr ; treeList = treeList->tslNext )
2577
2565
{
2578
2566
BasicBlock* const treeBlock = treeList->tslBlock ;
2579
2567
unsigned postorderNum = treeBlock->bbPostorderNum ;
@@ -2602,12 +2590,12 @@ void CSE_HeuristicParameterized::GetFeatures(CSEdsc* cse, double* features)
2602
2590
2603
2591
// More
2604
2592
//
2605
- features[17 ] = booleanScale * ((cse->csdTree ->gtFlags & GTF_CALL) != 0 );
2593
+ features[17 ] = booleanScale * ((cse->csdTreeList . tslTree ->gtFlags & GTF_CALL) != 0 );
2606
2594
features[18 ] = deMinimusAdj + log (max (deMinimis, cse->csdUseCount * cse->csdUseWtCnt ));
2607
2595
features[19 ] = deMinimusAdj + log (max (deMinimis, cse->numLocalOccurrences * cse->csdUseWtCnt ));
2608
2596
features[20 ] = booleanScale * ((double )(blockSpread) / numBBs);
2609
2597
2610
- const bool isContainable = cse->csdTree ->OperIs (GT_ADD, GT_NOT, GT_MUL, GT_LSH);
2598
+ const bool isContainable = cse->csdTreeList . tslTree ->OperIs (GT_ADD, GT_NOT, GT_MUL, GT_LSH);
2611
2599
features[21 ] = booleanScale * isContainable;
2612
2600
features[22 ] = booleanScale * (isContainable && isLowCost);
2613
2601
@@ -3172,7 +3160,7 @@ void CSE_HeuristicRLHook::GetFeatures(CSEdsc* cse, int* features)
3172
3160
unsigned maxPostorderNum = 0 ;
3173
3161
BasicBlock* minPostorderBlock = nullptr ;
3174
3162
BasicBlock* maxPostorderBlock = nullptr ;
3175
- for (treeStmtLst* treeList = cse->csdTreeList ; treeList != nullptr ; treeList = treeList->tslNext )
3163
+ for (treeStmtLst* treeList = & cse->csdTreeList ; treeList != nullptr ; treeList = treeList->tslNext )
3176
3164
{
3177
3165
BasicBlock* const treeBlock = treeList->tslBlock ;
3178
3166
unsigned postorderNum = treeBlock->bbPostorderNum ;
@@ -3232,13 +3220,13 @@ void CSE_HeuristicRLHook::GetFeatures(CSEdsc* cse, int* features)
3232
3220
features[i++] = type;
3233
3221
features[i++] = cse->IsViable () ? 1 : 0 ;
3234
3222
features[i++] = cse->csdLiveAcrossCall ? 1 : 0 ;
3235
- features[i++] = cse->csdTree ->OperIsConst () ? 1 : 0 ;
3223
+ features[i++] = cse->csdTreeList . tslTree ->OperIsConst () ? 1 : 0 ;
3236
3224
features[i++] = cse->csdIsSharedConst ? 1 : 0 ;
3237
3225
features[i++] = isMakeCse ? 1 : 0 ;
3238
- features[i++] = ((cse->csdTree ->gtFlags & GTF_CALL) != 0 ) ? 1 : 0 ;
3239
- features[i++] = cse->csdTree ->OperIs (GT_ADD, GT_NOT, GT_MUL, GT_LSH) ? 1 : 0 ;
3240
- features[i++] = cse->csdTree ->GetCostEx ();
3241
- features[i++] = cse->csdTree ->GetCostSz ();
3226
+ features[i++] = ((cse->csdTreeList . tslTree ->gtFlags & GTF_CALL) != 0 ) ? 1 : 0 ;
3227
+ features[i++] = cse->csdTreeList . tslTree ->OperIs (GT_ADD, GT_NOT, GT_MUL, GT_LSH) ? 1 : 0 ;
3228
+ features[i++] = cse->csdTreeList . tslTree ->GetCostEx ();
3229
+ features[i++] = cse->csdTreeList . tslTree ->GetCostSz ();
3242
3230
features[i++] = cse->csdUseCount ;
3243
3231
features[i++] = cse->csdDefCount ;
3244
3232
features[i++] = (int )cse->csdUseWtCnt ;
@@ -4271,7 +4259,7 @@ void CSE_Heuristic::SortCandidates()
4271
4259
for (unsigned cnt = 0 ; cnt < m_pCompiler->optCSECandidateCount ; cnt++)
4272
4260
{
4273
4261
CSEdsc* dsc = sortTab[cnt];
4274
- GenTree* expr = dsc->csdTree ;
4262
+ GenTree* expr = dsc->csdTreeList . tslTree ;
4275
4263
4276
4264
weight_t def;
4277
4265
weight_t use;
@@ -4281,13 +4269,13 @@ void CSE_Heuristic::SortCandidates()
4281
4269
{
4282
4270
def = dsc->csdDefCount ; // def count
4283
4271
use = dsc->csdUseCount ; // use count (excluding the implicit uses at defs)
4284
- cost = dsc->csdTree ->GetCostSz ();
4272
+ cost = dsc->csdTreeList . tslTree ->GetCostSz ();
4285
4273
}
4286
4274
else
4287
4275
{
4288
4276
def = dsc->csdDefWtCnt ; // weighted def count
4289
4277
use = dsc->csdUseWtCnt ; // weighted use count (excluding the implicit uses at defs)
4290
- cost = dsc->csdTree ->GetCostEx ();
4278
+ cost = dsc->csdTreeList . tslTree ->GetCostEx ();
4291
4279
}
4292
4280
4293
4281
if (!Compiler::Is_Shared_Const_CSE (dsc->csdHashKey ))
@@ -4840,7 +4828,7 @@ void CSE_HeuristicCommon::PerformCSE(CSE_Candidate* successfulCandidate)
4840
4828
ValueNum bestVN = ValueNumStore::NoVN;
4841
4829
bool bestIsDef = false ;
4842
4830
ssize_t bestConstValue = 0 ;
4843
- treeStmtLst* lst = dsc->csdTreeList ;
4831
+ treeStmtLst* lst = & dsc->csdTreeList ;
4844
4832
4845
4833
while (lst != nullptr )
4846
4834
{
@@ -4931,7 +4919,7 @@ void CSE_HeuristicCommon::PerformCSE(CSE_Candidate* successfulCandidate)
4931
4919
}
4932
4920
else // !isSharedConst
4933
4921
{
4934
- lst = dsc->csdTreeList ;
4922
+ lst = & dsc->csdTreeList ;
4935
4923
GenTree* firstTree = lst->tslTree ;
4936
4924
printf (" In %s, CSE (oper = %s, type = %s) has differing VNs: " , m_pCompiler->info .compFullName ,
4937
4925
GenTree::OpName (firstTree->OperGet ()), varTypeName (firstTree->TypeGet ()));
@@ -4956,7 +4944,7 @@ void CSE_HeuristicCommon::PerformCSE(CSE_Candidate* successfulCandidate)
4956
4944
ArrayStack<UseDefLocation> defUses (m_pCompiler->getAllocator (CMK_CSE));
4957
4945
4958
4946
// First process the defs.
4959
- for (lst = dsc->csdTreeList ; lst != nullptr ; lst = lst->tslNext )
4947
+ for (lst = & dsc->csdTreeList ; lst != nullptr ; lst = lst->tslNext )
4960
4948
{
4961
4949
GenTree* const exp = lst->tslTree ;
4962
4950
Statement* const stmt = lst->tslStmt ;
@@ -5065,7 +5053,7 @@ void CSE_HeuristicCommon::PerformCSE(CSE_Candidate* successfulCandidate)
5065
5053
}
5066
5054
5067
5055
// Now process the actual uses.
5068
- for (lst = dsc->csdTreeList ; lst != nullptr ; lst = lst->tslNext )
5056
+ for (lst = & dsc->csdTreeList ; lst != nullptr ; lst = lst->tslNext )
5069
5057
{
5070
5058
GenTree* const exp = lst->tslTree ;
5071
5059
Statement* const stmt = lst->tslStmt ;
0 commit comments