Reverting r118604. Windows build broke.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118613 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Trick 2010-11-09 19:47:51 +00:00
parent 467a0adfc8
commit 32d9aeb1df
4 changed files with 14 additions and 165 deletions

View File

@ -15,7 +15,6 @@
#define DEBUG_TYPE "regalloc" #define DEBUG_TYPE "regalloc"
#include "LiveIntervalUnion.h" #include "LiveIntervalUnion.h"
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include <algorithm> #include <algorithm>
@ -74,9 +73,12 @@ void LiveIntervalUnion::unify(LiveInterval &lvr) {
#ifndef NDEBUG #ifndef NDEBUG
// check for overlap (inductively) // check for overlap (inductively)
if (segPos != segments_.begin()) { if (segPos != segments_.begin()) {
assert(prior(segPos)->end <= segment.start && "overlapping segments" ); SegmentIter prevPos = segPos;
--prevPos;
assert(prevPos->end <= segment.start && "overlapping segments" );
} }
SegmentIter nextPos = next(segPos); SegmentIter nextPos = segPos;
++nextPos;
if (nextPos != segments_.end()) if (nextPos != segments_.end())
assert(segment.end <= nextPos->start && "overlapping segments" ); assert(segment.end <= nextPos->start && "overlapping segments" );
#endif // NDEBUG #endif // NDEBUG
@ -96,49 +98,6 @@ void LiveIntervalUnion::extract(const LiveInterval &lvr) {
} }
} }
raw_ostream& llvm::operator<<(raw_ostream& os, const LiveSegment &ls) {
return os << '[' << ls.start << ',' << ls.end << ':' <<
ls.liveVirtReg->reg << ")";
}
void LiveSegment::dump() const {
dbgs() << *this << "\n";
}
void
LiveIntervalUnion::print(raw_ostream &os,
const AbstractRegisterDescription *rdesc) const {
os << "LIU ";
if (rdesc != NULL)
os << rdesc->getName(repReg_);
else {
os << repReg_;
}
for (SegmentIter segI = segments_.begin(), segEnd = segments_.end();
segI != segEnd; ++segI) {
dbgs() << " " << *segI;
}
os << "\n";
}
void LiveIntervalUnion::dump(const AbstractRegisterDescription *rdesc) const {
print(dbgs(), rdesc);
}
#ifndef NDEBUG
// Verify the live intervals in this union and add them to the visited set.
void LiveIntervalUnion::verify(LvrBitSet& visitedVRegs) {
SegmentIter segI = segments_.begin();
SegmentIter segEnd = segments_.end();
if (segI == segEnd) return;
visitedVRegs.set(segI->liveVirtReg->reg);
for (++segI; segI != segEnd; ++segI) {
visitedVRegs.set(segI->liveVirtReg->reg);
assert(prior(segI)->end <= segI->start && "overlapping segments" );
}
}
#endif //!NDEBUG
// Private interface accessed by Query. // Private interface accessed by Query.
// //
// Find a pair of segments that intersect, one in the live virtual register // Find a pair of segments that intersect, one in the live virtual register

View File

@ -23,12 +23,6 @@
namespace llvm { namespace llvm {
#ifndef NDEBUG
// forward declaration
template <unsigned Element> class SparseBitVector;
typedef SparseBitVector<128> LvrBitSet;
#endif
/// A LiveSegment is a copy of a LiveRange object used within /// A LiveSegment is a copy of a LiveRange object used within
/// LiveIntervalUnion. LiveSegment additionally contains a pointer to its /// LiveIntervalUnion. LiveSegment additionally contains a pointer to its
/// original live virtual register (LiveInterval). This allows quick lookup of /// original live virtual register (LiveInterval). This allows quick lookup of
@ -57,9 +51,6 @@ struct LiveSegment {
// Order segments by starting point only--we expect them to be disjoint. // Order segments by starting point only--we expect them to be disjoint.
bool operator<(const LiveSegment &ls) const { return start < ls.start; } bool operator<(const LiveSegment &ls) const { return start < ls.start; }
void dump() const;
void print(raw_ostream &os) const;
}; };
inline bool operator<(SlotIndex V, const LiveSegment &ls) { inline bool operator<(SlotIndex V, const LiveSegment &ls) {
@ -75,16 +66,6 @@ inline bool overlap(const LiveRange &lvrSeg, const LiveSegment &liuSeg) {
return lvrSeg.start < liuSeg.end && liuSeg.start < lvrSeg.end; return lvrSeg.start < liuSeg.end && liuSeg.start < lvrSeg.end;
} }
template <> struct isPodLike<LiveSegment> { static const bool value = true; };
raw_ostream& operator<<(raw_ostream& os, const LiveSegment &ls);
/// Abstraction to provide info for the representative register.
class AbstractRegisterDescription {
public:
virtual const char *getName(unsigned reg) const = 0;
};
/// Union of live intervals that are strong candidates for coalescing into a /// Union of live intervals that are strong candidates for coalescing into a
/// single register (either physical or virtual depending on the context). We /// single register (either physical or virtual depending on the context). We
/// expect the constituent live intervals to be disjoint, although we may /// expect the constituent live intervals to be disjoint, although we may
@ -141,16 +122,6 @@ public:
// Remove a live virtual register's segments from this union. // Remove a live virtual register's segments from this union.
void extract(const LiveInterval &lvr); void extract(const LiveInterval &lvr);
void dump(const AbstractRegisterDescription *regInfo) const;
// If tri != NULL, use it to decode repReg_
void print(raw_ostream &os, const AbstractRegisterDescription *rdesc) const;
#ifndef NDEBUG
// Verify the live intervals in this union and add them to the visited set.
void verify(LvrBitSet& visitedVRegs);
#endif
/// Cache a single interference test result in the form of two intersecting /// Cache a single interference test result in the form of two intersecting
/// segments. This allows efficiently iterating over the interferences. The /// segments. This allows efficiently iterating over the interferences. The
/// iteration logic is handled by LiveIntervalUnion::Query which may /// iteration logic is handled by LiveIntervalUnion::Query which may

View File

@ -128,11 +128,6 @@ protected:
// exists, return the interfering register, which may be preg or an alias. // exists, return the interfering register, which may be preg or an alias.
unsigned checkPhysRegInterference(LiveInterval& lvr, unsigned preg); unsigned checkPhysRegInterference(LiveInterval& lvr, unsigned preg);
#ifndef NDEBUG
// Verify each LiveIntervalUnion.
void verify();
#endif
// Helper that spills all live virtual registers currently unified under preg // Helper that spills all live virtual registers currently unified under preg
// that interfere with the most recently queried lvr. // that interfere with the most recently queried lvr.
void spillInterferences(unsigned preg, void spillInterferences(unsigned preg,

View File

@ -34,9 +34,6 @@
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetRegisterInfo.h"
#ifndef NDEBUG
#include "llvm/ADT/SparseBitVector.h"
#endif
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
@ -49,19 +46,6 @@ using namespace llvm;
static RegisterRegAlloc basicRegAlloc("basic", "basic register allocator", static RegisterRegAlloc basicRegAlloc("basic", "basic register allocator",
createBasicRegisterAllocator); createBasicRegisterAllocator);
// Temporary verification option until we can put verification inside
// MachineVerifier.
static cl::opt<bool>
VerifyRegAlloc("verify-regalloc",
cl::desc("Verify live intervals before renaming"));
class PhysicalRegisterDescription : public AbstractRegisterDescription {
const TargetRegisterInfo *tri_;
public:
PhysicalRegisterDescription(const TargetRegisterInfo *tri): tri_(tri) {}
virtual const char *getName(unsigned reg) const { return tri_->getName(reg); }
};
namespace { namespace {
/// RABasic provides a minimal implementation of the basic register allocation /// RABasic provides a minimal implementation of the basic register allocation
@ -169,40 +153,6 @@ void RABasic::releaseMemory() {
RegAllocBase::releaseMemory(); RegAllocBase::releaseMemory();
} }
#ifndef NDEBUG
// Verify each LiveIntervalUnion.
void RegAllocBase::verify() {
LvrBitSet visitedVRegs;
OwningArrayPtr<LvrBitSet> unionVRegs(new LvrBitSet[physReg2liu_.numRegs()]);
// Verify disjoint unions.
for (unsigned preg = 0; preg < physReg2liu_.numRegs(); ++preg) {
DEBUG(PhysicalRegisterDescription prd(tri_); physReg2liu_[preg].dump(&prd));
LvrBitSet &vregs = unionVRegs[preg];
physReg2liu_[preg].verify(vregs);
// Union + intersection test could be done efficiently in one pass, but
// don't add a method to SparseBitVector unless we really need it.
assert(!visitedVRegs.intersects(vregs) && "vreg in multiple unions");
visitedVRegs |= vregs;
}
// Verify vreg coverage.
for (LiveIntervals::iterator liItr = lis_->begin(), liEnd = lis_->end();
liItr != liEnd; ++liItr) {
unsigned reg = liItr->first;
LiveInterval &li = *liItr->second;
if (li.empty() ) continue;
if (TargetRegisterInfo::isPhysicalRegister(reg)) continue;
if (!vrm_->hasPhys(reg)) continue; // spilled?
unsigned preg = vrm_->getPhys(reg);
if (!unionVRegs[preg].test(reg)) {
dbgs() << "LiveVirtReg " << reg << " not in union " <<
tri_->getName(preg) << "\n";
llvm_unreachable("unallocated live vreg");
}
}
// FIXME: I'm not sure how to verify spilled intervals.
}
#endif //!NDEBUG
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// RegAllocBase Implementation // RegAllocBase Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -272,7 +222,6 @@ void RegAllocBase::seedLiveVirtRegs(LiveVirtRegQueue &lvrQ) {
liItr != liEnd; ++liItr) { liItr != liEnd; ++liItr) {
unsigned reg = liItr->first; unsigned reg = liItr->first;
LiveInterval &li = *liItr->second; LiveInterval &li = *liItr->second;
if (li.empty()) continue;
if (TargetRegisterInfo::isPhysicalRegister(reg)) { if (TargetRegisterInfo::isPhysicalRegister(reg)) {
physReg2liu_[reg].unify(li); physReg2liu_[reg].unify(li);
} }
@ -294,14 +243,13 @@ void RegAllocBase::allocatePhysRegs() {
unsigned availablePhysReg = selectOrSplit(*lvr, splitLVRs); unsigned availablePhysReg = selectOrSplit(*lvr, splitLVRs);
if (availablePhysReg) { if (availablePhysReg) {
DEBUG(dbgs() << "allocating: " << tri_->getName(availablePhysReg) << DEBUG(dbgs() << "allocating: " << tri_->getName(availablePhysReg) <<
" " << *lvr << '\n'); " " << lvr << '\n');
assert(!vrm_->hasPhys(lvr->reg) && "duplicate vreg in interval unions"); assert(!vrm_->hasPhys(lvr->reg) && "duplicate vreg in interval unions");
vrm_->assignVirt2Phys(lvr->reg, availablePhysReg); vrm_->assignVirt2Phys(lvr->reg, availablePhysReg);
physReg2liu_[availablePhysReg].unify(*lvr); physReg2liu_[availablePhysReg].unify(*lvr);
} }
for (LVRVec::iterator lvrI = splitLVRs.begin(), lvrEnd = splitLVRs.end(); for (LVRVec::iterator lvrI = splitLVRs.begin(), lvrEnd = splitLVRs.end();
lvrI != lvrEnd; ++lvrI) { lvrI != lvrEnd; ++lvrI) {
if ((*lvrI)->empty()) continue;
DEBUG(dbgs() << "queuing new interval: " << **lvrI << "\n"); DEBUG(dbgs() << "queuing new interval: " << **lvrI << "\n");
assert(TargetRegisterInfo::isVirtualRegister((*lvrI)->reg) && assert(TargetRegisterInfo::isVirtualRegister((*lvrI)->reg) &&
"expect split value in virtual register"); "expect split value in virtual register");
@ -326,32 +274,26 @@ unsigned RegAllocBase::checkPhysRegInterference(LiveInterval &lvr,
return 0; return 0;
} }
// Spill or split all live virtual registers currently unified under preg that // Spill all live virtual registers currently unified under preg that interfere
// interfere with lvr. The newly spilled or split live intervals are returned by // with lvr.
// appending them to splitLVRs.
void RABasic::spillInterferences(unsigned preg, void RABasic::spillInterferences(unsigned preg,
SmallVectorImpl<LiveInterval*> &splitLVRs) { SmallVectorImpl<LiveInterval*> &splitLVRs) {
SmallPtrSet<LiveInterval*, 8> spilledLVRs; SmallPtrSet<LiveInterval*, 8> spilledLVRs;
LiveIntervalUnion::Query &query = queries_[preg]; LiveIntervalUnion::Query &query = queries_[preg];
// Record each interference before mutating either the union or live
// intervals.
LiveIntervalUnion::InterferenceResult ir = query.firstInterference(); LiveIntervalUnion::InterferenceResult ir = query.firstInterference();
assert(query.isInterference(ir) && "expect interference"); assert(query.isInterference(ir) && "expect interference");
do { do {
spilledLVRs.insert(ir.liuSegPos()->liveVirtReg); LiveInterval *lvr = ir.liuSegPos()->liveVirtReg;
if (!spilledLVRs.insert(lvr)) continue;
// Spill the previously allocated lvr.
SmallVector<LiveInterval*, 1> spillIs; // ignored
spiller_->spill(lvr, splitLVRs, spillIs);
} while (query.nextInterference(ir)); } while (query.nextInterference(ir));
for (SmallPtrSetIterator<LiveInterval*> lvrI = spilledLVRs.begin(), for (SmallPtrSetIterator<LiveInterval*> lvrI = spilledLVRs.begin(),
lvrEnd = spilledLVRs.end(); lvrEnd = spilledLVRs.end();
lvrI != lvrEnd; ++lvrI ) { lvrI != lvrEnd; ++lvrI ) {
LiveInterval& lvr = **lvrI;
// Spill the previously allocated lvr.
DEBUG(dbgs() << "extracting from " << preg << " " << lvr << '\n');
// Deallocate the interfering lvr by removing it from the preg union. // Deallocate the interfering lvr by removing it from the preg union.
// Live intervals may not be in a union during modification. physReg2liu_[preg].extract(**lvrI);
physReg2liu_[preg].extract(lvr);
// Spill the extracted interval.
SmallVector<LiveInterval*, 8> spillIs;
spiller_->spill(&lvr, splitLVRs, spillIs);
} }
// After extracting segments, the query's results are invalid. // After extracting segments, the query's results are invalid.
query.clear(); query.clear();
@ -457,24 +399,6 @@ bool RABasic::runOnMachineFunction(MachineFunction &mf) {
// optional HTML output // optional HTML output
DEBUG(rmf_->renderMachineFunction("After basic register allocation.", vrm_)); DEBUG(rmf_->renderMachineFunction("After basic register allocation.", vrm_));
// FIXME: Verification currently must run before VirtRegRewriter. We should
// make the rewriter a separate pass and override verifyAnalysis instead. When
// that happens, verification naturally falls under VerifyMachineCode.
#ifndef NDEBUG
if (VerifyRegAlloc) {
// Verify accuracy of LiveIntervals. The standard machine code verifier
// ensures that each LiveIntervals covers all uses of the virtual reg.
// FIXME: MachineVerifier is currently broken when using the standard
// spiller. Enable it for InlineSpiller only.
// mf_->verify(this);
// Verify that LiveIntervals are partitioned into unions and disjoint within
// the unions.
verify();
}
#endif // !NDEBUG
// Run rewriter // Run rewriter
std::auto_ptr<VirtRegRewriter> rewriter(createVirtRegRewriter()); std::auto_ptr<VirtRegRewriter> rewriter(createVirtRegRewriter());
rewriter->runOnMachineFunction(*mf_, *vrm_, lis_); rewriter->runOnMachineFunction(*mf_, *vrm_, lis_);