- // If not found, this means an alias of one of the operand is killed. Add a
- // new implicit operand if required.
- if (!Found && AddIfNotFound) {
- MI->addRegOperand(IncomingReg, false/*IsDef*/,true/*IsImp*/,true/*IsKill*/);
- return true;
+/// 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;
+ std::set<unsigned> 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);
+ }
+ }
+ }
+
+ // There was an earlier def of a super-register. Add implicit def to that MI.
+ //
+ // A: EAX = ...
+ // B: ... = AX
+ //
+ // Add implicit def to A if there isn't a use of AX (or EAX) before B.
+ if (!PhysRegUse[Reg]) {
+ MachineInstr *Def = PhysRegDef[Reg];
+ if (Def && !Def->modifiesRegister(Reg))
+ Def->addOperand(MachineOperand::CreateReg(Reg,
+ true /*IsDef*/,
+ true /*IsImp*/));