+ for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
+ unsigned Dist = DistanceMap[Defs[i]];
+ if (Dist < EarliestUse)
+ // The register is defined before its first use below.
+ return false;
+ }
+ return true;
+}
+
+bool LiveVariables::HandlePhysRegKill(unsigned Reg) {
+ if (!PhysRegUse[Reg] && !PhysRegDef[Reg])
+ return false;
+
+ MachineInstr *LastRefOrPartRef = PhysRegUse[Reg]
+ ? PhysRegUse[Reg] : PhysRegDef[Reg];
+ unsigned LastRefOrPartRefDist = DistanceMap[LastRefOrPartRef];
+ // The whole register is used.
+ // AL =
+ // AH =
+ //
+ // = AX
+ // = AL, AX<imp-use, kill>
+ // AX =
+ //
+ // Or whole register is defined, but not used at all.
+ // AX<dead> =
+ // ...
+ // AX =
+ //
+ // Or whole register is defined, but only partly used.
+ // AX<dead> = AL<imp-def>
+ // = AL<kill>
+ // AX =
+ std::set<unsigned> PartUses;
+ for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
+ unsigned SubReg = *SubRegs; ++SubRegs) {
+ if (MachineInstr *Use = PhysRegUse[SubReg]) {
+ PartUses.insert(SubReg);
+ for (const unsigned *SS = TRI->getSubRegisters(SubReg); *SS; ++SS)
+ PartUses.insert(*SS);
+ unsigned Dist = DistanceMap[Use];
+ if (Dist > LastRefOrPartRefDist) {
+ LastRefOrPartRefDist = Dist;
+ LastRefOrPartRef = Use;
+ }
+ }
+ }
+ if (LastRefOrPartRef == PhysRegDef[Reg])
+ // Not used at all.
+ LastRefOrPartRef->addRegisterDead(Reg, TRI, true);
+
+ /* Partial uses. Mark register def dead and add implicit def of
+ sub-registers which are used.
+ FIXME: LiveIntervalAnalysis can't handle this yet!
+ EAX<dead> = op AL<imp-def>
+ That is, EAX def is dead but AL def extends pass it.
+ Enable this after live interval analysis is fixed to improve codegen!
+ else if (!PhysRegUse[Reg]) {
+ PhysRegDef[Reg]->addRegisterDead(Reg, TRI, true);
+ for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
+ unsigned SubReg = *SubRegs; ++SubRegs) {
+ if (PartUses.count(SubReg)) {
+ PhysRegDef[Reg]->addOperand(MachineOperand::CreateReg(SubReg,
+ true, true));
+ LastRefOrPartRef->addRegisterKilled(SubReg, TRI, true);
+ for (const unsigned *SS = TRI->getSubRegisters(SubReg); *SS; ++SS)
+ PartUses.erase(*SS);
+ }
+ }
+ } */
+ else
+ LastRefOrPartRef->addRegisterKilled(Reg, TRI, true);
+ return true;