[CodeGen] Move lowerCopy from expandPostRA to TII

This will allow targets to lower their 'copy' instructions easily.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D152261
This commit is contained in:
Yashwant Singh
2023-07-04 09:04:46 +05:30
parent e18e17aa47
commit 7aebe4eaaa
3 changed files with 61 additions and 67 deletions

View File

@@ -1150,6 +1150,10 @@ public:
MachineInstr &LoadMI,
LiveIntervals *LIS = nullptr) const;
/// This function defines the logic to lower COPY instruction to
/// target specific instruction(s).
void lowerCopy(MachineInstr *MI, const TargetRegisterInfo *TRI) const;
/// Return true when there is potentially a faster code sequence
/// for an instruction chain ending in \p Root. All potential patterns are
/// returned in the \p Pattern vector. Pattern should be sorted in priority

View File

@@ -47,9 +47,6 @@ public:
private:
bool LowerSubregToReg(MachineInstr *MI);
bool LowerCopy(MachineInstr *MI);
void TransferImplicitOperands(MachineInstr *MI);
};
} // end anonymous namespace
@@ -59,25 +56,6 @@ char &llvm::ExpandPostRAPseudosID = ExpandPostRA::ID;
INITIALIZE_PASS(ExpandPostRA, DEBUG_TYPE,
"Post-RA pseudo instruction expansion pass", false, false)
/// TransferImplicitOperands - MI is a pseudo-instruction, and the lowered
/// replacement instructions immediately precede it. Copy any implicit
/// operands from MI to the replacement instruction.
void ExpandPostRA::TransferImplicitOperands(MachineInstr *MI) {
MachineBasicBlock::iterator CopyMI = MI;
--CopyMI;
Register DstReg = MI->getOperand(0).getReg();
for (const MachineOperand &MO : MI->implicit_operands()) {
CopyMI->addOperand(MO);
// Be conservative about preserving kills when subregister defs are
// involved. If there was implicit kill of a super-register overlapping the
// copy result, we would kill the subregisters previous copies defined.
if (MO.isKill() && TRI->regsOverlap(DstReg, MO.getReg()))
CopyMI->getOperand(CopyMI->getNumOperands() - 1).setIsKill(false);
}
}
bool ExpandPostRA::LowerSubregToReg(MachineInstr *MI) {
MachineBasicBlock *MBB = MI->getParent();
assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) &&
@@ -137,50 +115,6 @@ bool ExpandPostRA::LowerSubregToReg(MachineInstr *MI) {
return true;
}
bool ExpandPostRA::LowerCopy(MachineInstr *MI) {
if (MI->allDefsAreDead()) {
LLVM_DEBUG(dbgs() << "dead copy: " << *MI);
MI->setDesc(TII->get(TargetOpcode::KILL));
LLVM_DEBUG(dbgs() << "replaced by: " << *MI);
return true;
}
MachineOperand &DstMO = MI->getOperand(0);
MachineOperand &SrcMO = MI->getOperand(1);
bool IdentityCopy = (SrcMO.getReg() == DstMO.getReg());
if (IdentityCopy || SrcMO.isUndef()) {
LLVM_DEBUG(dbgs() << (IdentityCopy ? "identity copy: " : "undef copy: ")
<< *MI);
// No need to insert an identity copy instruction, but replace with a KILL
// if liveness is changed.
if (SrcMO.isUndef() || MI->getNumOperands() > 2) {
// We must make sure the super-register gets killed. Replace the
// instruction with KILL.
MI->setDesc(TII->get(TargetOpcode::KILL));
LLVM_DEBUG(dbgs() << "replaced by: " << *MI);
return true;
}
// Vanilla identity copy.
MI->eraseFromParent();
return true;
}
LLVM_DEBUG(dbgs() << "real copy: " << *MI);
TII->copyPhysReg(*MI->getParent(), MI, MI->getDebugLoc(),
DstMO.getReg(), SrcMO.getReg(), SrcMO.isKill());
if (MI->getNumOperands() > 2)
TransferImplicitOperands(MI);
LLVM_DEBUG({
MachineBasicBlock::iterator dMI = MI;
dbgs() << "replaced by: " << *(--dMI);
});
MI->eraseFromParent();
return true;
}
/// runOnMachineFunction - Reduce subregister inserts and extracts to register
/// copies.
///
@@ -211,7 +145,8 @@ bool ExpandPostRA::runOnMachineFunction(MachineFunction &MF) {
MadeChange |= LowerSubregToReg(&MI);
break;
case TargetOpcode::COPY:
MadeChange |= LowerCopy(&MI);
TII->lowerCopy(&MI, TRI);
MadeChange = true;
break;
case TargetOpcode::DBG_VALUE:
continue;

View File

@@ -696,6 +696,61 @@ MachineInstr *TargetInstrInfo::foldMemoryOperand(MachineInstr &MI,
return NewMI;
}
/// transferImplicitOperands - MI is a pseudo-instruction, and the lowered
/// replacement instructions immediately precede it. Copy any implicit
/// operands from MI to the replacement instruction.
static void transferImplicitOperands(MachineInstr *MI,
const TargetRegisterInfo *TRI) {
MachineBasicBlock::iterator CopyMI = MI;
--CopyMI;
Register DstReg = MI->getOperand(0).getReg();
for (const MachineOperand &MO : MI->implicit_operands()) {
CopyMI->addOperand(MO);
// Be conservative about preserving kills when subregister defs are
// involved. If there was implicit kill of a super-register overlapping the
// copy result, we would kill the subregisters previous copies defined.
if (MO.isKill() && TRI->regsOverlap(DstReg, MO.getReg()))
CopyMI->getOperand(CopyMI->getNumOperands() - 1).setIsKill(false);
}
}
void TargetInstrInfo::lowerCopy(MachineInstr *MI,
const TargetRegisterInfo *TRI) const {
if (MI->allDefsAreDead()) {
MI->setDesc(get(TargetOpcode::KILL));
return;
}
MachineOperand &DstMO = MI->getOperand(0);
MachineOperand &SrcMO = MI->getOperand(1);
bool IdentityCopy = (SrcMO.getReg() == DstMO.getReg());
if (IdentityCopy || SrcMO.isUndef()) {
// No need to insert an identity copy instruction, but replace with a KILL
// if liveness is changed.
if (SrcMO.isUndef() || MI->getNumOperands() > 2) {
// We must make sure the super-register gets killed. Replace the
// instruction with KILL.
MI->setDesc(get(TargetOpcode::KILL));
return;
}
// Vanilla identity copy.
MI->eraseFromParent();
return;
}
copyPhysReg(*MI->getParent(), MI, MI->getDebugLoc(), DstMO.getReg(),
SrcMO.getReg(), SrcMO.isKill());
if (MI->getNumOperands() > 2)
transferImplicitOperands(MI, TRI);
MI->eraseFromParent();
return;
}
bool TargetInstrInfo::hasReassociableOperands(
const MachineInstr &Inst, const MachineBasicBlock *MBB) const {
const MachineOperand &Op1 = Inst.getOperand(1);