mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-23 13:35:42 -04:00
Teach PHIElimination to handle <undef> operands.
When a PHI use is <undef>, don't emit a copy in the predecessor block, but insert an IMPLICIT_DEF instruction instead. This ensures that virtual register uses are always jointly dominated by defs, even if some of them are IMPLICIT_DEF. llvm-svn: 159121
This commit is contained in:
parent
6b556f824d
commit
70ed924e18
@ -171,21 +171,28 @@ bool PHIElimination::EliminatePHINodes(MachineFunction &MF,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// isImplicitlyDefined - Return true if all defs of VirtReg are implicit-defs.
|
||||||
|
/// This includes registers with no defs.
|
||||||
|
static bool isImplicitlyDefined(unsigned VirtReg,
|
||||||
|
const MachineRegisterInfo *MRI) {
|
||||||
|
for (MachineRegisterInfo::def_iterator DI = MRI->def_begin(VirtReg),
|
||||||
|
DE = MRI->def_end(); DI != DE; ++DI)
|
||||||
|
if (!DI->isImplicitDef())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// isSourceDefinedByImplicitDef - Return true if all sources of the phi node
|
/// isSourceDefinedByImplicitDef - Return true if all sources of the phi node
|
||||||
/// are implicit_def's.
|
/// are implicit_def's.
|
||||||
static bool isSourceDefinedByImplicitDef(const MachineInstr *MPhi,
|
static bool isSourceDefinedByImplicitDef(const MachineInstr *MPhi,
|
||||||
const MachineRegisterInfo *MRI) {
|
const MachineRegisterInfo *MRI) {
|
||||||
for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2) {
|
for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2)
|
||||||
unsigned SrcReg = MPhi->getOperand(i).getReg();
|
if (!isImplicitlyDefined(MPhi->getOperand(i).getReg(), MRI))
|
||||||
const MachineInstr *DefMI = MRI->getVRegDef(SrcReg);
|
|
||||||
if (!DefMI || !DefMI->isImplicitDef())
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// LowerAtomicPHINode - Lower the PHI node at the top of the specified block,
|
/// LowerAtomicPHINode - Lower the PHI node at the top of the specified block,
|
||||||
/// under the assuption that it needs to be lowered in a way that supports
|
/// under the assuption that it needs to be lowered in a way that supports
|
||||||
/// atomic execution of PHIs. This lowering method is always correct all of the
|
/// atomic execution of PHIs. This lowering method is always correct all of the
|
||||||
@ -287,7 +294,8 @@ void PHIElimination::LowerAtomicPHINode(
|
|||||||
for (int i = NumSrcs - 1; i >= 0; --i) {
|
for (int i = NumSrcs - 1; i >= 0; --i) {
|
||||||
unsigned SrcReg = MPhi->getOperand(i*2+1).getReg();
|
unsigned SrcReg = MPhi->getOperand(i*2+1).getReg();
|
||||||
unsigned SrcSubReg = MPhi->getOperand(i*2+1).getSubReg();
|
unsigned SrcSubReg = MPhi->getOperand(i*2+1).getSubReg();
|
||||||
|
bool SrcUndef = MPhi->getOperand(i*2+1).isUndef() ||
|
||||||
|
isImplicitlyDefined(SrcReg, MRI);
|
||||||
assert(TargetRegisterInfo::isVirtualRegister(SrcReg) &&
|
assert(TargetRegisterInfo::isVirtualRegister(SrcReg) &&
|
||||||
"Machine PHI Operands must all be virtual registers!");
|
"Machine PHI Operands must all be virtual registers!");
|
||||||
|
|
||||||
@ -295,14 +303,6 @@ void PHIElimination::LowerAtomicPHINode(
|
|||||||
// path the PHI.
|
// path the PHI.
|
||||||
MachineBasicBlock &opBlock = *MPhi->getOperand(i*2+2).getMBB();
|
MachineBasicBlock &opBlock = *MPhi->getOperand(i*2+2).getMBB();
|
||||||
|
|
||||||
// If source is defined by an implicit def, there is no need to insert a
|
|
||||||
// copy.
|
|
||||||
MachineInstr *DefMI = MRI->getVRegDef(SrcReg);
|
|
||||||
if (DefMI->isImplicitDef()) {
|
|
||||||
ImpDefs.insert(DefMI);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check to make sure we haven't already emitted the copy for this block.
|
// Check to make sure we haven't already emitted the copy for this block.
|
||||||
// This can happen because PHI nodes may have multiple entries for the same
|
// This can happen because PHI nodes may have multiple entries for the same
|
||||||
// basic block.
|
// basic block.
|
||||||
@ -315,12 +315,27 @@ void PHIElimination::LowerAtomicPHINode(
|
|||||||
findPHICopyInsertPoint(&opBlock, &MBB, SrcReg);
|
findPHICopyInsertPoint(&opBlock, &MBB, SrcReg);
|
||||||
|
|
||||||
// Insert the copy.
|
// Insert the copy.
|
||||||
if (!reusedIncoming && IncomingReg)
|
if (!reusedIncoming && IncomingReg) {
|
||||||
BuildMI(opBlock, InsertPos, MPhi->getDebugLoc(),
|
if (SrcUndef) {
|
||||||
TII->get(TargetOpcode::COPY), IncomingReg).addReg(SrcReg, 0, SrcSubReg);
|
// The source register is undefined, so there is no need for a real
|
||||||
|
// COPY, but we still need to ensure joint dominance by defs.
|
||||||
|
// Insert an IMPLICIT_DEF instruction.
|
||||||
|
BuildMI(opBlock, InsertPos, MPhi->getDebugLoc(),
|
||||||
|
TII->get(TargetOpcode::IMPLICIT_DEF), IncomingReg);
|
||||||
|
|
||||||
|
// Clean up the old implicit-def, if there even was one.
|
||||||
|
if (MachineInstr *DefMI = MRI->getVRegDef(SrcReg))
|
||||||
|
if (DefMI->isImplicitDef())
|
||||||
|
ImpDefs.insert(DefMI);
|
||||||
|
} else {
|
||||||
|
BuildMI(opBlock, InsertPos, MPhi->getDebugLoc(),
|
||||||
|
TII->get(TargetOpcode::COPY), IncomingReg)
|
||||||
|
.addReg(SrcReg, 0, SrcSubReg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Now update live variable information if we have it. Otherwise we're done
|
// Now update live variable information if we have it. Otherwise we're done
|
||||||
if (!LV) continue;
|
if (SrcUndef || !LV) continue;
|
||||||
|
|
||||||
// We want to be able to insert a kill of the register if this PHI (aka, the
|
// We want to be able to insert a kill of the register if this PHI (aka, the
|
||||||
// copy we just inserted) is the last use of the source value. Live
|
// copy we just inserted) is the last use of the source value. Live
|
||||||
|
Loading…
Reference in New Issue
Block a user