Skip to content

Commit f2d4bb6

Browse files
[GISel][CombinerHelper] Add a function that chains a list of generators together
1 parent 70eb536 commit f2d4bb6

File tree

1 file changed

+39
-23
lines changed

1 file changed

+39
-23
lines changed

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,21 @@ adderGenerator(const int32_t From, const int32_t To, const int32_t StepSize) {
398398
};
399399
}
400400

401+
// Move to the next generator if it is exhausted allowing to chain generators
402+
std::function<std::optional<int32_t>()> concatGenerators(
403+
SmallVector<std::function<std::optional<int32_t>()>> Generators) {
404+
auto *GeneratorIterator = Generators.begin();
405+
406+
return [GeneratorIterator, Generators]() mutable {
407+
std::optional<int32_t> GenValue = (*GeneratorIterator)();
408+
if (!GenValue.has_value() && GeneratorIterator != Generators.end()) {
409+
GeneratorIterator++;
410+
GenValue = (*GeneratorIterator)();
411+
}
412+
return GenValue;
413+
};
414+
}
415+
401416
Register CombinerHelper::createUnmergeValue(
402417
MachineInstr &MI, const Register SrcReg, const Register DstReg,
403418
const uint8_t DestinationIndex, const uint32_t Start, const uint32_t End) {
@@ -419,31 +434,32 @@ Register CombinerHelper::createUnmergeValue(
419434
TargetReg = MRI.createGenericVirtualRegister(HalfSizeTy);
420435
}
421436

422-
// Each destination fits n times into the source and each iteration we exactly
423-
// half the source. Therefore we need to pick on which side we want to iterate
424-
// on.
425-
const uint32_t DstNumElements = DstTy.isVector() ? DstTy.getNumElements() : 1;
426-
const uint32_t HalfWay = Start + ((End - Start) / 2);
427-
const uint32_t Position = DestinationIndex * DstNumElements;
428-
429-
uint32_t NextStart, NextEnd;
430-
if (Position < HalfWay) {
431-
Builder.buildInstr(TargetOpcode::G_UNMERGE_VALUES, {TargetReg, TmpReg},
432-
{SrcReg});
433-
NextStart = Start;
434-
NextEnd = HalfWay;
435-
} else {
436-
Builder.buildInstr(TargetOpcode::G_UNMERGE_VALUES, {TmpReg, TargetReg},
437-
{SrcReg});
438-
NextStart = HalfWay;
439-
NextEnd = End;
440-
}
437+
// Each destination fits n times into the source and each iteration we
438+
// exactly half the source. Therefore we need to pick on which side we want
439+
// to iterate on.
440+
const uint32_t DstNumElements =
441+
DstTy.isVector() ? DstTy.getNumElements() : 1;
442+
const uint32_t HalfWay = Start + ((End - Start) / 2);
443+
const uint32_t Position = DestinationIndex * DstNumElements;
444+
445+
uint32_t NextStart, NextEnd;
446+
if (Position < HalfWay) {
447+
Builder.buildInstr(TargetOpcode::G_UNMERGE_VALUES, {TargetReg, TmpReg},
448+
{SrcReg});
449+
NextStart = Start;
450+
NextEnd = HalfWay;
451+
} else {
452+
Builder.buildInstr(TargetOpcode::G_UNMERGE_VALUES, {TmpReg, TargetReg},
453+
{SrcReg});
454+
NextStart = HalfWay;
455+
NextEnd = End;
456+
}
441457

442-
if (HalfSizeTy.isVector() && DstTy != HalfSizeTy)
443-
return createUnmergeValue(MI, TargetReg, DstReg, DestinationIndex,
444-
NextStart, NextEnd);
458+
if (HalfSizeTy.isVector() && DstTy != HalfSizeTy)
459+
return createUnmergeValue(MI, TargetReg, DstReg, DestinationIndex,
460+
NextStart, NextEnd);
445461

446-
return DstReg;
462+
return DstReg;
447463
}
448464

449465
bool CombinerHelper::tryCombineShuffleVector(MachineInstr &MI) {

0 commit comments

Comments
 (0)