X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FVirtRegMap.cpp;h=e2dc636e69119c00377748613022631b4aada493;hb=58b1ac76d470eb5faa7e98feae97c4906d4d146e;hp=5a37738a2f6e59bc03c41f1041288f5e4e05fd04;hpb=752272a5e553313f7b0397a06a23b4fe8ac013c4;p=oota-llvm.git diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 5a37738a2f6..e2dc636e691 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -407,6 +407,8 @@ public: /// slot changes. This removes information about which register the previous /// value for this slot lives in (as the previous value is dead now). void ModifyStackSlotOrReMat(int SlotOrReMat); + + void AddAvailableRegsToLiveIn(MachineBasicBlock &MBB); }; } @@ -486,6 +488,28 @@ void AvailableSpills::ModifyStackSlotOrReMat(int SlotOrReMat) { PhysRegsAvailable.erase(I); } +/// AddAvailableRegsToLiveIn - Availability information is being kept coming +/// into the specified MBB. Add available physical registers as live-in's +/// so register scavenger and post-allocation scheduler are happy. +void AvailableSpills::AddAvailableRegsToLiveIn(MachineBasicBlock &MBB) { + for (std::multimap::iterator + I = PhysRegsAvailable.begin(), E = PhysRegsAvailable.end(); + I != E; ++I) { + unsigned Reg = (*I).first; + const TargetRegisterClass* RC = TRI->getPhysicalRegisterRegClass(Reg); + // FIXME: A temporary workaround. We can't reuse available value if it's + // not safe to move the def of the virtual register's class. e.g. + // X86::RFP* register classes. Do not add it as a live-in. + if (!TII->isSafeToMoveRegClassDefs(RC)) + continue; + if (!MBB.isLiveIn(Reg)) + MBB.addLiveIn(Reg); + } +} + +/// findSinglePredSuccessor - Return via reference a vector of machine basic +/// blocks each of which is a successor of the specified BB and has no other +/// predecessor. static void findSinglePredSuccessor(MachineBasicBlock *MBB, SmallVectorImpl &Succs) { for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), @@ -497,8 +521,6 @@ static void findSinglePredSuccessor(MachineBasicBlock *MBB, } namespace { - class AvailableSpills; - /// LocalSpiller - This spiller does a simple pass over the machine basic /// block to attempt to keep spills in registers as much as possible for /// blocks that have low register pressure (the vreg may be spilled due to @@ -551,8 +573,10 @@ namespace { // FIXME: More than one successors, each of which has MBB has // the only predecessor. MBB = SinglePredSuccs[0]; - if (!Visited.count(MBB) && EarlyVisited.insert(MBB)) + if (!Visited.count(MBB) && EarlyVisited.insert(MBB)) { + Spills.AddAvailableRegsToLiveIn(*MBB); RewriteMBB(*MBB, VRM, Spills); + } } } while (MBB); @@ -1029,7 +1053,7 @@ bool LocalSpiller::PrepForUnfoldOpti(MachineBasicBlock &MBB, NewMIs.clear(); int Idx = NewMI->findRegisterUseOperandIdx(VirtReg, false); assert(Idx != -1); - SmallVector Ops; + SmallVector Ops; Ops.push_back(Idx); MachineInstr *FoldedMI = TII->foldMemoryOperand(MF, NewMI, Ops, SS); if (FoldedMI) { @@ -1100,7 +1124,7 @@ bool LocalSpiller::CommuteToFoldReload(MachineBasicBlock &MBB, MachineInstr *CommutedMI = TII->commuteInstruction(DefMI, true); if (!CommutedMI) return false; - SmallVector Ops; + SmallVector Ops; Ops.push_back(NewDstIdx); MachineInstr *FoldedMI = TII->foldMemoryOperand(MF, CommutedMI, Ops, SS); // Not needed since foldMemoryOperand returns new MI. @@ -1343,9 +1367,12 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM, bool DoReMat = VRM.isReMaterialized(VirtReg); int SSorRMId = DoReMat ? VRM.getReMatId(VirtReg) : VRM.getStackSlot(VirtReg); - unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SSorRMId); - assert((!InReg || !RegKills[InReg]) && - "Restoring a value that's previously defined in the same BB?"); + const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg); + // FIXME: A temporary workaround. Don't reuse available value if it's + // not safe to move the def of the virtual register's class. e.g. + // X86::RFP* register classes. + unsigned InReg = TII->isSafeToMoveRegClassDefs(RC) ? + Spills.getSpillSlotOrReMatPhysReg(SSorRMId) : 0; if (InReg == Phys) { // If the value is already available in the expected register, save // a reload / remat. @@ -1371,7 +1398,6 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM, // If the reloaded / remat value is available in another register, // copy it to the desired register. - const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg); TII->copyRegToReg(MBB, &MI, Phys, InReg, RC, RC); // This invalidates Phys. @@ -1573,6 +1599,12 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM, PotentialDeadStoreSlots.push_back(ReuseSlot); } + + // Assumes this is the last use. IsKill will be unset if reg is reused + // unless it's a two-address operand. + if (ti == -1) + MI.getOperand(i).setIsKill(); + continue; } // CanReuse @@ -1738,6 +1770,11 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM, DefMO = NextMII->findRegisterDefOperand(DestReg); DefMO->setSubReg(SubIdx); } + + // Mark is killed. + MachineOperand *KillOpnd = NextMII->findRegisterUseOperand(InReg); + KillOpnd->setIsKill(); + BackTracked = true; } else { DOUT << "Removing now-noop copy: " << MI;