-/// addRegisterKills - For all of a register's sub-registers that are killed in
-/// at this machine instruction, mark them as "killed". (If the machine operand
-/// isn't found, add it first.)
-void LiveVariables::addRegisterKills(unsigned Reg, MachineInstr *MI,
- SmallSet<unsigned, 4> &SubKills) {
- if (SubKills.count(Reg) == 0) {
- MI->addRegisterKilled(Reg, TRI, true);
- return;
+/// HandlePhysRegUse - Turn previous partial def's into read/mod/writes. Add
+/// implicit defs to a machine instruction if there was an earlier def of its
+/// super-register.
+void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) {
+ // If there was a previous use or a "full" def all is well.
+ if (!PhysRegDef[Reg] && !PhysRegUse[Reg]) {
+ // Otherwise, the last sub-register def implicitly defines this register.
+ // e.g.
+ // AH =
+ // AL = ... <imp-def EAX>, <imp-kill AH>
+ // = AH
+ // ...
+ // = EAX
+ // All of the sub-registers must have been defined before the use of Reg!
+ unsigned PartDefReg = 0;
+ MachineInstr *LastPartialDef = FindLastPartialDef(Reg, PartDefReg);
+ // If LastPartialDef is NULL, it must be using a livein register.
+ if (LastPartialDef) {
+ LastPartialDef->addOperand(MachineOperand::CreateReg(Reg, true/*IsDef*/,
+ true/*IsImp*/));
+ PhysRegDef[Reg] = LastPartialDef;
+ SmallSet<unsigned, 8> Processed;
+ for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
+ unsigned SubReg = *SubRegs; ++SubRegs) {
+ if (Processed.count(SubReg))
+ continue;
+ if (SubReg == PartDefReg || TRI->isSubRegister(PartDefReg, SubReg))
+ continue;
+ // This part of Reg was defined before the last partial def. It's killed
+ // here.
+ LastPartialDef->addOperand(MachineOperand::CreateReg(SubReg,
+ false/*IsDef*/,
+ true/*IsImp*/));
+ PhysRegDef[SubReg] = LastPartialDef;
+ for (const unsigned *SS = TRI->getSubRegisters(SubReg); *SS; ++SS)
+ Processed.insert(*SS);
+ }
+ }