@@ -546,19 +546,25 @@ static std::set<Value *> getBaseValues(Value *V,
546
546
static bool
547
547
checkHoistValue (Value *V, Instruction *InsertPoint, DominatorTree &DT,
548
548
DenseSet<Instruction *> &Unhoistables,
549
- DenseSet<Instruction *> *HoistStops) {
549
+ DenseSet<Instruction *> *HoistStops,
550
+ DenseMap<Instruction *, bool > &Visited) {
550
551
assert (InsertPoint && " Null InsertPoint" );
551
552
if (auto *I = dyn_cast<Instruction>(V)) {
553
+ if (Visited.count (I)) {
554
+ return Visited[I];
555
+ }
552
556
assert (DT.getNode (I->getParent ()) && " DT must contain I's parent block" );
553
557
assert (DT.getNode (InsertPoint->getParent ()) && " DT must contain Destination" );
554
558
if (Unhoistables.count (I)) {
555
559
// Don't hoist if they are not to be hoisted.
560
+ Visited[I] = false ;
556
561
return false ;
557
562
}
558
563
if (DT.dominates (I, InsertPoint)) {
559
564
// We are already above the insert point. Stop here.
560
565
if (HoistStops)
561
566
HoistStops->insert (I);
567
+ Visited[I] = true ;
562
568
return true ;
563
569
}
564
570
// We aren't not above the insert point, check if we can hoist it above the
@@ -568,7 +574,8 @@ checkHoistValue(Value *V, Instruction *InsertPoint, DominatorTree &DT,
568
574
DenseSet<Instruction *> OpsHoistStops;
569
575
bool AllOpsHoisted = true ;
570
576
for (Value *Op : I->operands ()) {
571
- if (!checkHoistValue (Op, InsertPoint, DT, Unhoistables, &OpsHoistStops)) {
577
+ if (!checkHoistValue (Op, InsertPoint, DT, Unhoistables, &OpsHoistStops,
578
+ Visited)) {
572
579
AllOpsHoisted = false ;
573
580
break ;
574
581
}
@@ -577,9 +584,11 @@ checkHoistValue(Value *V, Instruction *InsertPoint, DominatorTree &DT,
577
584
CHR_DEBUG (dbgs () << " checkHoistValue " << *I << " \n " );
578
585
if (HoistStops)
579
586
HoistStops->insert (OpsHoistStops.begin (), OpsHoistStops.end ());
587
+ Visited[I] = true ;
580
588
return true ;
581
589
}
582
590
}
591
+ Visited[I] = false ;
583
592
return false ;
584
593
}
585
594
// Non-instructions are considered hoistable.
@@ -892,8 +901,9 @@ void CHR::checkScopeHoistable(CHRScope *Scope) {
892
901
++it;
893
902
continue ;
894
903
}
904
+ DenseMap<Instruction *, bool > Visited;
895
905
bool IsHoistable = checkHoistValue (SI->getCondition (), InsertPoint,
896
- DT, Unhoistables, nullptr );
906
+ DT, Unhoistables, nullptr , Visited );
897
907
if (!IsHoistable) {
898
908
CHR_DEBUG (dbgs () << " Dropping select " << *SI << " \n " );
899
909
ORE.emit ([&]() {
@@ -912,8 +922,9 @@ void CHR::checkScopeHoistable(CHRScope *Scope) {
912
922
InsertPoint = getBranchInsertPoint (RI);
913
923
CHR_DEBUG (dbgs () << " InsertPoint " << *InsertPoint << " \n " );
914
924
if (RI.HasBranch && InsertPoint != Branch) {
925
+ DenseMap<Instruction *, bool > Visited;
915
926
bool IsHoistable = checkHoistValue (Branch->getCondition (), InsertPoint,
916
- DT, Unhoistables, nullptr );
927
+ DT, Unhoistables, nullptr , Visited );
917
928
if (!IsHoistable) {
918
929
// If the branch isn't hoistable, drop the selects in the entry
919
930
// block, preferring the branch, which makes the branch the hoist
@@ -944,15 +955,17 @@ void CHR::checkScopeHoistable(CHRScope *Scope) {
944
955
if (RI.HasBranch ) {
945
956
assert (!DT.dominates (Branch, InsertPoint) &&
946
957
" Branch can't be already above the hoist point" );
958
+ DenseMap<Instruction *, bool > Visited;
947
959
assert (checkHoistValue (Branch->getCondition (), InsertPoint,
948
- DT, Unhoistables, nullptr ) &&
960
+ DT, Unhoistables, nullptr , Visited ) &&
949
961
" checkHoistValue for branch" );
950
962
}
951
963
for (auto *SI : Selects) {
952
964
assert (!DT.dominates (SI, InsertPoint) &&
953
965
" SI can't be already above the hoist point" );
966
+ DenseMap<Instruction *, bool > Visited;
954
967
assert (checkHoistValue (SI->getCondition (), InsertPoint, DT,
955
- Unhoistables, nullptr ) &&
968
+ Unhoistables, nullptr , Visited ) &&
956
969
" checkHoistValue for selects" );
957
970
}
958
971
CHR_DEBUG (dbgs () << " Result\n " );
@@ -1053,7 +1066,8 @@ static bool shouldSplit(Instruction *InsertPoint,
1053
1066
assert (InsertPoint && " Null InsertPoint" );
1054
1067
// If any of Bases isn't hoistable to the hoist point, split.
1055
1068
for (Value *V : ConditionValues) {
1056
- if (!checkHoistValue (V, InsertPoint, DT, Unhoistables, nullptr )) {
1069
+ DenseMap<Instruction *, bool > Visited;
1070
+ if (!checkHoistValue (V, InsertPoint, DT, Unhoistables, nullptr , Visited)) {
1057
1071
CHR_DEBUG (dbgs () << " Split. checkHoistValue false " << *V << " \n " );
1058
1072
return true ; // Not hoistable, split.
1059
1073
}
@@ -1382,8 +1396,9 @@ void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
1382
1396
" Must be truthy or falsy" );
1383
1397
auto *BI = cast<BranchInst>(R->getEntry ()->getTerminator ());
1384
1398
// Note checkHoistValue fills in HoistStops.
1399
+ DenseMap<Instruction *, bool > Visited;
1385
1400
bool IsHoistable = checkHoistValue (BI->getCondition (), InsertPoint, DT,
1386
- Unhoistables, &HoistStops);
1401
+ Unhoistables, &HoistStops, Visited );
1387
1402
assert (IsHoistable && " Must be hoistable" );
1388
1403
(void )(IsHoistable); // Unused in release build
1389
1404
IsHoisted = true ;
@@ -1393,8 +1408,9 @@ void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
1393
1408
OutermostScope->FalseBiasedSelects .count (SI) > 0 ) &&
1394
1409
" Must be true or false biased" );
1395
1410
// Note checkHoistValue fills in HoistStops.
1411
+ DenseMap<Instruction *, bool > Visited;
1396
1412
bool IsHoistable = checkHoistValue (SI->getCondition (), InsertPoint, DT,
1397
- Unhoistables, &HoistStops);
1413
+ Unhoistables, &HoistStops, Visited );
1398
1414
assert (IsHoistable && " Must be hoistable" );
1399
1415
(void )(IsHoistable); // Unused in release build
1400
1416
IsHoisted = true ;
0 commit comments