diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2009-08-08 13:19:25 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2009-08-08 13:19:25 +0000 |
commit | 710b13b2c2257d65779fd6380e27b823b06a74a9 (patch) | |
tree | 0d33b7f7f9e703aebef9fffbdd536006b2706979 /lib | |
parent | 9390cd0e86cb3b79f6836acab2a27b275e5bde9e (diff) | |
download | external_llvm-710b13b2c2257d65779fd6380e27b823b06a74a9.zip external_llvm-710b13b2c2257d65779fd6380e27b823b06a74a9.tar.gz external_llvm-710b13b2c2257d65779fd6380e27b823b06a74a9.tar.bz2 |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78467 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/MachineVerifier.cpp | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp index 16d06a7..e6ed180 100644 --- a/lib/CodeGen/MachineVerifier.cpp +++ b/lib/CodeGen/MachineVerifier.cpp @@ -78,7 +78,8 @@ namespace { BitVector regsReserved; RegSet regsLive; - RegVector regsDefined, regsImpDefined, regsDead, regsKilled; + RegVector regsDefined, regsDead, regsKilled; + RegSet regsLiveInButUnused; // Add Reg and any sub-registers to RV void addRegWithSubRegs(RegVector &RV, unsigned Reg) { @@ -306,9 +307,9 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) for (const unsigned *R = TRI->getSubRegisters(*I); *R; R++) regsLive.insert(*R); } + regsLiveInButUnused = regsLive; regsKilled.clear(); regsDefined.clear(); - regsImpDefined.clear(); } void @@ -352,7 +353,11 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) return; // 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()) { addRegWithSubRegs(regsKilled, Reg); // 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) addRegWithSubRegs(regsKilled, Reg); } - // Use of a dead register. A register use marked <undef> is OK. - if (!MO->isUndef() && !regsLive.count(Reg)) { + // Use of a dead register. + if (!regsLive.count(Reg)) { if (TargetRegisterInfo::isPhysicalRegister(Reg)) { // Reserved registers may be used even when 'dead'. if (!isReserved(Reg)) @@ -384,12 +389,13 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) } } } else { + assert(MO->isDef()); // Register defined. // TODO: verify that earlyclobber ops are not used. - addRegWithSubRegs(regsDefined, Reg); - if (MO->isDead()) addRegWithSubRegs(regsDead, Reg); + else + addRegWithSubRegs(regsDefined, Reg); } // Check register classes. @@ -456,11 +462,16 @@ MachineVerifier::visitMachineInstrAfter(const MachineInstr *MI) set_subtract(regsLive, regsKilled); regsKilled.clear(); - for (RegVector::const_iterator I = regsDefined.begin(), - E = regsDefined.end(); I != E; ++I) { + // Verify that both <def> and <def,dead> operands refer to dead registers. + 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 (TargetRegisterInfo::isPhysicalRegister(*I)) { - if (!allowPhysDoubleDefs && !isReserved(*I)) { + if (!allowPhysDoubleDefs && !isReserved(*I) && + !regsLiveInButUnused.count(*I)) { report("Redefining a live physical register", MI); *OS << "Register " << TRI->getName(*I) << " 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_union(regsLive, regsDefined); regsDefined.clear(); } void |