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-
14069bool 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
345131char AIESuperRegRewriter::ID = 0 ;
0 commit comments