From 6097d13b2a624048dbe02e39e2dfb23bfa269b64 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 19 Jul 2004 02:15:56 +0000 Subject: [PATCH] remove the mbbi2mbbMap_, which was just keeping track of mbb order anyway. Heavily refactor handleVirtualRegisterDef, adding comments and making it more efficient. It is also much easier to follow and convince ones self that it is correct :) Add -debug output to the joine, showing the result of joining the intervals. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14989 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveIntervalAnalysis.cpp | 129 +++++++++++++++------------ 1 file changed, 74 insertions(+), 55 deletions(-) diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index e0ea6d95be1..5e9e495edcc 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -60,6 +60,7 @@ namespace { EnableJoining("join-liveintervals", cl::desc("Join compatible live intervals"), cl::init(true)); + cl::opt EnableVirtVirtJoining("join-liveintervals-virtvirtjoining", cl::desc("Join live intervals for virtreg pairs (buggy)"), @@ -79,7 +80,6 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const void LiveIntervals::releaseMemory() { - mbbi2mbbMap_.clear(); mi2iMap_.clear(); i2miMap_.clear(); r2iMap_.clear(); @@ -99,20 +99,14 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) { // number MachineInstrs unsigned miIndex = 0; for (MachineFunction::iterator mbb = mf_->begin(), mbbEnd = mf_->end(); - mbb != mbbEnd; ++mbb) { - unsigned mbbIdx = mbb->getNumber(); - bool inserted = mbbi2mbbMap_.insert(std::make_pair(mbbIdx, - mbb)).second; - assert(inserted && "multiple index -> MachineBasicBlock"); - + mbb != mbbEnd; ++mbb) for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end(); mi != miEnd; ++mi) { - inserted = mi2iMap_.insert(std::make_pair(mi, miIndex)).second; + bool inserted = mi2iMap_.insert(std::make_pair(mi, miIndex)).second; assert(inserted && "multiple MachineInstr -> index mappings"); i2miMap_.push_back(mi); miIndex += InstrSlots::NUM; } - } computeIntervals(); @@ -120,6 +114,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) { // join intervals if requested if (EnableJoining) joinIntervals(); + //DEBUG(mf_->viewCFG()); numIntervalsAfter += intervals_.size(); @@ -290,50 +285,74 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb, DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg)); LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg); - // Iterate over all of the blocks that the variable is completely - // live in, adding [insrtIndex(begin), instrIndex(end)+4) to the - // live interval. Obviously we only need to do this once. + // Virtual registers may be defined multiple times (due to phi + // elimination). Much of what we do only has to be done once for the vreg. + // We use an empty interval to detect the first time we see a vreg. if (interval.empty()) { - for (unsigned i = 0, e = vi.AliveBlocks.size(); i != e; ++i) { - if (vi.AliveBlocks[i]) { - MachineBasicBlock* mbb = mf_->getBlockNumbered(i); - if (!mbb->empty()) { - interval.addRange( - getInstructionIndex(&mbb->front()), - getInstructionIndex(&mbb->back()) + InstrSlots::NUM); - } - } - } + + // Get the Idx of the defining instructions. + unsigned defIndex = getDefIndex(getInstructionIndex(mi)); + + // Loop over all of the blocks that the vreg is defined in. There are + // two cases we have to handle here. The most common case is a vreg + // whose lifetime is contained within a basic block. In this case there + // will be a single kill, in MBB, which comes after the definition. + if (vi.Kills.size() == 1 && vi.Kills[0].first == mbb) { + // FIXME: what about dead vars? + unsigned killIdx; + if (vi.Kills[0].second != mi) + killIdx = getUseIndex(getInstructionIndex(vi.Kills[0].second))+1; + else + killIdx = defIndex+1; + + // If the kill happens after the definition, we have an intra-block + // live range. + if (killIdx > defIndex) { + assert(vi.AliveBlocks.empty() && + "Shouldn't be alive across any blocks!"); + interval.addRange(defIndex, killIdx); + return; + } + } + + // The other case we handle is when a virtual register lives to the end + // of the defining block, potentially live across some blocks, then is + // live into some number of blocks, but gets killed. Start by adding a + // range that goes from this definition to the end of the defining block. + interval.addRange(defIndex, + getInstructionIndex(&mbb->back()) + InstrSlots::NUM); + + // Iterate over all of the blocks that the variable is completely + // live in, adding [insrtIndex(begin), instrIndex(end)+4) to the + // live interval. + for (unsigned i = 0, e = vi.AliveBlocks.size(); i != e; ++i) { + if (vi.AliveBlocks[i]) { + MachineBasicBlock* mbb = mf_->getBlockNumbered(i); + if (!mbb->empty()) { + interval.addRange( + getInstructionIndex(&mbb->front()), + getInstructionIndex(&mbb->back()) + InstrSlots::NUM); + } + } + } + + // Finally, this virtual register is live from the start of any killing + // block to the 'use' slot of the killing instruction. + for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) { + std::pair &Kill = vi.Kills[i]; + interval.addRange(getInstructionIndex(Kill.first->begin()), + getUseIndex(getInstructionIndex(Kill.second))+1); + } + + } else { + // If this is the second time we see a virtual register definition, it + // must be due to phi elimination. In this case, the defined value will + // be live until the end of the basic block it is defined in. + unsigned defIndex = getDefIndex(getInstructionIndex(mi)); + interval.addRange(defIndex, + getInstructionIndex(&mbb->back()) + InstrSlots::NUM); } - unsigned baseIndex = getInstructionIndex(mi); - - bool killedInDefiningBasicBlock = false; - for (int i = 0, e = vi.Kills.size(); i != e; ++i) { - MachineBasicBlock* killerBlock = vi.Kills[i].first; - MachineInstr* killerInstr = vi.Kills[i].second; - unsigned start = (mbb == killerBlock ? - getDefIndex(baseIndex) : - getInstructionIndex(&killerBlock->front())); - unsigned end = (killerInstr == mi ? - // dead - start + 1 : - // killed - getUseIndex(getInstructionIndex(killerInstr))+1); - // we do not want to add invalid ranges. these can happen when - // a variable has its latest use and is redefined later on in - // the same basic block (common with variables introduced by - // PHI elimination) - if (start < end) { - killedInDefiningBasicBlock |= mbb == killerBlock; - interval.addRange(start, end); - } - } - - if (!killedInDefiningBasicBlock) { - unsigned end = getInstructionIndex(&mbb->back()) + InstrSlots::NUM; - interval.addRange(getDefIndex(baseIndex), end); - } DEBUG(std::cerr << '\n'); } @@ -426,10 +445,9 @@ void LiveIntervals::computeIntervals() DEBUG(std::cerr << "********** Function: " << ((Value*)mf_->getFunction())->getName() << '\n'); - for (MbbIndex2MbbMap::iterator - it = mbbi2mbbMap_.begin(), itEnd = mbbi2mbbMap_.end(); - it != itEnd; ++it) { - MachineBasicBlock* mbb = it->second; + for (MachineFunction::iterator I = mf_->begin(), E = mf_->end(); + I != E; ++I) { + MachineBasicBlock* mbb = I; DEBUG(std::cerr << ((Value*)mbb->getBasicBlock())->getName() << ":\n"); for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end(); @@ -688,7 +706,7 @@ void LiveInterval::addRange(unsigned start, unsigned end) void LiveInterval::join(const LiveInterval& other) { - DEBUG(std::cerr << "\t\tjoining " << *this << " with " << other << '\n'); + DEBUG(std::cerr << "\t\tjoining " << *this << " with " << other); Ranges::iterator cur = ranges.begin(); for (Ranges::const_iterator i = other.ranges.begin(), @@ -699,6 +717,7 @@ void LiveInterval::join(const LiveInterval& other) } weight += other.weight; ++numJoins; + DEBUG(std::cerr << ". Result = " << *this << "\n"); } LiveInterval::Ranges::iterator LiveInterval::