@@ -795,16 +795,6 @@ struct InstructionsState {
795
795
796
796
} // end anonymous namespace
797
797
798
- /// Chooses the correct key for scheduling data. If \p Op has the same (or
799
- /// alternate) opcode as \p OpValue, the key is \p Op. Otherwise the key is \p
800
- /// OpValue.
801
- static Value *isOneOf(const InstructionsState &S, Value *Op) {
802
- auto *I = dyn_cast<Instruction>(Op);
803
- if (I && S.isOpcodeOrAlt(I))
804
- return Op;
805
- return S.OpValue;
806
- }
807
-
808
798
/// \returns true if \p Opcode is allowed as part of the main/alternate
809
799
/// instruction for SLP vectorization.
810
800
///
@@ -3583,14 +3573,14 @@ class BoUpSLP {
3583
3573
3584
3574
ScheduleData() = default;
3585
3575
3586
- void init(int BlockSchedulingRegionID, Value *OpVal ) {
3576
+ void init(int BlockSchedulingRegionID, Instruction *I ) {
3587
3577
FirstInBundle = this;
3588
3578
NextInBundle = nullptr;
3589
3579
NextLoadStore = nullptr;
3590
3580
IsScheduled = false;
3591
3581
SchedulingRegionID = BlockSchedulingRegionID;
3592
3582
clearDependencies();
3593
- OpValue = OpVal ;
3583
+ Inst = I ;
3594
3584
TE = nullptr;
3595
3585
}
3596
3586
@@ -3696,9 +3686,6 @@ class BoUpSLP {
3696
3686
3697
3687
Instruction *Inst = nullptr;
3698
3688
3699
- /// Opcode of the current instruction in the schedule data.
3700
- Value *OpValue = nullptr;
3701
-
3702
3689
/// The TreeEntry that this instruction corresponds to.
3703
3690
TreeEntry *TE = nullptr;
3704
3691
@@ -3815,18 +3802,6 @@ class BoUpSLP {
3815
3802
return nullptr;
3816
3803
}
3817
3804
3818
- ScheduleData *getScheduleData(Value *V, Value *Key) {
3819
- if (V == Key)
3820
- return getScheduleData(V);
3821
- auto I = ExtraScheduleDataMap.find(V);
3822
- if (I != ExtraScheduleDataMap.end()) {
3823
- ScheduleData *SD = I->second.lookup(Key);
3824
- if (SD && isInSchedulingRegion(SD))
3825
- return SD;
3826
- }
3827
- return nullptr;
3828
- }
3829
-
3830
3805
bool isInSchedulingRegion(ScheduleData *SD) const {
3831
3806
return SD->SchedulingRegionID == SchedulingRegionID;
3832
3807
}
@@ -3840,27 +3815,24 @@ class BoUpSLP {
3840
3815
3841
3816
for (ScheduleData *BundleMember = SD; BundleMember;
3842
3817
BundleMember = BundleMember->NextInBundle) {
3843
- if (BundleMember->Inst != BundleMember->OpValue)
3844
- continue;
3845
3818
3846
3819
// Handle the def-use chain dependencies.
3847
3820
3848
3821
// Decrement the unscheduled counter and insert to ready list if ready.
3849
3822
auto &&DecrUnsched = [this, &ReadyList](Instruction *I) {
3850
- doForAllOpcodes(I, [&ReadyList](ScheduleData *OpDef) {
3851
- if (OpDef && OpDef->hasValidDependencies() &&
3852
- OpDef->incrementUnscheduledDeps(-1) == 0) {
3853
- // There are no more unscheduled dependencies after
3854
- // decrementing, so we can put the dependent instruction
3855
- // into the ready list.
3856
- ScheduleData *DepBundle = OpDef->FirstInBundle;
3857
- assert(!DepBundle->IsScheduled &&
3858
- "already scheduled bundle gets ready");
3859
- ReadyList.insert(DepBundle);
3860
- LLVM_DEBUG(dbgs()
3861
- << "SLP: gets ready (def): " << *DepBundle << "\n");
3862
- }
3863
- });
3823
+ ScheduleData *OpDef = getScheduleData(I);
3824
+ if (OpDef && OpDef->hasValidDependencies() &&
3825
+ OpDef->incrementUnscheduledDeps(-1) == 0) {
3826
+ // There are no more unscheduled dependencies after
3827
+ // decrementing, so we can put the dependent instruction
3828
+ // into the ready list.
3829
+ ScheduleData *DepBundle = OpDef->FirstInBundle;
3830
+ assert(!DepBundle->IsScheduled &&
3831
+ "already scheduled bundle gets ready");
3832
+ ReadyList.insert(DepBundle);
3833
+ LLVM_DEBUG(dbgs()
3834
+ << "SLP: gets ready (def): " << *DepBundle << "\n");
3835
+ }
3864
3836
};
3865
3837
3866
3838
// If BundleMember is a vector bundle, its operands may have been
@@ -3944,8 +3916,7 @@ class BoUpSLP {
3944
3916
"primary schedule data not in window?");
3945
3917
assert(isInSchedulingRegion(SD->FirstInBundle) &&
3946
3918
"entire bundle in window!");
3947
- (void)SD;
3948
- doForAllOpcodes(I, [](ScheduleData *SD) { SD->verify(); });
3919
+ SD->verify();
3949
3920
}
3950
3921
3951
3922
for (auto *SD : ReadyInsts) {
@@ -3955,29 +3926,17 @@ class BoUpSLP {
3955
3926
}
3956
3927
}
3957
3928
3958
- void doForAllOpcodes(Value *V,
3959
- function_ref<void(ScheduleData *SD)> Action) {
3960
- if (ScheduleData *SD = getScheduleData(V))
3961
- Action(SD);
3962
- auto I = ExtraScheduleDataMap.find(V);
3963
- if (I != ExtraScheduleDataMap.end())
3964
- for (auto &P : I->second)
3965
- if (isInSchedulingRegion(P.second))
3966
- Action(P.second);
3967
- }
3968
-
3969
3929
/// Put all instructions into the ReadyList which are ready for scheduling.
3970
3930
template <typename ReadyListType>
3971
3931
void initialFillReadyList(ReadyListType &ReadyList) {
3972
3932
for (auto *I = ScheduleStart; I != ScheduleEnd; I = I->getNextNode()) {
3973
- doForAllOpcodes(I, [&](ScheduleData *SD) {
3974
- if (SD->isSchedulingEntity() && SD->hasValidDependencies() &&
3975
- SD->isReady()) {
3976
- ReadyList.insert(SD);
3977
- LLVM_DEBUG(dbgs()
3978
- << "SLP: initially in ready list: " << *SD << "\n");
3979
- }
3980
- });
3933
+ ScheduleData *SD = getScheduleData(I);
3934
+ if (SD && SD->isSchedulingEntity() && SD->hasValidDependencies() &&
3935
+ SD->isReady()) {
3936
+ ReadyList.insert(SD);
3937
+ LLVM_DEBUG(dbgs()
3938
+ << "SLP: initially in ready list: " << *SD << "\n");
3939
+ }
3981
3940
}
3982
3941
}
3983
3942
@@ -4035,10 +3994,6 @@ class BoUpSLP {
4035
3994
/// ScheduleData structures are recycled.
4036
3995
DenseMap<Instruction *, ScheduleData *> ScheduleDataMap;
4037
3996
4038
- /// Attaches ScheduleData to Instruction with the leading key.
4039
- DenseMap<Value *, SmallDenseMap<Value *, ScheduleData *>>
4040
- ExtraScheduleDataMap;
4041
-
4042
3997
/// The ready-list for scheduling (only used for the dry-run).
4043
3998
SetVector<ScheduleData *> ReadyInsts;
4044
3999
@@ -11898,8 +11853,7 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
11898
11853
auto *Bundle = BlocksSchedules[BB]->getScheduleData(V);
11899
11854
if (Bundle && Bundle->isPartOfBundle())
11900
11855
for (; Bundle; Bundle = Bundle->NextInBundle)
11901
- if (Bundle->OpValue == Bundle->Inst)
11902
- Res.second = Bundle->Inst;
11856
+ Res.second = Bundle->Inst;
11903
11857
}
11904
11858
11905
11859
// LastInst can still be null at this point if there's either not an entry
@@ -14966,7 +14920,8 @@ BoUpSLP::BlockScheduling::tryScheduleBundle(ArrayRef<Value *> VL, BoUpSLP *SLP,
14966
14920
// initial bundle to the region.
14967
14921
if (ScheduleEnd != OldScheduleEnd) {
14968
14922
for (auto *I = ScheduleStart; I != ScheduleEnd; I = I->getNextNode())
14969
- doForAllOpcodes(I, [](ScheduleData *SD) { SD->clearDependencies(); });
14923
+ if (ScheduleData *SD = getScheduleData(I))
14924
+ SD->clearDependencies();
14970
14925
ReSchedule = true;
14971
14926
}
14972
14927
if (Bundle) {
@@ -15085,37 +15040,21 @@ BoUpSLP::ScheduleData *BoUpSLP::BlockScheduling::allocateScheduleDataChunks() {
15085
15040
return &(ScheduleDataChunks.back()[ChunkPos++]);
15086
15041
}
15087
15042
15088
- bool BoUpSLP::BlockScheduling::extendSchedulingRegion(Value *V,
15089
- const InstructionsState &S) {
15090
- if (getScheduleData(V, isOneOf(S, V)))
15091
- return true;
15043
+ bool BoUpSLP::BlockScheduling::extendSchedulingRegion(
15044
+ Value *V, const InstructionsState &S) {
15092
15045
Instruction *I = dyn_cast<Instruction>(V);
15093
15046
assert(I && "bundle member must be an instruction");
15094
15047
assert(!isa<PHINode>(I) && !isVectorLikeInstWithConstOps(I) &&
15095
15048
!doesNotNeedToBeScheduled(I) &&
15096
15049
"phi nodes/insertelements/extractelements/extractvalues don't need to "
15097
15050
"be scheduled");
15098
- auto &&CheckScheduleForI = [this, &S](Instruction *I) -> bool {
15099
- ScheduleData *ISD = getScheduleData(I);
15100
- if (!ISD)
15101
- return false;
15102
- assert(isInSchedulingRegion(ISD) &&
15103
- "ScheduleData not in scheduling region");
15104
- ScheduleData *SD = allocateScheduleDataChunks();
15105
- SD->Inst = I;
15106
- SD->init(SchedulingRegionID, S.OpValue);
15107
- ExtraScheduleDataMap[I][S.OpValue] = SD;
15108
- return true;
15109
- };
15110
- if (CheckScheduleForI(I))
15051
+ if (getScheduleData(I))
15111
15052
return true;
15112
15053
if (!ScheduleStart) {
15113
15054
// It's the first instruction in the new region.
15114
15055
initScheduleData(I, I->getNextNode(), nullptr, nullptr);
15115
15056
ScheduleStart = I;
15116
15057
ScheduleEnd = I->getNextNode();
15117
- if (isOneOf(S, I) != I)
15118
- CheckScheduleForI(I);
15119
15058
assert(ScheduleEnd && "tried to vectorize a terminator?");
15120
15059
LLVM_DEBUG(dbgs() << "SLP: initialize schedule region to " << *I << "\n");
15121
15060
return true;
@@ -15154,8 +15093,6 @@ bool BoUpSLP::BlockScheduling::extendSchedulingRegion(Value *V,
15154
15093
"Instruction is in wrong basic block.");
15155
15094
initScheduleData(I, ScheduleStart, nullptr, FirstLoadStoreInRegion);
15156
15095
ScheduleStart = I;
15157
- if (isOneOf(S, I) != I)
15158
- CheckScheduleForI(I);
15159
15096
LLVM_DEBUG(dbgs() << "SLP: extend schedule region start to " << *I
15160
15097
<< "\n");
15161
15098
return true;
@@ -15168,8 +15105,6 @@ bool BoUpSLP::BlockScheduling::extendSchedulingRegion(Value *V,
15168
15105
initScheduleData(ScheduleEnd, I->getNextNode(), LastLoadStoreInRegion,
15169
15106
nullptr);
15170
15107
ScheduleEnd = I->getNextNode();
15171
- if (isOneOf(S, I) != I)
15172
- CheckScheduleForI(I);
15173
15108
assert(ScheduleEnd && "tried to vectorize a terminator?");
15174
15109
LLVM_DEBUG(dbgs() << "SLP: extend schedule region end to " << *I << "\n");
15175
15110
return true;
@@ -15188,7 +15123,6 @@ void BoUpSLP::BlockScheduling::initScheduleData(Instruction *FromI,
15188
15123
if (!SD) {
15189
15124
SD = allocateScheduleDataChunks();
15190
15125
ScheduleDataMap[I] = SD;
15191
- SD->Inst = I;
15192
15126
}
15193
15127
assert(!isInSchedulingRegion(SD) &&
15194
15128
"new ScheduleData already in scheduling region");
@@ -15242,26 +15176,15 @@ void BoUpSLP::BlockScheduling::calculateDependencies(ScheduleData *SD,
15242
15176
BundleMember->resetUnscheduledDeps();
15243
15177
15244
15178
// Handle def-use chain dependencies.
15245
- if (BundleMember->OpValue != BundleMember->Inst) {
15246
- if (ScheduleData *UseSD = getScheduleData(BundleMember->Inst )) {
15179
+ for (User *U : BundleMember->Inst->users() ) {
15180
+ if (ScheduleData *UseSD = getScheduleData(cast<Instruction>(U) )) {
15247
15181
BundleMember->Dependencies++;
15248
15182
ScheduleData *DestBundle = UseSD->FirstInBundle;
15249
15183
if (!DestBundle->IsScheduled)
15250
15184
BundleMember->incrementUnscheduledDeps(1);
15251
15185
if (!DestBundle->hasValidDependencies())
15252
15186
WorkList.push_back(DestBundle);
15253
15187
}
15254
- } else {
15255
- for (User *U : BundleMember->Inst->users()) {
15256
- if (ScheduleData *UseSD = getScheduleData(cast<Instruction>(U))) {
15257
- BundleMember->Dependencies++;
15258
- ScheduleData *DestBundle = UseSD->FirstInBundle;
15259
- if (!DestBundle->IsScheduled)
15260
- BundleMember->incrementUnscheduledDeps(1);
15261
- if (!DestBundle->hasValidDependencies())
15262
- WorkList.push_back(DestBundle);
15263
- }
15264
- }
15265
15188
}
15266
15189
15267
15190
auto MakeControlDependent = [&](Instruction *I) {
@@ -15409,12 +15332,12 @@ void BoUpSLP::BlockScheduling::resetSchedule() {
15409
15332
assert(ScheduleStart &&
15410
15333
"tried to reset schedule on block which has not been scheduled");
15411
15334
for (Instruction *I = ScheduleStart; I != ScheduleEnd; I = I->getNextNode()) {
15412
- doForAllOpcodes(I, [&] (ScheduleData *SD) {
15335
+ if (ScheduleData *SD = getScheduleData(I) ) {
15413
15336
assert(isInSchedulingRegion(SD) &&
15414
15337
"ScheduleData not in scheduling region");
15415
15338
SD->IsScheduled = false;
15416
15339
SD->resetUnscheduledDeps();
15417
- });
15340
+ }
15418
15341
}
15419
15342
ReadyInsts.clear();
15420
15343
}
@@ -15449,7 +15372,7 @@ void BoUpSLP::scheduleBlock(BlockScheduling *BS) {
15449
15372
int Idx = 0;
15450
15373
for (auto *I = BS->ScheduleStart; I != BS->ScheduleEnd;
15451
15374
I = I->getNextNode()) {
15452
- BS->doForAllOpcodes(I, [this, &Idx, BS] (ScheduleData *SD) {
15375
+ if (ScheduleData *SD = BS->getScheduleData(I) ) {
15453
15376
TreeEntry *SDTE = getTreeEntry(SD->Inst);
15454
15377
(void)SDTE;
15455
15378
assert((isVectorLikeInstWithConstOps(SD->Inst) ||
@@ -15460,7 +15383,7 @@ void BoUpSLP::scheduleBlock(BlockScheduling *BS) {
15460
15383
15461
15384
if (SD->isSchedulingEntity() && SD->isPartOfBundle())
15462
15385
BS->calculateDependencies(SD, false, this);
15463
- });
15386
+ }
15464
15387
}
15465
15388
BS->initialFillReadyList(ReadyInsts);
15466
15389
@@ -15492,11 +15415,9 @@ void BoUpSLP::scheduleBlock(BlockScheduling *BS) {
15492
15415
#if !defined(NDEBUG) || defined(EXPENSIVE_CHECKS)
15493
15416
// Check that all schedulable entities got scheduled
15494
15417
for (auto *I = BS->ScheduleStart; I != BS->ScheduleEnd; I = I->getNextNode()) {
15495
- BS->doForAllOpcodes(I, [&](ScheduleData *SD) {
15496
- if (SD->isSchedulingEntity() && SD->hasValidDependencies()) {
15497
- assert(SD->IsScheduled && "must be scheduled at this point");
15498
- }
15499
- });
15418
+ ScheduleData *SD = BS->getScheduleData(I);
15419
+ if (SD && SD->isSchedulingEntity() && SD->hasValidDependencies())
15420
+ assert(SD->IsScheduled && "must be scheduled at this point");
15500
15421
}
15501
15422
#endif
15502
15423
0 commit comments