mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
Update the machine code verifier to keep up with the scavenger.
* Cleaner handling of <undef>. * <def> takes precedence over <def,dead>. * Implement the OK-to-redefine-a-register-that-was- live-in-but-has-not-been-used-before rule. llvm-svn: 78467
This commit is contained in:
parent
153d425bb6
commit
040c46d86d
@ -78,7 +78,8 @@ namespace {
|
|||||||
|
|
||||||
BitVector regsReserved;
|
BitVector regsReserved;
|
||||||
RegSet regsLive;
|
RegSet regsLive;
|
||||||
RegVector regsDefined, regsImpDefined, regsDead, regsKilled;
|
RegVector regsDefined, regsDead, regsKilled;
|
||||||
|
RegSet regsLiveInButUnused;
|
||||||
|
|
||||||
// Add Reg and any sub-registers to RV
|
// Add Reg and any sub-registers to RV
|
||||||
void addRegWithSubRegs(RegVector &RV, unsigned Reg) {
|
void addRegWithSubRegs(RegVector &RV, unsigned Reg) {
|
||||||
@ -306,9 +307,9 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB)
|
|||||||
for (const unsigned *R = TRI->getSubRegisters(*I); *R; R++)
|
for (const unsigned *R = TRI->getSubRegisters(*I); *R; R++)
|
||||||
regsLive.insert(*R);
|
regsLive.insert(*R);
|
||||||
}
|
}
|
||||||
|
regsLiveInButUnused = regsLive;
|
||||||
regsKilled.clear();
|
regsKilled.clear();
|
||||||
regsDefined.clear();
|
regsDefined.clear();
|
||||||
regsImpDefined.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -352,7 +353,11 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Check Live Variables.
|
// Check Live Variables.
|
||||||
if (MO->isUse()) {
|
if (MO->isUndef()) {
|
||||||
|
// An <undef> doesn't refer to any register, so just skip it.
|
||||||
|
} else if (MO->isUse()) {
|
||||||
|
regsLiveInButUnused.erase(Reg);
|
||||||
|
|
||||||
if (MO->isKill()) {
|
if (MO->isKill()) {
|
||||||
addRegWithSubRegs(regsKilled, Reg);
|
addRegWithSubRegs(regsKilled, Reg);
|
||||||
// Tied operands on two-address instuctions MUST NOT have a <kill> flag.
|
// Tied operands on two-address instuctions MUST NOT have a <kill> flag.
|
||||||
@ -366,8 +371,8 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum)
|
|||||||
MI->getOperand(defIdx).getReg() == Reg)
|
MI->getOperand(defIdx).getReg() == Reg)
|
||||||
addRegWithSubRegs(regsKilled, Reg);
|
addRegWithSubRegs(regsKilled, Reg);
|
||||||
}
|
}
|
||||||
// Use of a dead register. A register use marked <undef> is OK.
|
// Use of a dead register.
|
||||||
if (!MO->isUndef() && !regsLive.count(Reg)) {
|
if (!regsLive.count(Reg)) {
|
||||||
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
|
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
|
||||||
// Reserved registers may be used even when 'dead'.
|
// Reserved registers may be used even when 'dead'.
|
||||||
if (!isReserved(Reg))
|
if (!isReserved(Reg))
|
||||||
@ -384,12 +389,13 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
assert(MO->isDef());
|
||||||
// Register defined.
|
// Register defined.
|
||||||
// TODO: verify that earlyclobber ops are not used.
|
// TODO: verify that earlyclobber ops are not used.
|
||||||
addRegWithSubRegs(regsDefined, Reg);
|
|
||||||
|
|
||||||
if (MO->isDead())
|
if (MO->isDead())
|
||||||
addRegWithSubRegs(regsDead, Reg);
|
addRegWithSubRegs(regsDead, Reg);
|
||||||
|
else
|
||||||
|
addRegWithSubRegs(regsDefined, Reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check register classes.
|
// Check register classes.
|
||||||
@ -456,11 +462,16 @@ MachineVerifier::visitMachineInstrAfter(const MachineInstr *MI)
|
|||||||
set_subtract(regsLive, regsKilled);
|
set_subtract(regsLive, regsKilled);
|
||||||
regsKilled.clear();
|
regsKilled.clear();
|
||||||
|
|
||||||
for (RegVector::const_iterator I = regsDefined.begin(),
|
// Verify that both <def> and <def,dead> operands refer to dead registers.
|
||||||
E = regsDefined.end(); I != E; ++I) {
|
RegVector defs(regsDefined);
|
||||||
|
defs.append(regsDead.begin(), regsDead.end());
|
||||||
|
|
||||||
|
for (RegVector::const_iterator I = defs.begin(), E = defs.end();
|
||||||
|
I != E; ++I) {
|
||||||
if (regsLive.count(*I)) {
|
if (regsLive.count(*I)) {
|
||||||
if (TargetRegisterInfo::isPhysicalRegister(*I)) {
|
if (TargetRegisterInfo::isPhysicalRegister(*I)) {
|
||||||
if (!allowPhysDoubleDefs && !isReserved(*I)) {
|
if (!allowPhysDoubleDefs && !isReserved(*I) &&
|
||||||
|
!regsLiveInButUnused.count(*I)) {
|
||||||
report("Redefining a live physical register", MI);
|
report("Redefining a live physical register", MI);
|
||||||
*OS << "Register " << TRI->getName(*I)
|
*OS << "Register " << TRI->getName(*I)
|
||||||
<< " was defined but already live.\n";
|
<< " was defined but already live.\n";
|
||||||
@ -480,9 +491,8 @@ MachineVerifier::visitMachineInstrAfter(const MachineInstr *MI)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_union(regsLive, regsDefined); regsDefined.clear();
|
|
||||||
set_union(regsLive, regsImpDefined); regsImpDefined.clear();
|
|
||||||
set_subtract(regsLive, regsDead); regsDead.clear();
|
set_subtract(regsLive, regsDead); regsDead.clear();
|
||||||
|
set_union(regsLive, regsDefined); regsDefined.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user