+/// hasRegisterUseBelow - Return true if the specified register is used after
+/// the current instruction and before it's next definition.
+bool LiveVariables::hasRegisterUseBelow(unsigned Reg,
+ MachineBasicBlock::iterator I,
+ MachineBasicBlock *MBB) {
+ if (I == MBB->end())
+ return false;
+
+ // First find out if there are any uses / defs below.
+ bool hasDistInfo = true;
+ unsigned CurDist = DistanceMap[I];
+ SmallVector<MachineInstr*, 4> Uses;
+ SmallVector<MachineInstr*, 4> Defs;
+ for (MachineRegisterInfo::reg_iterator RI = MRI->reg_begin(Reg),
+ RE = MRI->reg_end(); RI != RE; ++RI) {
+ MachineOperand &UDO = RI.getOperand();
+ MachineInstr *UDMI = &*RI;
+ if (UDMI->getParent() != MBB)
+ continue;
+ DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(UDMI);
+ bool isBelow = false;
+ if (DI == DistanceMap.end()) {
+ // Must be below if it hasn't been assigned a distance yet.
+ isBelow = true;
+ hasDistInfo = false;
+ } else if (DI->second > CurDist)
+ isBelow = true;
+ if (isBelow) {
+ if (UDO.isUse())
+ Uses.push_back(UDMI);
+ if (UDO.isDef())
+ Defs.push_back(UDMI);
+ }
+ }
+
+ if (Uses.empty())
+ // No uses below.
+ return false;
+ else if (!Uses.empty() && Defs.empty())
+ // There are uses below but no defs below.
+ return true;
+ // There are both uses and defs below. We need to know which comes first.
+ if (!hasDistInfo) {
+ // Complete DistanceMap for this MBB. This information is computed only
+ // once per MBB.
+ ++I;
+ ++CurDist;
+ for (MachineBasicBlock::iterator E = MBB->end(); I != E; ++I, ++CurDist)
+ DistanceMap.insert(std::make_pair(I, CurDist));
+ }
+
+ unsigned EarliestUse = DistanceMap[Uses[0]];
+ for (unsigned i = 1, e = Uses.size(); i != e; ++i) {
+ unsigned Dist = DistanceMap[Uses[i]];
+ if (Dist < EarliestUse)
+ EarliestUse = Dist;
+ }
+ 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;
+ }
+ }