diff --git a/lib/CodeGen/Spiller.cpp b/lib/CodeGen/Spiller.cpp index 919a0ce160f..405cd8087ac 100644 --- a/lib/CodeGen/Spiller.cpp +++ b/lib/CodeGen/Spiller.cpp @@ -78,24 +78,21 @@ protected: return miIdx; } - /// Insert a store of the given vreg to the given stack slot immediately /// after the given instruction. Returns the base index of the inserted /// instruction. The caller is responsible for adding an appropriate /// LiveInterval to the LiveIntervals analysis. - unsigned insertStoreFor(MachineInstr *mi, unsigned ss, + unsigned insertStoreAfter(MachineInstr *mi, unsigned ss, unsigned vreg, const TargetRegisterClass *trc) { - MachineBasicBlock::iterator nextInstItr(mi); - ++nextInstItr; + MachineBasicBlock::iterator nextInstItr(next(mi)); unsigned miIdx = makeSpaceAfter(mi); tii->storeRegToStackSlot(*mi->getParent(), nextInstItr, vreg, true, ss, trc); - MachineBasicBlock::iterator storeInstItr(mi); - ++storeInstItr; + MachineBasicBlock::iterator storeInstItr(next(mi)); MachineInstr *storeInst = &*storeInstItr; unsigned storeInstIdx = miIdx + LiveInterval::InstrSlots::NUM; @@ -107,37 +104,81 @@ protected: return storeInstIdx; } - void insertStoreOnInterval(LiveInterval *li, - MachineInstr *mi, unsigned ss, - unsigned vreg, - const TargetRegisterClass *trc) { + /// Insert a store of the given vreg to the given stack slot immediately + /// before the given instructnion. Returns the base index of the inserted + /// Instruction. + unsigned insertStoreBefore(MachineInstr *mi, unsigned ss, + unsigned vreg, + const TargetRegisterClass *trc) { + unsigned miIdx = makeSpaceBefore(mi); + + tii->storeRegToStackSlot(*mi->getParent(), mi, vreg, true, ss, trc); + MachineBasicBlock::iterator storeInstItr(prior(mi)); + MachineInstr *storeInst = &*storeInstItr; + unsigned storeInstIdx = miIdx - LiveInterval::InstrSlots::NUM; - unsigned storeInstIdx = insertStoreFor(mi, ss, vreg, trc); + assert(lis->getInstructionFromIndex(storeInstIdx) == 0 && + "Store inst index already in use."); + + lis->InsertMachineInstrInMaps(storeInst, storeInstIdx); + + return storeInstIdx; + } + + void insertStoreAfterInstOnInterval(LiveInterval *li, + MachineInstr *mi, unsigned ss, + unsigned vreg, + const TargetRegisterClass *trc) { + + unsigned storeInstIdx = insertStoreAfter(mi, ss, vreg, trc); unsigned start = lis->getDefIndex(lis->getInstructionIndex(mi)), end = lis->getUseIndex(storeInstIdx); VNInfo *vni = li->getNextValue(storeInstIdx, 0, true, lis->getVNInfoAllocator()); vni->kills.push_back(storeInstIdx); + DOUT << " Inserting store range: [" << start << ", " << end << ")\n"; LiveRange lr(start, end, vni); li->addRange(lr); } - /// Insert a load of the given veg from the given stack slot immediately + /// Insert a load of the given vreg from the given stack slot immediately + /// after the given instruction. Returns the base index of the inserted + /// instruction. The caller is responsibel for adding/removing an appropriate + /// range vreg's LiveInterval. + unsigned insertLoadAfter(MachineInstr *mi, unsigned ss, + unsigned vreg, + const TargetRegisterClass *trc) { + + MachineBasicBlock::iterator nextInstItr(next(mi)); + + unsigned miIdx = makeSpaceAfter(mi); + + tii->loadRegFromStackSlot(*mi->getParent(), nextInstItr, vreg, ss, trc); + MachineBasicBlock::iterator loadInstItr(next(mi)); + MachineInstr *loadInst = &*loadInstItr; + unsigned loadInstIdx = miIdx + LiveInterval::InstrSlots::NUM; + + assert(lis->getInstructionFromIndex(loadInstIdx) == 0 && + "Store inst index already in use."); + + lis->InsertMachineInstrInMaps(loadInst, loadInstIdx); + + return loadInstIdx; + } + + /// Insert a load of the given vreg from the given stack slot immediately /// before the given instruction. Returns the base index of the inserted /// instruction. The caller is responsible for adding an appropriate /// LiveInterval to the LiveIntervals analysis. - unsigned insertLoadFor(MachineInstr *mi, unsigned ss, - unsigned vreg, - const TargetRegisterClass *trc) { - MachineBasicBlock::iterator useInstItr(mi); - + unsigned insertLoadBefore(MachineInstr *mi, unsigned ss, + unsigned vreg, + const TargetRegisterClass *trc) { unsigned miIdx = makeSpaceBefore(mi); - tii->loadRegFromStackSlot(*mi->getParent(), useInstItr, vreg, ss, trc); - MachineBasicBlock::iterator loadInstItr(mi); - --loadInstItr; + tii->loadRegFromStackSlot(*mi->getParent(), mi, vreg, ss, trc); + MachineBasicBlock::iterator loadInstItr(prior(mi)); MachineInstr *loadInst = &*loadInstItr; unsigned loadInstIdx = miIdx - LiveInterval::InstrSlots::NUM; @@ -149,18 +190,19 @@ protected: return loadInstIdx; } - void insertLoadOnInterval(LiveInterval *li, - MachineInstr *mi, unsigned ss, - unsigned vreg, - const TargetRegisterClass *trc) { + void insertLoadBeforeInstOnInterval(LiveInterval *li, + MachineInstr *mi, unsigned ss, + unsigned vreg, + const TargetRegisterClass *trc) { - unsigned loadInstIdx = insertLoadFor(mi, ss, vreg, trc); + unsigned loadInstIdx = insertLoadBefore(mi, ss, vreg, trc); unsigned start = lis->getDefIndex(loadInstIdx), end = lis->getUseIndex(lis->getInstructionIndex(mi)); VNInfo *vni = li->getNextValue(loadInstIdx, 0, true, lis->getVNInfoAllocator()); vni->kills.push_back(lis->getInstructionIndex(mi)); + DOUT << " Intserting load range: [" << start << ", " << end << ")\n"; LiveRange lr(start, end, vni); li->addRange(lr); @@ -180,6 +222,8 @@ protected: assert(!li->isStackSlot() && "Trying to spill a stack slot."); + DOUT << "Trivial spill everywhere of reg" << li->reg << "\n"; + std::vector added; const TargetRegisterClass *trc = mri->getRegClass(li->reg); @@ -189,6 +233,9 @@ protected: regItr = mri->reg_begin(li->reg); regItr != mri->reg_end();) { MachineInstr *mi = &*regItr; + + DOUT << " Processing " << *mi; + do { ++regItr; } while (regItr != mri->reg_end() && (&*regItr == mi)); @@ -227,11 +274,11 @@ protected: assert(hasUse || hasDef); if (hasUse) { - insertLoadOnInterval(newLI, mi, ss, newVReg, trc); + insertLoadBeforeInstOnInterval(newLI, mi, ss, newVReg, trc); } if (hasDef) { - insertStoreOnInterval(newLI, mi, ss, newVReg, trc); + insertStoreAfterInstOnInterval(newLI, mi, ss, newVReg, trc); } added.push_back(newLI); @@ -258,29 +305,53 @@ public: std::vector intraBlockSplit(LiveInterval *li, VNInfo *valno) { std::vector spillIntervals; - MachineBasicBlock::iterator storeInsertPoint; + + if (!valno->isDefAccurate() && !valno->isPHIDef()) { + // Early out for values which have no well defined def point. + return spillIntervals; + } + + // Ok.. we should be able to proceed... + const TargetRegisterClass *trc = mri->getRegClass(li->reg); + unsigned ss = vrm->assignVirt2StackSlot(li->reg); + vrm->grow(); + vrm->assignVirt2StackSlot(li->reg, ss); + + MachineInstr *mi = 0; + unsigned storeIdx = 0; if (valno->isDefAccurate()) { // If we have an accurate def we can just grab an iterator to the instr // after the def. - storeInsertPoint = - next(MachineBasicBlock::iterator(lis->getInstructionFromIndex(valno->def))); + mi = lis->getInstructionFromIndex(valno->def); + storeIdx = insertStoreAfter(mi, ss, li->reg, trc) + + LiveInterval::InstrSlots::DEF; } else { - // If the def info isn't accurate we check if this is a PHI def. - // If it is then def holds the index of the defining Basic Block, and we - // can use that to get an insertion point. - if (valno->isPHIDef()) { - - } else { - // We have no usable def info. We can't split this value sensibly. - // FIXME: Need sensible feedback for "failure to split", an empty - // set of spill intervals could be reasonably returned from a - // split where both the store and load are folded. - return spillIntervals; - } + // if we get here we have a PHI def. + mi = &lis->getMBBFromIndex(valno->def)->front(); + storeIdx = insertStoreBefore(mi, ss, li->reg, trc) + + LiveInterval::InstrSlots::DEF; } - + MachineBasicBlock *defBlock = mi->getParent(); + unsigned loadIdx = 0; + + // Now we need to find the load... + MachineBasicBlock::iterator useItr(mi); + for (; !useItr->readsRegister(li->reg); ++useItr) {} + + if (useItr != defBlock->end()) { + MachineInstr *loadInst = useItr; + loadIdx = insertLoadBefore(loadInst, ss, li->reg, trc) + + LiveInterval::InstrSlots::USE; + } + else { + MachineInstr *loadInst = &defBlock->back(); + loadIdx = insertLoadAfter(loadInst, ss, li->reg, trc) + + LiveInterval::InstrSlots::USE; + } + + li->removeRange(storeIdx, loadIdx, true); return spillIntervals; }