+/// AvailableSpills - As the local spiller is scanning and rewriting an MBB from
+/// top down, keep track of which spills slots are available in each register.
+///
+/// Note that not all physregs are created equal here. In particular, some
+/// physregs are reloads that we are allowed to clobber or ignore at any time.
+/// Other physregs are values that the register allocated program is using that
+/// we cannot CHANGE, but we can read if we like. We keep track of this on a
+/// per-stack-slot basis as the low bit in the value of the SpillSlotsAvailable
+/// entries. The predicate 'canClobberPhysReg()' checks this bit and
+/// addAvailable sets it if.
+namespace {
+class VISIBILITY_HIDDEN AvailableSpills {
+ const MRegisterInfo *MRI;
+ const TargetInstrInfo *TII;
+
+ // SpillSlotsAvailable - This map keeps track of all of the spilled virtual
+ // register values that are still available, due to being loaded or stored to,
+ // but not invalidated yet. It also tracks the instructions that defined
+ // or used the register.
+ typedef std::pair<unsigned, std::vector<MachineInstr*> > SSInfo;
+ std::map<int, SSInfo> SpillSlotsAvailable;
+
+ // PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating
+ // which stack slot values are currently held by a physreg. This is used to
+ // invalidate entries in SpillSlotsAvailable when a physreg is modified.
+ std::multimap<unsigned, int> PhysRegsAvailable;
+
+ void disallowClobberPhysRegOnly(unsigned PhysReg);
+
+ void ClobberPhysRegOnly(unsigned PhysReg);
+public:
+ AvailableSpills(const MRegisterInfo *mri, const TargetInstrInfo *tii)
+ : MRI(mri), TII(tii) {
+ }
+
+ const MRegisterInfo *getRegInfo() const { return MRI; }
+
+ /// getSpillSlotPhysReg - If the specified stack slot is available in a
+ /// physical register, return that PhysReg, otherwise return 0. It also
+ /// returns by reference the instruction that either defines or last uses
+ /// the register.
+ unsigned getSpillSlotPhysReg(int Slot, MachineInstr *&SSMI) const {
+ std::map<int, SSInfo>::const_iterator I = SpillSlotsAvailable.find(Slot);
+ if (I != SpillSlotsAvailable.end()) {
+ if (!I->second.second.empty())
+ SSMI = I->second.second.back();
+ return I->second.first >> 1; // Remove the CanClobber bit.
+ }
+ return 0;
+ }
+
+ /// addLastUse - Add the last use information of all stack slots whose
+ /// values are available in the specific register.
+ void addLastUse(unsigned PhysReg, MachineInstr *Use) {
+ std::multimap<unsigned, int>::iterator I =
+ PhysRegsAvailable.lower_bound(PhysReg);
+ while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
+ int Slot = I->second;
+ I++;
+
+ std::map<int, SSInfo>::iterator II = SpillSlotsAvailable.find(Slot);
+ assert(II != SpillSlotsAvailable.end() && "Slot not available!");
+ unsigned Val = II->second.first;
+ assert((Val >> 1) == PhysReg && "Bidirectional map mismatch!");
+ // This can be true if there are multiple uses of the same register.
+ if (II->second.second.back() != Use)
+ II->second.second.push_back(Use);
+ }
+ }
+
+ /// removeLastUse - Remove the last use information of all stack slots whose
+ /// values are available in the specific register.
+ void removeLastUse(unsigned PhysReg, MachineInstr *Use) {
+ std::multimap<unsigned, int>::iterator I =
+ PhysRegsAvailable.lower_bound(PhysReg);
+ while (I != PhysRegsAvailable.end() && I->first == PhysReg) {
+ int Slot = I->second;
+ I++;
+
+ std::map<int, SSInfo>::iterator II = SpillSlotsAvailable.find(Slot);
+ assert(II != SpillSlotsAvailable.end() && "Slot not available!");
+ unsigned Val = II->second.first;
+ assert((Val >> 1) == PhysReg && "Bidirectional map mismatch!");
+ if (II->second.second.back() == Use)
+ II->second.second.pop_back();
+ }
+ }
+
+ /// addAvailable - Mark that the specified stack slot is available in the
+ /// specified physreg. If CanClobber is true, the physreg can be modified at
+ /// any time without changing the semantics of the program.
+ void addAvailable(int Slot, MachineInstr *MI, unsigned Reg,
+ bool CanClobber = true) {
+ // If this stack slot is thought to be available in some other physreg,
+ // remove its record.
+ ModifyStackSlot(Slot);
+
+ PhysRegsAvailable.insert(std::make_pair(Reg, Slot));
+ std::vector<MachineInstr*> DefUses;
+ DefUses.push_back(MI);
+ SpillSlotsAvailable[Slot] =
+ std::make_pair((Reg << 1) | (unsigned)CanClobber, DefUses);
+
+ if (Slot > VirtRegMap::MAX_STACK_SLOT)
+ DOUT << "Remembering RM#" << Slot-VirtRegMap::MAX_STACK_SLOT-1;
+ else
+ DOUT << "Remembering SS#" << Slot;
+ DOUT << " in physreg " << MRI->getName(Reg) << "\n";
+ }
+
+ /// canClobberPhysReg - Return true if the spiller is allowed to change the
+ /// value of the specified stackslot register if it desires. The specified
+ /// stack slot must be available in a physreg for this query to make sense.
+ bool canClobberPhysReg(int Slot) const {
+ assert(SpillSlotsAvailable.count(Slot) && "Slot not available!");
+ return SpillSlotsAvailable.find(Slot)->second.first & 1;
+ }
+
+ /// disallowClobberPhysReg - Unset the CanClobber bit of the specified
+ /// stackslot register. The register is still available but is no longer
+ /// allowed to be modifed.
+ void disallowClobberPhysReg(unsigned PhysReg);
+
+ /// ClobberPhysReg - This is called when the specified physreg changes
+ /// value. We use this to invalidate any info about stuff we thing lives in
+ /// it and any of its aliases.
+ void ClobberPhysReg(unsigned PhysReg);
+
+ /// ModifyStackSlot - This method is called when the value in a stack slot
+ /// changes. This removes information about which register the previous value
+ /// for this slot lives in (as the previous value is dead now).
+ void ModifyStackSlot(int Slot);
+};
+}
+
+/// disallowClobberPhysRegOnly - Unset the CanClobber bit of the specified
+/// stackslot register. The register is still available but is no longer
+/// allowed to be modifed.
+void AvailableSpills::disallowClobberPhysRegOnly(unsigned PhysReg) {
+ std::multimap<unsigned, int>::iterator I =
+ PhysRegsAvailable.lower_bound(PhysReg);
+ while (I != PhysRegsAvailable.end() && I->first == PhysReg) {