diff options
Diffstat (limited to 'lib/CodeGen/Spiller.cpp')
-rw-r--r-- | lib/CodeGen/Spiller.cpp | 95 |
1 files changed, 73 insertions, 22 deletions
diff --git a/lib/CodeGen/Spiller.cpp b/lib/CodeGen/Spiller.cpp index 55642aa3f4..919a0ce160 100644 --- a/lib/CodeGen/Spiller.cpp +++ b/lib/CodeGen/Spiller.cpp @@ -39,7 +39,8 @@ protected: VirtRegMap *vrm; /// Construct a spiller base. - SpillerBase(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls, VirtRegMap *vrm) : + SpillerBase(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls, + VirtRegMap *vrm) : mf(mf), lis(lis), ls(ls), vrm(vrm) { mfi = mf->getFrameInfo(); @@ -85,6 +86,7 @@ protected: unsigned insertStoreFor(MachineInstr *mi, unsigned ss, unsigned vreg, const TargetRegisterClass *trc) { + MachineBasicBlock::iterator nextInstItr(mi); ++nextInstItr; @@ -105,6 +107,23 @@ protected: return storeInstIdx; } + void insertStoreOnInterval(LiveInterval *li, + MachineInstr *mi, unsigned ss, + unsigned vreg, + const TargetRegisterClass *trc) { + + unsigned storeInstIdx = insertStoreFor(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); + LiveRange lr(start, end, vni); + + li->addRange(lr); + } + /// Insert a load of the given veg 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 @@ -130,6 +149,25 @@ protected: return loadInstIdx; } + void insertLoadOnInterval(LiveInterval *li, + MachineInstr *mi, unsigned ss, + unsigned vreg, + const TargetRegisterClass *trc) { + + unsigned loadInstIdx = insertLoadFor(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)); + LiveRange lr(start, end, vni); + + li->addRange(lr); + } + + + /// Add spill ranges for every use/def of the live interval, inserting loads /// immediately before each use, and stores after each def. No folding is /// attempted. @@ -189,29 +227,11 @@ protected: assert(hasUse || hasDef); if (hasUse) { - unsigned loadInstIdx = insertLoadFor(mi, ss, newVReg, trc); - unsigned start = lis->getDefIndex(loadInstIdx), - end = lis->getUseIndex(lis->getInstructionIndex(mi)); - - VNInfo *vni = - newLI->getNextValue(loadInstIdx, 0, true, lis->getVNInfoAllocator()); - vni->kills.push_back(lis->getInstructionIndex(mi)); - LiveRange lr(start, end, vni); - - newLI->addRange(lr); + insertLoadOnInterval(newLI, mi, ss, newVReg, trc); } if (hasDef) { - unsigned storeInstIdx = insertStoreFor(mi, ss, newVReg, trc); - unsigned start = lis->getDefIndex(lis->getInstructionIndex(mi)), - end = lis->getUseIndex(storeInstIdx); - - VNInfo *vni = - newLI->getNextValue(storeInstIdx, 0, true, lis->getVNInfoAllocator()); - vni->kills.push_back(storeInstIdx); - LiveRange lr(start, end, vni); - - newLI->addRange(lr); + insertStoreOnInterval(newLI, mi, ss, newVReg, trc); } added.push_back(newLI); @@ -227,13 +247,44 @@ protected: /// folding. class TrivialSpiller : public SpillerBase { public: - TrivialSpiller(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls, VirtRegMap *vrm) : + + TrivialSpiller(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls, + VirtRegMap *vrm) : SpillerBase(mf, lis, ls, vrm) {} std::vector<LiveInterval*> spill(LiveInterval *li) { return trivialSpillEverywhere(li); } + std::vector<LiveInterval*> intraBlockSplit(LiveInterval *li, VNInfo *valno) { + std::vector<LiveInterval*> spillIntervals; + MachineBasicBlock::iterator storeInsertPoint; + + 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))); + } 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; + } + } + + + + return spillIntervals; + } + }; } |