+// ReusedOp - For each reused operand, we keep track of a bit of information, in
+// case we need to rollback upon processing a new operand. See comments below.
+namespace {
+ struct ReusedOp {
+ // The MachineInstr operand that reused an available value.
+ unsigned Operand;
+
+ // StackSlot - The spill slot of the value being reused.
+ unsigned StackSlot;
+
+ // PhysRegReused - The physical register the value was available in.
+ unsigned PhysRegReused;
+
+ // AssignedPhysReg - The physreg that was assigned for use by the reload.
+ unsigned AssignedPhysReg;
+
+ ReusedOp(unsigned o, unsigned ss, unsigned prr, unsigned apr)
+ : Operand(o), StackSlot(ss), PhysRegReused(prr), AssignedPhysReg(apr) {}
+ };
+}
+
+
+/// rewriteMBB - Keep track of which spills are available even after the
+/// register allocator is done with them. If possible, avoid reloading vregs.
+void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
+
+ // SpillSlotsAvailable - This map keeps track of all of the spilled virtual
+ // register values that are still available, due to being loaded to stored to,
+ // but not invalidated yet.
+ std::map<int, unsigned> SpillSlotsAvailable;
+
+ // PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating
+ // which physregs are in use holding a stack slot value.
+ std::map<unsigned, int> PhysRegsAvailable;
+
+ DEBUG(std::cerr << MBB.getBasicBlock()->getName() << ":\n");
+
+ std::vector<ReusedOp> ReusedOperands;
+
+ // DefAndUseVReg - When we see a def&use operand that is spilled, keep track
+ // of it. ".first" is the machine operand index (should always be 0 for now),
+ // and ".second" is the virtual register that is spilled.
+ std::vector<std::pair<unsigned, unsigned> > DefAndUseVReg;
+
+ // MaybeDeadStores - When we need to write a value back into a stack slot,
+ // keep track of the inserted store. If the stack slot value is never read
+ // (because the value was used from some available register, for example), and
+ // subsequently stored to, the original store is dead. This map keeps track
+ // of inserted stores that are not used. If we see a subsequent store to the
+ // same stack slot, the original store is deleted.
+ std::map<int, MachineInstr*> MaybeDeadStores;
+
+ bool *PhysRegsUsed = MBB.getParent()->getUsedPhysregs();
+
+ for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end();
+ MII != E; ) {
+ MachineInstr &MI = *MII;
+ MachineBasicBlock::iterator NextMII = MII; ++NextMII;
+
+ ReusedOperands.clear();
+ DefAndUseVReg.clear();
+
+ // Process all of the spilled uses and all non spilled reg references.
+ for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI.getOperand(i);
+ if (!MO.isRegister() || MO.getReg() == 0)
+ continue; // Ignore non-register operands.
+
+ if (MRegisterInfo::isPhysicalRegister(MO.getReg())) {
+ // Ignore physregs for spilling, but remember that it is used by this
+ // function.
+ PhysRegsUsed[MO.getReg()] = true;
+ continue;
+ }
+
+ assert(MRegisterInfo::isVirtualRegister(MO.getReg()) &&
+ "Not a virtual or a physical register?");
+
+ unsigned VirtReg = MO.getReg();
+ if (!VRM.hasStackSlot(VirtReg)) {
+ // This virtual register was assigned a physreg!
+ unsigned Phys = VRM.getPhys(VirtReg);
+ PhysRegsUsed[Phys] = true;
+ MI.SetMachineOperandReg(i, Phys);
+ continue;
+ }
+
+ // This virtual register is now known to be a spilled value.
+ if (!MO.isUse())
+ continue; // Handle defs in the loop below (handle use&def here though)
+
+ // If this is both a def and a use, we need to emit a store to the
+ // stack slot after the instruction. Keep track of D&U operands
+ // because we are about to change it to a physreg here.
+ if (MO.isDef()) {
+ // Remember that this was a def-and-use operand, and that the
+ // stack slot is live after this instruction executes.
+ DefAndUseVReg.push_back(std::make_pair(i, VirtReg));
+ }
+
+ int StackSlot = VRM.getStackSlot(VirtReg);
+ unsigned PhysReg;
+
+ // Check to see if this stack slot is available.
+ std::map<int, unsigned>::iterator SSI =
+ SpillSlotsAvailable.find(StackSlot);
+ if (SSI != SpillSlotsAvailable.end()) {
+ DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg "
+ << MRI->getName(SSI->second) << " for vreg"
+ << VirtReg <<" instead of reloading into physreg "
+ << MRI->getName(VRM.getPhys(VirtReg)) << "\n");
+ // If this stack slot value is already available, reuse it!
+ PhysReg = SSI->second;
+ MI.SetMachineOperandReg(i, PhysReg);
+
+ // The only technical detail we have is that we don't know that
+ // PhysReg won't be clobbered by a reloaded stack slot that occurs
+ // later in the instruction. In particular, consider 'op V1, V2'.
+ // If V1 is available in physreg R0, we would choose to reuse it
+ // here, instead of reloading it into the register the allocator
+ // indicated (say R1). However, V2 might have to be reloaded
+ // later, and it might indicate that it needs to live in R0. When
+ // this occurs, we need to have information available that
+ // indicates it is safe to use R1 for the reload instead of R0.
+ //
+ // To further complicate matters, we might conflict with an alias,
+ // or R0 and R1 might not be compatible with each other. In this
+ // case, we actually insert a reload for V1 in R1, ensuring that
+ // we can get at R0 or its alias.
+ ReusedOperands.push_back(ReusedOp(i, StackSlot, PhysReg,
+ VRM.getPhys(VirtReg)));
+ ++NumReused;
+ continue;