-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[WIP][CodeGen] Encode liveness for COPY instructions after virtRegRewriter pass. #151123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
8cb9a5e
9f3acc2
3352e34
0fd50a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -213,6 +213,8 @@ class VirtRegRewriter { | |
| void rewrite(); | ||
| void addMBBLiveIns(); | ||
| bool readsUndefSubreg(const MachineOperand &MO) const; | ||
| uint64_t calcLiveRegUnitMask(const MachineOperand &MO, | ||
| MCRegister PhysReg) const; | ||
| void addLiveInsForSubRanges(const LiveInterval &LI, MCRegister PhysReg) const; | ||
| void handleIdentityCopy(MachineInstr &MI); | ||
| void expandCopyBundle(MachineInstr &MI) const; | ||
|
|
@@ -474,6 +476,77 @@ bool VirtRegRewriter::readsUndefSubreg(const MachineOperand &MO) const { | |
| return true; | ||
| } | ||
|
|
||
| // Return LaneBitmask value as uint64_t for PhysReg assigned to MO, | ||
| // representing its live register units at its parent MI. In case of undef or | ||
| // fully live MO, return 0u. | ||
| uint64_t VirtRegRewriter::calcLiveRegUnitMask(const MachineOperand &MO, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why don't you return LaneBitmask as it is? |
||
| MCRegister PhysReg) const { | ||
| Register Reg = MO.getReg(); | ||
| const LiveInterval &LI = LIS->getInterval(Reg); | ||
| const MachineInstr &MI = *MO.getParent(); | ||
| SlotIndex MIIndex = LIS->getInstructionIndex(MI); | ||
| unsigned SubRegIdx = MO.getSubReg(); | ||
| LaneBitmask UseMask = SubRegIdx | ||
| ? TRI->getSubRegIndexLaneMask(SubRegIdx) | ||
| : (Reg.isVirtual() ? MRI->getMaxLaneMaskForVReg(Reg) | ||
| : LaneBitmask::getNone()); | ||
|
|
||
| LaneBitmask LiveRegUnitMask; | ||
| DenseSet<unsigned> LiveRegUnits; | ||
|
|
||
| // dbgs() << "\n********** " << printReg(Reg, TRI) << "[ " << | ||
| // printReg(PhysReg, TRI) << " ]" << " **********\n"; | ||
|
|
||
| if (MO.isUndef()) | ||
| return 0u; | ||
|
|
||
| assert(LI.liveAt(MIIndex) && | ||
| "Reads of completely dead register should be marked undef already"); | ||
|
|
||
| if (LI.hasSubRanges()) { | ||
| for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { | ||
| unsigned Unit = (*Units).first; | ||
| LaneBitmask Mask = (*Units).second; | ||
| for (const LiveInterval::SubRange &S : LI.subranges()) { | ||
| if ((S.LaneMask & UseMask & Mask).any() && S.liveAt(MIIndex)) { | ||
| LiveRegUnits.insert(Unit); | ||
| } | ||
| } | ||
| } | ||
| } else { | ||
| for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { | ||
| unsigned Unit = (*Units).first; | ||
| const LiveRange &UnitRange = LIS->getRegUnit(Unit); | ||
| LaneBitmask Mask = (*Units).second; | ||
|
|
||
| if (UnitRange.liveAt(MIIndex) && (UseMask & Mask).any()) | ||
| LiveRegUnits.insert(Unit); | ||
| } | ||
| } | ||
|
|
||
| // Consider the exact subregister & create new UseMask as per the RC for it. | ||
| if (SubRegIdx != 0) { | ||
| PhysReg = TRI->getSubReg(PhysReg, SubRegIdx); | ||
| UseMask = (TRI->getMinimalPhysRegClass(PhysReg))->getLaneMask(); | ||
| } | ||
|
|
||
| for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { | ||
| unsigned Unit = (*Units).first; | ||
| LaneBitmask Mask = (*Units).second; | ||
| if (LiveRegUnits.count(Unit)) { | ||
| // dbgs() << "LIVE DEF UNIT : " << printRegUnit(Unit, TRI) << '\n'; | ||
| LiveRegUnitMask |= Mask; | ||
| } | ||
| } | ||
|
|
||
| // dbgs() << "UseMask : " << PrintLaneMask(UseMask) << '\n'; | ||
| // dbgs() << "LiveRegUnitMask : " << PrintLaneMask(LiveRegUnitMask) << '\n'; | ||
| if (UseMask == LiveRegUnitMask) | ||
| return 0u; | ||
|
|
||
| return LiveRegUnitMask.getAsInteger(); | ||
| } | ||
|
|
||
| void VirtRegRewriter::handleIdentityCopy(MachineInstr &MI) { | ||
| if (!MI.isIdentityCopy()) | ||
| return; | ||
|
|
@@ -495,7 +568,11 @@ void VirtRegRewriter::handleIdentityCopy(MachineInstr &MI) { | |
| // give us additional liveness information: The target (super-)register | ||
| // must not be valid before this point. Replace the COPY with a KILL | ||
| // instruction to maintain this information. | ||
| if (MI.getOperand(1).isUndef() || MI.getNumOperands() > 2) { | ||
|
|
||
| // Avoid COPY with an exact 3 operand, with third operand be Mask, as | ||
| // it same as a COPY with no additional liveness information. | ||
| if (MI.getOperand(1).isUndef() || MI.getNumOperands() > 3 || | ||
| (MI.getNumOperands() == 3 && !MI.getOperand(2).isImm())) { | ||
| MI.setDesc(TII->get(TargetOpcode::KILL)); | ||
| LLVM_DEBUG(dbgs() << " replace by: " << MI); | ||
| return; | ||
|
|
@@ -641,11 +718,14 @@ void VirtRegRewriter::rewrite() { | |
| SmallVector<Register, 8> SuperDeads; | ||
| SmallVector<Register, 8> SuperDefs; | ||
| SmallVector<Register, 8> SuperKills; | ||
| uint64_t Mask; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, declare it as LaneBitmask. |
||
|
|
||
| for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end(); | ||
| MBBI != MBBE; ++MBBI) { | ||
| LLVM_DEBUG(MBBI->print(dbgs(), Indexes)); | ||
| for (MachineInstr &MI : llvm::make_early_inc_range(MBBI->instrs())) { | ||
| // reset for each MI. | ||
| Mask = 0u; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use LaneBitmask::getNone() to clear all bits. |
||
| for (MachineOperand &MO : MI.operands()) { | ||
| // Make sure MRI knows about registers clobbered by regmasks. | ||
| if (MO.isRegMask()) | ||
|
|
@@ -663,6 +743,9 @@ void VirtRegRewriter::rewrite() { | |
| RewriteRegs.insert(PhysReg); | ||
| assert(!MRI->isReserved(PhysReg) && "Reserved register assignment"); | ||
|
|
||
| if (MO.isUse() && MI.isCopy()) | ||
| Mask = calcLiveRegUnitMask(MO, PhysReg); | ||
|
|
||
| // Preserve semantics of sub-register operands. | ||
| unsigned SubReg = MO.getSubReg(); | ||
| if (SubReg != 0) { | ||
|
|
@@ -739,6 +822,10 @@ void VirtRegRewriter::rewrite() { | |
| MO.setIsRenamable(true); | ||
| } | ||
|
|
||
| // Add LaneBitmask as MO_Imm | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Terminate all single-line comments with a period. |
||
| if (MI.isCopy() && Mask) | ||
| MI.addOperand(*MF, MachineOperand::CreateImm(Mask)); | ||
|
|
||
| // Add any missing super-register kills after rewriting the whole | ||
| // instruction. | ||
| while (!SuperKills.empty()) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should not change the standard copy instruction
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its just for the experimentation purpose, as didn't know exactly where to encode the liveness info as laneMask while working on it! Will go with your suggestion for MO_laneMask now!