mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[PowerPC] Make StartMI ignore COPY like instructions.
Reviewed By: lkail Differential Revision: https://reviews.llvm.org/D85659
This commit is contained in:
parent
d99b7697f1
commit
91c84c2226
@ -2655,22 +2655,35 @@ const unsigned *PPCInstrInfo::getLoadOpcodesForSpillArray() const {
|
||||
return LoadSpillOpcodesArray[getSpillTarget()];
|
||||
}
|
||||
|
||||
void PPCInstrInfo::fixupIsDeadOrKill(MachineInstr &StartMI, MachineInstr &EndMI,
|
||||
void PPCInstrInfo::fixupIsDeadOrKill(MachineInstr *StartMI, MachineInstr *EndMI,
|
||||
unsigned RegNo) const {
|
||||
// Conservatively clear kill flag for the register if the instructions are in
|
||||
// different basic blocks and in SSA form, because the kill flag may no longer
|
||||
// be right. There is no need to bother with dead flags since defs with no
|
||||
// uses will be handled by DCE.
|
||||
MachineRegisterInfo &MRI = StartMI.getParent()->getParent()->getRegInfo();
|
||||
if (MRI.isSSA() && (StartMI.getParent() != EndMI.getParent())) {
|
||||
MachineRegisterInfo &MRI = StartMI->getParent()->getParent()->getRegInfo();
|
||||
if (MRI.isSSA() && (StartMI->getParent() != EndMI->getParent())) {
|
||||
MRI.clearKillFlags(RegNo);
|
||||
return;
|
||||
}
|
||||
|
||||
// Instructions between [StartMI, EndMI] should be in same basic block.
|
||||
assert((StartMI.getParent() == EndMI.getParent()) &&
|
||||
assert((StartMI->getParent() == EndMI->getParent()) &&
|
||||
"Instructions are not in same basic block");
|
||||
|
||||
// If before RA, StartMI may be def through COPY, we need to adjust it to the
|
||||
// real def. See function getForwardingDefMI.
|
||||
if (MRI.isSSA()) {
|
||||
bool Reads, Writes;
|
||||
std::tie(Reads, Writes) = StartMI->readsWritesVirtualRegister(RegNo);
|
||||
if (!Reads && !Writes) {
|
||||
assert(Register::isVirtualRegister(RegNo) &&
|
||||
"Must be a virtual register");
|
||||
// Get real def and ignore copies.
|
||||
StartMI = MRI.getVRegDef(RegNo);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsKillSet = false;
|
||||
|
||||
auto clearOperandKillInfo = [=] (MachineInstr &MI, unsigned Index) {
|
||||
@ -2683,21 +2696,21 @@ void PPCInstrInfo::fixupIsDeadOrKill(MachineInstr &StartMI, MachineInstr &EndMI,
|
||||
// Set killed flag for EndMI.
|
||||
// No need to do anything if EndMI defines RegNo.
|
||||
int UseIndex =
|
||||
EndMI.findRegisterUseOperandIdx(RegNo, false, &getRegisterInfo());
|
||||
EndMI->findRegisterUseOperandIdx(RegNo, false, &getRegisterInfo());
|
||||
if (UseIndex != -1) {
|
||||
EndMI.getOperand(UseIndex).setIsKill(true);
|
||||
EndMI->getOperand(UseIndex).setIsKill(true);
|
||||
IsKillSet = true;
|
||||
// Clear killed flag for other EndMI operands related to RegNo. In some
|
||||
// upexpected cases, killed may be set multiple times for same register
|
||||
// operand in same MI.
|
||||
for (int i = 0, e = EndMI.getNumOperands(); i != e; ++i)
|
||||
for (int i = 0, e = EndMI->getNumOperands(); i != e; ++i)
|
||||
if (i != UseIndex)
|
||||
clearOperandKillInfo(EndMI, i);
|
||||
clearOperandKillInfo(*EndMI, i);
|
||||
}
|
||||
|
||||
// Walking the inst in reverse order (EndMI -> StartMI].
|
||||
MachineBasicBlock::reverse_iterator It = EndMI;
|
||||
MachineBasicBlock::reverse_iterator E = EndMI.getParent()->rend();
|
||||
MachineBasicBlock::reverse_iterator It = *EndMI;
|
||||
MachineBasicBlock::reverse_iterator E = EndMI->getParent()->rend();
|
||||
// EndMI has been handled above, skip it here.
|
||||
It++;
|
||||
MachineOperand *MO = nullptr;
|
||||
@ -2723,13 +2736,13 @@ void PPCInstrInfo::fixupIsDeadOrKill(MachineInstr &StartMI, MachineInstr &EndMI,
|
||||
} else if ((MO = It->findRegisterDefOperand(RegNo, false, true,
|
||||
&getRegisterInfo()))) {
|
||||
// No use found, set dead for its def.
|
||||
assert(&*It == &StartMI && "No new def between StartMI and EndMI.");
|
||||
assert(&*It == StartMI && "No new def between StartMI and EndMI.");
|
||||
MO->setIsDead(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((&*It) == &StartMI)
|
||||
if ((&*It) == StartMI)
|
||||
break;
|
||||
}
|
||||
// Ensure RegMo liveness is killed after EndMI.
|
||||
@ -3860,7 +3873,7 @@ bool PPCInstrInfo::simplifyToLI(MachineInstr &MI, MachineInstr &DefMI,
|
||||
// ForwardingOperandReg = LI imm1
|
||||
// y = op2 imm2, ForwardingOperandReg(killed)
|
||||
if (IsForwardingOperandKilled)
|
||||
fixupIsDeadOrKill(DefMI, MI, ForwardingOperandReg);
|
||||
fixupIsDeadOrKill(&DefMI, &MI, ForwardingOperandReg);
|
||||
|
||||
LLVM_DEBUG(dbgs() << "With:\n");
|
||||
LLVM_DEBUG(MI.dump());
|
||||
@ -3952,9 +3965,9 @@ bool PPCInstrInfo::transformToNewImmFormFedByAdd(
|
||||
|
||||
// Update kill flag
|
||||
if (RegMO->isKill() || IsKilledFor(RegMO->getReg()))
|
||||
fixupIsDeadOrKill(DefMI, MI, RegMO->getReg());
|
||||
fixupIsDeadOrKill(&DefMI, &MI, RegMO->getReg());
|
||||
if (ForwardKilledOperandReg != ~0U)
|
||||
fixupIsDeadOrKill(DefMI, MI, ForwardKilledOperandReg);
|
||||
fixupIsDeadOrKill(&DefMI, &MI, ForwardKilledOperandReg);
|
||||
}
|
||||
|
||||
LLVM_DEBUG(dbgs() << "With:\n");
|
||||
@ -4065,12 +4078,12 @@ bool PPCInstrInfo::transformToImmFormFedByAdd(
|
||||
// x = ADD reg(killed), imm
|
||||
// y = XOP 0, x
|
||||
if (IsFwdFeederRegKilled || RegMO->isKill())
|
||||
fixupIsDeadOrKill(DefMI, MI, RegMO->getReg());
|
||||
fixupIsDeadOrKill(&DefMI, &MI, RegMO->getReg());
|
||||
// Pattern 3:
|
||||
// ForwardKilledOperandReg = ADD reg, imm
|
||||
// y = XOP 0, ForwardKilledOperandReg(killed)
|
||||
if (ForwardKilledOperandReg != ~0U)
|
||||
fixupIsDeadOrKill(DefMI, MI, ForwardKilledOperandReg);
|
||||
fixupIsDeadOrKill(&DefMI, &MI, ForwardKilledOperandReg);
|
||||
|
||||
LLVM_DEBUG(dbgs() << "With:\n");
|
||||
LLVM_DEBUG(MI.dump());
|
||||
@ -4226,7 +4239,7 @@ bool PPCInstrInfo::transformToImmFormFedByLI(MachineInstr &MI,
|
||||
// ForwardKilledOperandReg = LI imm
|
||||
// y = XOP reg, ForwardKilledOperandReg(killed)
|
||||
if (ForwardKilledOperandReg != ~0U)
|
||||
fixupIsDeadOrKill(DefMI, MI, ForwardKilledOperandReg);
|
||||
fixupIsDeadOrKill(&DefMI, &MI, ForwardKilledOperandReg);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -567,14 +567,16 @@ public:
|
||||
/// up. Before calling this function,
|
||||
/// 1. Ensure that \p RegNo liveness is killed after instruction \p EndMI.
|
||||
/// 2. Ensure that there is no new definition between (\p StartMI, \p EndMI)
|
||||
/// and possible definition for \p RegNo is \p StartMI or \p EndMI.
|
||||
/// and possible definition for \p RegNo is \p StartMI or \p EndMI. For
|
||||
/// pre-RA cases, definition may be \p StartMI through COPY, \p StartMI
|
||||
/// will be adjust to true definition.
|
||||
/// 3. We can do accurate fixup for the case when all instructions between
|
||||
/// [\p StartMI, \p EndMI] are in same basic block.
|
||||
/// 4. For the case when \p StartMI and \p EndMI are not in same basic block,
|
||||
/// we conservatively clear kill flag for all uses of \p RegNo for pre-RA
|
||||
/// and for post-RA, we give an assertion as without reaching definition
|
||||
/// analysis post-RA, \p StartMI and \p EndMI are hard to keep right.
|
||||
void fixupIsDeadOrKill(MachineInstr &StartMI, MachineInstr &EndMI,
|
||||
void fixupIsDeadOrKill(MachineInstr *StartMI, MachineInstr *EndMI,
|
||||
unsigned RegNo) const;
|
||||
void replaceInstrWithLI(MachineInstr &MI, const LoadImmediateInfo &LII) const;
|
||||
void replaceInstrOperandWithImm(MachineInstr &MI, unsigned OpNo,
|
||||
|
@ -19,3 +19,20 @@ body: |
|
||||
STW killed %4:gprc, %4:gprc, 100
|
||||
BLR8 implicit $lr8, implicit $rm
|
||||
...
|
||||
---
|
||||
name: test2
|
||||
#CHECK : name : test2
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $r3
|
||||
%0:gprc = COPY $r3
|
||||
%1:gprc_and_gprc_nor0 = LI 0
|
||||
; CHECK: dead %2:gprc = COPY %1
|
||||
%2:gprc = COPY %1:gprc_and_gprc_nor0
|
||||
; CHECK: %3:gprc = LI 1
|
||||
%3:gprc = ORI killed %2:gprc, 1
|
||||
; CHECK: STW killed %3, %0, 100
|
||||
STW killed %3:gprc, %0:gprc, 100
|
||||
BLR8 implicit $lr8, implicit $rm
|
||||
...
|
||||
|
Loading…
x
Reference in New Issue
Block a user