From 1bade5ff0992b78f3154b6dc008a9c399cad0f28 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Fri, 19 Jun 2009 02:17:53 +0000 Subject: [PATCH] More VNInfo tweaking, plus a little progress on intra-block splitting. llvm-svn: 73750 --- include/llvm/CodeGen/LiveInterval.h | 16 ++--- lib/CodeGen/LiveIntervalAnalysis.cpp | 6 +- lib/CodeGen/Spiller.cpp | 95 +++++++++++++++++++++------- lib/CodeGen/Spiller.h | 8 ++- 4 files changed, 92 insertions(+), 33 deletions(-) diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index a52919d313d..0cb7e900438 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -40,14 +40,14 @@ namespace llvm { /// Care must be taken in interpreting the def index of the value. The /// following rules apply: /// - /// If the isDefAccurate() method returns false then the def index does not - /// actually point to the defining MachineInstr, or even (necessarily) a - /// valid MachineInstr at all. In general such a def index should not be - /// used as an index to obtain a MachineInstr. The exception is Values - /// defined by PHI instructions, after PHI elimination has occured. In this - /// case the def should point to the start of the block in which the PHI - /// existed. This fact can be used to insert code dealing with the PHI value - /// at the merge point (e.g. to spill or split it). + /// If the isDefAccurate() method returns false then def does not contain the + /// index of the defining MachineInstr, or even (necessarily) to a + /// MachineInstr at all. In general such a def index is not meaningful + /// and should not be used. The exception is that, for values originally + /// defined by PHI instructions, after PHI elimination def will contain the + /// index of the MBB in which the PHI originally existed. This can be used + /// to insert code (spills or copies) which deals with the value, which will + /// be live in to the block. class VNInfo { private: diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index d4169dbcf51..d6931df896d 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -584,7 +584,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, // Replace the interval with one of a NEW value number. Note that this // value number isn't actually defined by an instruction, weird huh? :) - LiveRange LR(Start, End, interval.getNextValue(Start, 0, false, VNInfoAllocator)); + LiveRange LR(Start, End, + interval.getNextValue(mbb->getNumber(), 0, false, VNInfoAllocator)); LR.valno->setIsPHIDef(true); DOUT << " replace range with " << LR; interval.addRange(LR); @@ -785,7 +786,8 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB, } } - VNInfo *vni = interval.getNextValue(start, 0, false, VNInfoAllocator); + VNInfo *vni = + interval.getNextValue(MBB->getNumber(), 0, false, VNInfoAllocator); vni->setIsPHIDef(true); LiveRange LR(start, end, vni); diff --git a/lib/CodeGen/Spiller.cpp b/lib/CodeGen/Spiller.cpp index 55642aa3f4c..919a0ce160f 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 spill(LiveInterval *li) { return trivialSpillEverywhere(li); } + std::vector intraBlockSplit(LiveInterval *li, VNInfo *valno) { + std::vector 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; + } + }; } diff --git a/lib/CodeGen/Spiller.h b/lib/CodeGen/Spiller.h index 86d7db23c7b..9c3900df0b5 100644 --- a/lib/CodeGen/Spiller.h +++ b/lib/CodeGen/Spiller.h @@ -13,12 +13,14 @@ #include namespace llvm { + class LiveInterval; class LiveIntervals; class LiveStacks; class MachineFunction; - class VirtRegMap; class MachineInstr; + class VirtRegMap; + class VNInfo; /// Spiller interface. /// @@ -32,6 +34,10 @@ namespace llvm { /// implementation selected. virtual std::vector spill(LiveInterval *li) = 0; + /// Intra-block split. + virtual std::vector intraBlockSplit(LiveInterval *li, + VNInfo *valno) = 0; + }; /// Create and return a spiller object, as specified on the command line.