Skip to content

Commit fcfe1b6

Browse files
authored
[GlobalISel] Refactor extractParts() (#75223)
Moved extractParts() and extractVectorParts() from LegalizerHelper to Utils to be able to use it in different passes. extractParts() will also try to use unmerge when doing irregular splits where possible, falling back to extract elements when not.
1 parent 62b7e35 commit fcfe1b6

File tree

7 files changed

+279
-202
lines changed

7 files changed

+279
-202
lines changed

llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -187,22 +187,6 @@ class LegalizerHelper {
187187
LegalizeResult widenScalarMulo(MachineInstr &MI, unsigned TypeIdx,
188188
LLT WideTy);
189189

190-
/// Helper function to split a wide generic register into bitwise blocks with
191-
/// the given Type (which implies the number of blocks needed). The generic
192-
/// registers created are appended to Ops, starting at bit 0 of Reg.
193-
void extractParts(Register Reg, LLT Ty, int NumParts,
194-
SmallVectorImpl<Register> &VRegs);
195-
196-
/// Version which handles irregular splits.
197-
bool extractParts(Register Reg, LLT RegTy, LLT MainTy,
198-
LLT &LeftoverTy,
199-
SmallVectorImpl<Register> &VRegs,
200-
SmallVectorImpl<Register> &LeftoverVRegs);
201-
202-
/// Version which handles irregular sub-vector splits.
203-
void extractVectorParts(Register Reg, unsigned NumElst,
204-
SmallVectorImpl<Register> &VRegs);
205-
206190
/// Helper function to build a wide generic register \p DstReg of type \p
207191
/// RegTy from smaller parts. This will produce a G_MERGE_VALUES,
208192
/// G_BUILD_VECTOR, G_CONCAT_VECTORS, or sequence of G_INSERT as appropriate

llvm/include/llvm/CodeGen/GlobalISel/Utils.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class BlockFrequencyInfo;
3333
class GISelKnownBits;
3434
class MachineFunction;
3535
class MachineInstr;
36+
class MachineIRBuilder;
3637
class MachineOperand;
3738
class MachineOptimizationRemarkEmitter;
3839
class MachineOptimizationRemarkMissed;
@@ -247,6 +248,24 @@ MachineInstr *getDefIgnoringCopies(Register Reg,
247248
/// Also walks through hints such as G_ASSERT_ZEXT.
248249
Register getSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI);
249250

251+
/// Helper function to split a wide generic register into bitwise blocks with
252+
/// the given Type (which implies the number of blocks needed). The generic
253+
/// registers created are appended to Ops, starting at bit 0 of Reg.
254+
void extractParts(Register Reg, LLT Ty, int NumParts,
255+
SmallVectorImpl<Register> &VRegs,
256+
MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI);
257+
258+
/// Version which handles irregular splits.
259+
bool extractParts(Register Reg, LLT RegTy, LLT MainTy, LLT &LeftoverTy,
260+
SmallVectorImpl<Register> &VRegs,
261+
SmallVectorImpl<Register> &LeftoverVRegs,
262+
MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI);
263+
264+
/// Version which handles irregular sub-vector splits.
265+
void extractVectorParts(Register Reg, unsigned NumElts,
266+
SmallVectorImpl<Register> &VRegs,
267+
MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI);
268+
250269
// Templated variant of getOpcodeDef returning a MachineInstr derived T.
251270
/// See if Reg is defined by an single def instruction of type T
252271
/// Also try to do trivial folding if it's a COPY with

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 33 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -158,100 +158,6 @@ LegalizerHelper::legalizeInstrStep(MachineInstr &MI,
158158
}
159159
}
160160

161-
void LegalizerHelper::extractParts(Register Reg, LLT Ty, int NumParts,
162-
SmallVectorImpl<Register> &VRegs) {
163-
for (int i = 0; i < NumParts; ++i)
164-
VRegs.push_back(MRI.createGenericVirtualRegister(Ty));
165-
MIRBuilder.buildUnmerge(VRegs, Reg);
166-
}
167-
168-
bool LegalizerHelper::extractParts(Register Reg, LLT RegTy,
169-
LLT MainTy, LLT &LeftoverTy,
170-
SmallVectorImpl<Register> &VRegs,
171-
SmallVectorImpl<Register> &LeftoverRegs) {
172-
assert(!LeftoverTy.isValid() && "this is an out argument");
173-
174-
unsigned RegSize = RegTy.getSizeInBits();
175-
unsigned MainSize = MainTy.getSizeInBits();
176-
unsigned NumParts = RegSize / MainSize;
177-
unsigned LeftoverSize = RegSize - NumParts * MainSize;
178-
179-
// Use an unmerge when possible.
180-
if (LeftoverSize == 0) {
181-
for (unsigned I = 0; I < NumParts; ++I)
182-
VRegs.push_back(MRI.createGenericVirtualRegister(MainTy));
183-
MIRBuilder.buildUnmerge(VRegs, Reg);
184-
return true;
185-
}
186-
187-
// Perform irregular split. Leftover is last element of RegPieces.
188-
if (MainTy.isVector()) {
189-
SmallVector<Register, 8> RegPieces;
190-
extractVectorParts(Reg, MainTy.getNumElements(), RegPieces);
191-
for (unsigned i = 0; i < RegPieces.size() - 1; ++i)
192-
VRegs.push_back(RegPieces[i]);
193-
LeftoverRegs.push_back(RegPieces[RegPieces.size() - 1]);
194-
LeftoverTy = MRI.getType(LeftoverRegs[0]);
195-
return true;
196-
}
197-
198-
LeftoverTy = LLT::scalar(LeftoverSize);
199-
// For irregular sizes, extract the individual parts.
200-
for (unsigned I = 0; I != NumParts; ++I) {
201-
Register NewReg = MRI.createGenericVirtualRegister(MainTy);
202-
VRegs.push_back(NewReg);
203-
MIRBuilder.buildExtract(NewReg, Reg, MainSize * I);
204-
}
205-
206-
for (unsigned Offset = MainSize * NumParts; Offset < RegSize;
207-
Offset += LeftoverSize) {
208-
Register NewReg = MRI.createGenericVirtualRegister(LeftoverTy);
209-
LeftoverRegs.push_back(NewReg);
210-
MIRBuilder.buildExtract(NewReg, Reg, Offset);
211-
}
212-
213-
return true;
214-
}
215-
216-
void LegalizerHelper::extractVectorParts(Register Reg, unsigned NumElts,
217-
SmallVectorImpl<Register> &VRegs) {
218-
LLT RegTy = MRI.getType(Reg);
219-
assert(RegTy.isVector() && "Expected a vector type");
220-
221-
LLT EltTy = RegTy.getElementType();
222-
LLT NarrowTy = (NumElts == 1) ? EltTy : LLT::fixed_vector(NumElts, EltTy);
223-
unsigned RegNumElts = RegTy.getNumElements();
224-
unsigned LeftoverNumElts = RegNumElts % NumElts;
225-
unsigned NumNarrowTyPieces = RegNumElts / NumElts;
226-
227-
// Perfect split without leftover
228-
if (LeftoverNumElts == 0)
229-
return extractParts(Reg, NarrowTy, NumNarrowTyPieces, VRegs);
230-
231-
// Irregular split. Provide direct access to all elements for artifact
232-
// combiner using unmerge to elements. Then build vectors with NumElts
233-
// elements. Remaining element(s) will be (used to build vector) Leftover.
234-
SmallVector<Register, 8> Elts;
235-
extractParts(Reg, EltTy, RegNumElts, Elts);
236-
237-
unsigned Offset = 0;
238-
// Requested sub-vectors of NarrowTy.
239-
for (unsigned i = 0; i < NumNarrowTyPieces; ++i, Offset += NumElts) {
240-
ArrayRef<Register> Pieces(&Elts[Offset], NumElts);
241-
VRegs.push_back(MIRBuilder.buildMergeLikeInstr(NarrowTy, Pieces).getReg(0));
242-
}
243-
244-
// Leftover element(s).
245-
if (LeftoverNumElts == 1) {
246-
VRegs.push_back(Elts[Offset]);
247-
} else {
248-
LLT LeftoverTy = LLT::fixed_vector(LeftoverNumElts, EltTy);
249-
ArrayRef<Register> Pieces(&Elts[Offset], LeftoverNumElts);
250-
VRegs.push_back(
251-
MIRBuilder.buildMergeLikeInstr(LeftoverTy, Pieces).getReg(0));
252-
}
253-
}
254-
255161
void LegalizerHelper::insertParts(Register DstReg,
256162
LLT ResultTy, LLT PartTy,
257163
ArrayRef<Register> PartRegs,
@@ -293,7 +199,8 @@ void LegalizerHelper::appendVectorElts(SmallVectorImpl<Register> &Elts,
293199
Register Reg) {
294200
LLT Ty = MRI.getType(Reg);
295201
SmallVector<Register, 8> RegElts;
296-
extractParts(Reg, Ty.getScalarType(), Ty.getNumElements(), RegElts);
202+
extractParts(Reg, Ty.getScalarType(), Ty.getNumElements(), RegElts,
203+
MIRBuilder, MRI);
297204
Elts.append(RegElts);
298205
}
299206

@@ -1542,7 +1449,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
15421449
MachineBasicBlock &OpMBB = *MI.getOperand(i + 1).getMBB();
15431450
MIRBuilder.setInsertPt(OpMBB, OpMBB.getFirstTerminatorForward());
15441451
extractParts(MI.getOperand(i).getReg(), NarrowTy, NumParts,
1545-
SrcRegs[i / 2]);
1452+
SrcRegs[i / 2], MIRBuilder, MRI);
15461453
}
15471454
MachineBasicBlock &MBB = *MI.getParent();
15481455
MIRBuilder.setInsertPt(MBB, MI);
@@ -1584,13 +1491,13 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
15841491
LLT LeftoverTy; // Example: s88 -> s64 (NarrowTy) + s24 (leftover)
15851492
SmallVector<Register, 4> LHSPartRegs, LHSLeftoverRegs;
15861493
if (!extractParts(LHS, SrcTy, NarrowTy, LeftoverTy, LHSPartRegs,
1587-
LHSLeftoverRegs))
1494+
LHSLeftoverRegs, MIRBuilder, MRI))
15881495
return UnableToLegalize;
15891496

15901497
LLT Unused; // Matches LeftoverTy; G_ICMP LHS and RHS are the same type.
15911498
SmallVector<Register, 4> RHSPartRegs, RHSLeftoverRegs;
15921499
if (!extractParts(MI.getOperand(3).getReg(), SrcTy, NarrowTy, Unused,
1593-
RHSPartRegs, RHSLeftoverRegs))
1500+
RHSPartRegs, RHSLeftoverRegs, MIRBuilder, MRI))
15941501
return UnableToLegalize;
15951502

15961503
// We now have the LHS and RHS of the compare split into narrow-type
@@ -1744,7 +1651,8 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
17441651
Observer.changingInstr(MI);
17451652
SmallVector<Register, 2> SrcRegs, DstRegs;
17461653
unsigned NumParts = SizeOp0 / NarrowSize;
1747-
extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs);
1654+
extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs,
1655+
MIRBuilder, MRI);
17481656

17491657
for (unsigned i = 0; i < NumParts; ++i) {
17501658
auto DstPart = MIRBuilder.buildInstr(MI.getOpcode(), {NarrowTy},
@@ -4194,7 +4102,8 @@ LegalizerHelper::fewerElementsVectorMultiEltType(
41944102
MI.getOperand(UseIdx));
41954103
} else {
41964104
SmallVector<Register, 8> SplitPieces;
4197-
extractVectorParts(MI.getReg(UseIdx), NumElts, SplitPieces);
4105+
extractVectorParts(MI.getReg(UseIdx), NumElts, SplitPieces, MIRBuilder,
4106+
MRI);
41984107
for (auto Reg : SplitPieces)
41994108
InputOpsPieces[UseNo].push_back(Reg);
42004109
}
@@ -4250,7 +4159,8 @@ LegalizerHelper::fewerElementsVectorPhi(GenericMachineInstr &MI,
42504159
UseIdx += 2, ++UseNo) {
42514160
MachineBasicBlock &OpMBB = *MI.getOperand(UseIdx + 1).getMBB();
42524161
MIRBuilder.setInsertPt(OpMBB, OpMBB.getFirstTerminatorForward());
4253-
extractVectorParts(MI.getReg(UseIdx), NumElts, InputOpsPieces[UseNo]);
4162+
extractVectorParts(MI.getReg(UseIdx), NumElts, InputOpsPieces[UseNo],
4163+
MIRBuilder, MRI);
42544164
}
42554165

42564166
// Build PHIs with fewer elements.
@@ -4519,7 +4429,7 @@ LegalizerHelper::reduceLoadStoreWidth(GLoadStore &LdStMI, unsigned TypeIdx,
45194429
std::tie(NumParts, NumLeftover) = getNarrowTypeBreakDown(ValTy, NarrowTy, LeftoverTy);
45204430
} else {
45214431
if (extractParts(ValReg, ValTy, NarrowTy, LeftoverTy, NarrowRegs,
4522-
NarrowLeftoverRegs)) {
4432+
NarrowLeftoverRegs, MIRBuilder, MRI)) {
45234433
NumParts = NarrowRegs.size();
45244434
NumLeftover = NarrowLeftoverRegs.size();
45254435
}
@@ -4765,8 +4675,8 @@ LegalizerHelper::LegalizeResult LegalizerHelper::fewerElementsVectorShuffle(
47654675
unsigned NewElts = NarrowTy.getNumElements();
47664676

47674677
SmallVector<Register> SplitSrc1Regs, SplitSrc2Regs;
4768-
extractParts(Src1Reg, NarrowTy, 2, SplitSrc1Regs);
4769-
extractParts(Src2Reg, NarrowTy, 2, SplitSrc2Regs);
4678+
extractParts(Src1Reg, NarrowTy, 2, SplitSrc1Regs, MIRBuilder, MRI);
4679+
extractParts(Src2Reg, NarrowTy, 2, SplitSrc2Regs, MIRBuilder, MRI);
47704680
Register Inputs[4] = {SplitSrc1Regs[0], SplitSrc1Regs[1], SplitSrc2Regs[0],
47714681
SplitSrc2Regs[1]};
47724682

@@ -4900,7 +4810,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::fewerElementsVectorReductions(
49004810
NarrowTy.isVector() ? SrcTy.getNumElements() / NarrowTy.getNumElements()
49014811
: SrcTy.getNumElements();
49024812

4903-
extractParts(SrcReg, NarrowTy, NumParts, SplitSrcs);
4813+
extractParts(SrcReg, NarrowTy, NumParts, SplitSrcs, MIRBuilder, MRI);
49044814
if (NarrowTy.isScalar()) {
49054815
if (DstTy != NarrowTy)
49064816
return UnableToLegalize; // FIXME: handle implicit extensions.
@@ -4983,7 +4893,7 @@ LegalizerHelper::fewerElementsVectorSeqReductions(MachineInstr &MI,
49834893

49844894
SmallVector<Register> SplitSrcs;
49854895
unsigned NumParts = SrcTy.getNumElements();
4986-
extractParts(SrcReg, NarrowTy, NumParts, SplitSrcs);
4896+
extractParts(SrcReg, NarrowTy, NumParts, SplitSrcs, MIRBuilder, MRI);
49874897
Register Acc = ScalarReg;
49884898
for (unsigned i = 0; i < NumParts; i++)
49894899
Acc = MIRBuilder.buildInstr(ScalarOpc, {NarrowTy}, {Acc, SplitSrcs[i]})
@@ -5001,7 +4911,8 @@ LegalizerHelper::tryNarrowPow2Reduction(MachineInstr &MI, Register SrcReg,
50014911
SmallVector<Register> SplitSrcs;
50024912
// Split the sources into NarrowTy size pieces.
50034913
extractParts(SrcReg, NarrowTy,
5004-
SrcTy.getNumElements() / NarrowTy.getNumElements(), SplitSrcs);
4914+
SrcTy.getNumElements() / NarrowTy.getNumElements(), SplitSrcs,
4915+
MIRBuilder, MRI);
50054916
// We're going to do a tree reduction using vector operations until we have
50064917
// one NarrowTy size value left.
50074918
while (SplitSrcs.size() > 1) {
@@ -5640,8 +5551,10 @@ LegalizerHelper::narrowScalarAddSub(MachineInstr &MI, unsigned TypeIdx,
56405551
LLT RegTy = MRI.getType(MI.getOperand(0).getReg());
56415552
LLT LeftoverTy, DummyTy;
56425553
SmallVector<Register, 2> Src1Regs, Src2Regs, Src1Left, Src2Left, DstRegs;
5643-
extractParts(Src1, RegTy, NarrowTy, LeftoverTy, Src1Regs, Src1Left);
5644-
extractParts(Src2, RegTy, NarrowTy, DummyTy, Src2Regs, Src2Left);
5554+
extractParts(Src1, RegTy, NarrowTy, LeftoverTy, Src1Regs, Src1Left,
5555+
MIRBuilder, MRI);
5556+
extractParts(Src2, RegTy, NarrowTy, DummyTy, Src2Regs, Src2Left, MIRBuilder,
5557+
MRI);
56455558

56465559
int NarrowParts = Src1Regs.size();
56475560
for (int I = 0, E = Src1Left.size(); I != E; ++I) {
@@ -5699,8 +5612,8 @@ LegalizerHelper::narrowScalarMul(MachineInstr &MI, LLT NarrowTy) {
56995612

57005613
SmallVector<Register, 2> Src1Parts, Src2Parts;
57015614
SmallVector<Register, 2> DstTmpRegs(DstTmpParts);
5702-
extractParts(Src1, NarrowTy, NumParts, Src1Parts);
5703-
extractParts(Src2, NarrowTy, NumParts, Src2Parts);
5615+
extractParts(Src1, NarrowTy, NumParts, Src1Parts, MIRBuilder, MRI);
5616+
extractParts(Src2, NarrowTy, NumParts, Src2Parts, MIRBuilder, MRI);
57045617
multiplyRegisters(DstTmpRegs, Src1Parts, Src2Parts, NarrowTy);
57055618

57065619
// Take only high half of registers if this is high mul.
@@ -5752,7 +5665,8 @@ LegalizerHelper::narrowScalarExtract(MachineInstr &MI, unsigned TypeIdx,
57525665

57535666
SmallVector<Register, 2> SrcRegs, DstRegs;
57545667
SmallVector<uint64_t, 2> Indexes;
5755-
extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs);
5668+
extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs,
5669+
MIRBuilder, MRI);
57565670

57575671
Register OpReg = MI.getOperand(0).getReg();
57585672
uint64_t OpStart = MI.getOperand(2).getImm();
@@ -5814,7 +5728,7 @@ LegalizerHelper::narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx,
58145728
LLT RegTy = MRI.getType(MI.getOperand(0).getReg());
58155729
LLT LeftoverTy;
58165730
extractParts(MI.getOperand(1).getReg(), RegTy, NarrowTy, LeftoverTy, SrcRegs,
5817-
LeftoverRegs);
5731+
LeftoverRegs, MIRBuilder, MRI);
58185732

58195733
for (Register Reg : LeftoverRegs)
58205734
SrcRegs.push_back(Reg);
@@ -5899,12 +5813,12 @@ LegalizerHelper::narrowScalarBasic(MachineInstr &MI, unsigned TypeIdx,
58995813
SmallVector<Register, 4> Src1Regs, Src1LeftoverRegs;
59005814
LLT LeftoverTy;
59015815
if (!extractParts(MI.getOperand(1).getReg(), DstTy, NarrowTy, LeftoverTy,
5902-
Src0Regs, Src0LeftoverRegs))
5816+
Src0Regs, Src0LeftoverRegs, MIRBuilder, MRI))
59035817
return UnableToLegalize;
59045818

59055819
LLT Unused;
59065820
if (!extractParts(MI.getOperand(2).getReg(), DstTy, NarrowTy, Unused,
5907-
Src1Regs, Src1LeftoverRegs))
5821+
Src1Regs, Src1LeftoverRegs, MIRBuilder, MRI))
59085822
llvm_unreachable("inconsistent extractParts result");
59095823

59105824
for (unsigned I = 0, E = Src1Regs.size(); I != E; ++I) {
@@ -5967,12 +5881,12 @@ LegalizerHelper::narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx,
59675881
SmallVector<Register, 4> Src2Regs, Src2LeftoverRegs;
59685882
LLT LeftoverTy;
59695883
if (!extractParts(MI.getOperand(2).getReg(), DstTy, NarrowTy, LeftoverTy,
5970-
Src1Regs, Src1LeftoverRegs))
5884+
Src1Regs, Src1LeftoverRegs, MIRBuilder, MRI))
59715885
return UnableToLegalize;
59725886

59735887
LLT Unused;
59745888
if (!extractParts(MI.getOperand(3).getReg(), DstTy, NarrowTy, Unused,
5975-
Src2Regs, Src2LeftoverRegs))
5889+
Src2Regs, Src2LeftoverRegs, MIRBuilder, MRI))
59765890
llvm_unreachable("inconsistent extractParts result");
59775891

59785892
for (unsigned I = 0, E = Src1Regs.size(); I != E; ++I) {
@@ -6468,7 +6382,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerTRUNC(MachineInstr &MI) {
64686382

64696383
// First, split the source into two smaller vectors.
64706384
SmallVector<Register, 2> SplitSrcs;
6471-
extractParts(SrcReg, SplitSrcTy, 2, SplitSrcs);
6385+
extractParts(SrcReg, SplitSrcTy, 2, SplitSrcs, MIRBuilder, MRI);
64726386

64736387
// Truncate the splits into intermediate narrower elements.
64746388
LLT InterTy;
@@ -7208,7 +7122,7 @@ LegalizerHelper::lowerExtractInsertVectorElt(MachineInstr &MI) {
72087122
int64_t IdxVal;
72097123
if (mi_match(Idx, MRI, m_ICst(IdxVal)) && IdxVal <= NumElts) {
72107124
SmallVector<Register, 8> SrcRegs;
7211-
extractParts(SrcVec, EltTy, NumElts, SrcRegs);
7125+
extractParts(SrcVec, EltTy, NumElts, SrcRegs, MIRBuilder, MRI);
72127126

72137127
if (InsertVal) {
72147128
SrcRegs[IdxVal] = MI.getOperand(2).getReg();

0 commit comments

Comments
 (0)