Skip to content

Commit 3e58a87

Browse files
[AIEX][NFC] Refator some AIESuperReg utilities
Co-Authored-By: Krishnam Tibrewala <[email protected]>
1 parent 912a547 commit 3e58a87

File tree

5 files changed

+357
-246
lines changed

5 files changed

+357
-246
lines changed

llvm/lib/Target/AIE/AIESuperRegRewriter.cpp

Lines changed: 12 additions & 226 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "AIEBaseInstrInfo.h"
1212
#include "AIEBaseRegisterInfo.h"
13+
#include "AIESuperRegUtils.h"
1314

1415
#include "llvm/ADT/MapVector.h"
1516
#include "llvm/ADT/SmallSet.h"
@@ -63,80 +64,8 @@ class AIESuperRegRewriter : public MachineFunctionPass {
6364
}
6465

6566
bool runOnMachineFunction(MachineFunction &Fn) override;
66-
67-
private:
68-
void rewriteSuperReg(Register Reg, Register AssignedPhysReg,
69-
MachineRegisterInfo &MRI, const AIEBaseRegisterInfo &TRI,
70-
VirtRegMap &VRM, LiveRegMatrix &LRM, LiveIntervals &LIS,
71-
SlotIndexes &Indexes, LiveDebugVariables &DebugVars);
7267
};
7368

74-
/// Returns the subreg indices that can be used to rewrite \p Reg into smaller
75-
/// regs. Returns {} if the rewrite isn't possible.
76-
static SmallSet<int, 8> getRewritableSubRegs(Register Reg,
77-
const MachineRegisterInfo &MRI,
78-
const AIEBaseRegisterInfo &TRI,
79-
std::set<Register> &VisitedVRegs) {
80-
if (Reg.isPhysical()) {
81-
// TODO: One could use collectSubRegs() in AIEBaseInstrInfo.cpp
82-
// But given that MOD registers are not part of the ABI, they should
83-
// not appear as physical registers before RA.
84-
LLVM_DEBUG(dbgs() << " Cannot rewrite physreg " << printReg(Reg, &TRI)
85-
<< "\n");
86-
return {};
87-
}
88-
89-
auto &SubRegSplit = TRI.getSubRegSplit(MRI.getRegClass(Reg)->getID());
90-
if (SubRegSplit.size() <= 1) {
91-
// Register does not have multiple subregs to be rewritten into.
92-
LLVM_DEBUG(dbgs() << " Cannot rewrite " << printReg(Reg, &TRI, 0, &MRI)
93-
<< ": no sub-reg split\n");
94-
return {};
95-
}
96-
97-
VisitedVRegs.insert(Reg);
98-
SmallSet<int, 8> UsedSubRegs;
99-
for (MachineOperand &RegOp : MRI.reg_operands(Reg)) {
100-
int SubReg = RegOp.getSubReg();
101-
if (SubReg && SubRegSplit.count(SubReg)) {
102-
UsedSubRegs.insert(SubReg);
103-
} else if (RegOp.getParent()->isFullCopy()) {
104-
// To rewrite a full copy, both operands need to be rewritable using
105-
// their subregs.
106-
Register DstReg = RegOp.getParent()->getOperand(0).getReg();
107-
if (!VisitedVRegs.count(DstReg) &&
108-
getRewritableSubRegs(DstReg, MRI, TRI, VisitedVRegs).empty()) {
109-
LLVM_DEBUG(dbgs() << " Cannot rewrite "
110-
<< printReg(DstReg, &TRI, 0, &MRI) << " in "
111-
<< *RegOp.getParent());
112-
return {};
113-
}
114-
Register SrcReg = RegOp.getParent()->getOperand(1).getReg();
115-
if (!VisitedVRegs.count(SrcReg) &&
116-
getRewritableSubRegs(SrcReg, MRI, TRI, VisitedVRegs).empty()) {
117-
LLVM_DEBUG(dbgs() << " Cannot rewrite "
118-
<< printReg(SrcReg, &TRI, 0, &MRI) << " in "
119-
<< *RegOp.getParent());
120-
return {};
121-
}
122-
UsedSubRegs.insert(SubRegSplit.begin(), SubRegSplit.end());
123-
} else {
124-
LLVM_DEBUG(dbgs() << " Cannot rewrite " << RegOp << " in "
125-
<< *RegOp.getParent());
126-
return {};
127-
}
128-
}
129-
130-
return UsedSubRegs;
131-
}
132-
133-
static SmallSet<int, 8> getRewritableSubRegs(Register Reg,
134-
const MachineRegisterInfo &MRI,
135-
const AIEBaseRegisterInfo &TRI) {
136-
std::set<Register> VisitedVRegs;
137-
return getRewritableSubRegs(Reg, MRI, TRI, VisitedVRegs);
138-
}
139-
14069
bool AIESuperRegRewriter::runOnMachineFunction(MachineFunction &MF) {
14170
LLVM_DEBUG(llvm::dbgs() << "*** Splitting super-registers: " << MF.getName()
14271
<< " ***\n");
@@ -149,7 +78,7 @@ bool AIESuperRegRewriter::runOnMachineFunction(MachineFunction &MF) {
14978
LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
15079
SlotIndexes &Indexes = getAnalysis<SlotIndexesWrapperPass>().getSI();
15180
LiveDebugVariables &DebugVars = getAnalysis<LiveDebugVariablesWrapperLegacy>().getLDV();
152-
std::map<Register, MCRegister> AssignedPhysRegs;
81+
std::map<Register, std::pair<MCRegister, SmallSet<int, 8>>> AssignedPhysRegs;
15382

15483
// Collect already-assigned VRegs that can be split into smaller ones.
15584
LLVM_DEBUG(VRM.dump());
@@ -173,8 +102,11 @@ bool AIESuperRegRewriter::runOnMachineFunction(MachineFunction &MF) {
173102

174103
LLVM_DEBUG(dbgs() << "Analysing " << printReg(Reg, &TRI, 0, &MRI) << ":"
175104
<< printRegClassOrBank(Reg, MRI, &TRI) << '\n');
176-
if (!getRewritableSubRegs(Reg, MRI, TRI).empty()) {
177-
AssignedPhysRegs[Reg] = VRM.getPhys(Reg);
105+
SmallSet<int, 8> RewritableSubRegs =
106+
AIESuperRegUtils::getRewritableSubRegs(Reg, MRI, TRI);
107+
if (!RewritableSubRegs.empty()) {
108+
AssignedPhysRegs[Reg] =
109+
std::make_pair(VRM.getPhys(Reg), RewritableSubRegs);
178110
LRM.unassign(LIS.getInterval(Reg));
179111
} else {
180112
LLVM_DEBUG(dbgs() << "Could not rewrite " << printReg(Reg, &TRI, 0, &MRI)
@@ -183,163 +115,17 @@ bool AIESuperRegRewriter::runOnMachineFunction(MachineFunction &MF) {
183115
}
184116

185117
// Re-write all the collected VRegs
186-
for (auto &[VReg, PhysReg] : AssignedPhysRegs) {
187-
rewriteSuperReg(VReg, PhysReg, MRI, TRI, VRM, LRM, LIS, Indexes, DebugVars);
118+
for (auto &[VReg, PhysRegAndSubRegs] : AssignedPhysRegs) {
119+
const Register PhysReg = PhysRegAndSubRegs.first;
120+
SmallSet<int, 8> &SubRegs = PhysRegAndSubRegs.second;
121+
AIESuperRegUtils::rewriteSuperReg(VReg, PhysReg, SubRegs, MRI, TRI, VRM,
122+
LRM, LIS, Indexes, DebugVars);
188123
}
189124

190125
LLVM_DEBUG(VRM.dump());
191126
return !AssignedPhysRegs.empty();
192127
}
193128

194-
/// Return a mask of all the lanes that are live at \p Index
195-
static LaneBitmask getLiveLanesAt(SlotIndex Index, Register Reg,
196-
const LiveIntervals &LIS) {
197-
const LiveInterval &LI = LIS.getInterval(Reg);
198-
if (!LI.hasSubRanges())
199-
return LaneBitmask::getAll();
200-
201-
LaneBitmask LiveLanes;
202-
for (const LiveInterval::SubRange &SubLI : LI.subranges()) {
203-
if (SubLI.liveAt(Index))
204-
LiveLanes |= SubLI.LaneMask;
205-
}
206-
return LiveLanes;
207-
}
208-
209-
/// Rewrite a full copy into multiple copies using the subregs in \p CopySubRegs
210-
static void rewriteFullCopy(MachineInstr &MI, const std::set<int> &CopySubRegs,
211-
LiveIntervals &LIS, const TargetInstrInfo &TII,
212-
const TargetRegisterInfo &TRI, VirtRegMap &VRM,
213-
LiveRegMatrix &LRM) {
214-
assert(MI.isFullCopy());
215-
SlotIndex CopyIndex = LIS.getInstructionIndex(MI);
216-
LLVM_DEBUG(dbgs() << " Changing full copy at " << CopyIndex << ": " << MI);
217-
Register DstReg = MI.getOperand(0).getReg();
218-
Register SrcReg = MI.getOperand(1).getReg();
219-
LaneBitmask LiveSrcLanes = getLiveLanesAt(CopyIndex, SrcReg, LIS);
220-
221-
LIS.removeVRegDefAt(LIS.getInterval(DstReg), CopyIndex.getRegSlot());
222-
223-
SmallSet<Register, 8> RegistersToRepair;
224-
for (int SubRegIdx : CopySubRegs) {
225-
if ((LiveSrcLanes & TRI.getSubRegIndexLaneMask(SubRegIdx)).none()) {
226-
LLVM_DEBUG(dbgs() << " Skip undef subreg "
227-
<< TRI.getSubRegIndexName(SubRegIdx) << "\n");
228-
continue;
229-
}
230-
231-
MachineInstr *PartCopy = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),
232-
TII.get(TargetOpcode::COPY))
233-
.addReg(DstReg, RegState::Define, SubRegIdx)
234-
.addReg(SrcReg, 0, SubRegIdx)
235-
.getInstr();
236-
LLVM_DEBUG(dbgs() << " to " << *PartCopy);
237-
LIS.InsertMachineInstrInMaps(*PartCopy);
238-
LIS.getInterval(PartCopy->getOperand(0).getReg());
239-
RegistersToRepair.insert(PartCopy->getOperand(1).getReg());
240-
}
241-
242-
LIS.RemoveMachineInstrFromMaps(MI);
243-
MI.eraseFromParent();
244-
// As we don't handle all registers now (selective LI filter),
245-
// We should make sure that all LiveIntervals are correct.
246-
// If we dont't repair, MI will compose the LIs of some registers,
247-
// what is not correct because MI was deleted.
248-
for (Register R : RegistersToRepair) {
249-
250-
if (!LIS.hasInterval(R))
251-
continue;
252-
253-
if (VRM.hasPhys(R)) {
254-
const MCRegister PhysReg = VRM.getPhys(R);
255-
const LiveInterval &OldLI = LIS.getInterval(R);
256-
LRM.unassign(OldLI);
257-
LIS.removeInterval(R);
258-
const LiveInterval &LI = LIS.getInterval(R);
259-
LRM.assign(LI, PhysReg);
260-
} else {
261-
LIS.removeInterval(R);
262-
LIS.createAndComputeVirtRegInterval(R);
263-
}
264-
}
265-
}
266-
267-
void AIESuperRegRewriter::rewriteSuperReg(
268-
Register Reg, Register AssignedPhysReg, MachineRegisterInfo &MRI,
269-
const AIEBaseRegisterInfo &TRI, VirtRegMap &VRM, LiveRegMatrix &LRM,
270-
LiveIntervals &LIS, SlotIndexes &Indexes, LiveDebugVariables &DebugVars) {
271-
LLVM_DEBUG(dbgs() << "Rewriting " << printReg(Reg, &TRI, 0, &MRI) << '\n');
272-
auto *TII = static_cast<const AIEBaseInstrInfo *>(
273-
VRM.getMachineFunction().getSubtarget().getInstrInfo());
274-
275-
// Collect all the subreg indices to rewrite as independent vregs.
276-
SmallMapVector<int, Register, 8> SubRegToVReg;
277-
const TargetRegisterClass *SuperRC = MRI.getRegClass(Reg);
278-
SmallSet<int, 8> SubRegs = getRewritableSubRegs(Reg, MRI, TRI);
279-
assert(!SubRegs.empty());
280-
for (int SubReg : SubRegs) {
281-
const TargetRegisterClass *SubRC = TRI.getSubRegisterClass(SuperRC, SubReg);
282-
SubRegToVReg[SubReg] = MRI.createVirtualRegister(SubRC);
283-
}
284-
285-
// Rewrite full copies into multiple copies using subregs
286-
for (MachineInstr &MI : make_early_inc_range(MRI.reg_instructions(Reg))) {
287-
if (MI.isFullCopy())
288-
rewriteFullCopy(MI, TRI.getSubRegSplit(MRI.getRegClass(Reg)->getID()),
289-
LIS, *TII, TRI, VRM, LRM);
290-
}
291-
292-
LLVM_DEBUG(dbgs() << " Splitting range " << LIS.getInterval(Reg) << "\n");
293-
for (MachineOperand &RegOp : make_early_inc_range(MRI.reg_operands(Reg))) {
294-
LLVM_DEBUG(dbgs() << " Changing " << *RegOp.getParent());
295-
int SubReg = RegOp.getSubReg();
296-
assert(SubReg);
297-
RegOp.setReg(SubRegToVReg[SubReg]);
298-
RegOp.setSubReg(0);
299-
300-
// There might have been a write-undef due to only writing one sub-lane.
301-
// Now that each sub-lane has its own VReg, the qualifier is invalid.
302-
if (RegOp.isDef())
303-
RegOp.setIsUndef(false);
304-
305-
// Make sure the right reg class is applied, some MIs might use compound
306-
// classes with both 20 and 32 bits registers.
307-
const TargetRegisterClass *OpRC = TII->getRegClass(
308-
RegOp.getParent()->getDesc(), RegOp.getParent()->getOperandNo(&RegOp),
309-
&TRI, VRM.getMachineFunction());
310-
MRI.constrainRegClass(SubRegToVReg[SubReg], OpRC);
311-
312-
LLVM_DEBUG(dbgs() << " to " << *RegOp.getParent());
313-
}
314-
315-
VRM.grow();
316-
LIS.removeInterval(Reg);
317-
318-
for (auto &[SubRegIdx, VReg] : SubRegToVReg) {
319-
MCRegister SubPhysReg = TRI.getSubReg(AssignedPhysReg, SubRegIdx);
320-
LiveInterval &SubRegLI = LIS.getInterval(VReg);
321-
LLVM_DEBUG(dbgs() << " Assigning Range: " << SubRegLI << '\n');
322-
323-
// By giving an independent VReg to each lane, we might have created
324-
// multiple separate components. Give a VReg to each separate component.
325-
SmallVector<LiveInterval *, 4> LIComponents;
326-
LIS.splitSeparateComponents(SubRegLI, LIComponents);
327-
LIComponents.push_back(&SubRegLI);
328-
VRM.grow();
329-
330-
for (LiveInterval *LI : LIComponents) {
331-
LRM.assign(*LI, SubPhysReg);
332-
VRM.setRequiredPhys(LI->reg(), SubPhysReg);
333-
LLVM_DEBUG(dbgs() << " Assigned " << printReg(LI->reg()) << "\n");
334-
}
335-
}
336-
337-
// Announce new VRegs so DBG locations can be updated.
338-
auto NewVRegs = SmallVector<Register, 8>(llvm::map_range(
339-
SubRegToVReg, [&](auto &Mapping) { return Mapping.second; }));
340-
DebugVars.splitRegister(Reg, NewVRegs, LIS);
341-
}
342-
343129
} // end anonymous namespace
344130

345131
char AIESuperRegRewriter::ID = 0;

0 commit comments

Comments
 (0)