Handle multiple virtual register definitions gracefully.
Move some of the longer LiveIntervals::Interval method out of the header and add debug information to them. Fix bug and simplify range merging code. llvm-svn: 10509
This commit is contained in:
parent
b3fdf83d17
commit
40874c708f
|
@ -59,55 +59,12 @@ namespace llvm {
|
||||||
return end() <= index;
|
return end() <= index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool overlaps(unsigned index) const {
|
void addRange(unsigned start, unsigned end);
|
||||||
for (Ranges::const_iterator
|
|
||||||
i = ranges.begin(), e = ranges.end(); i != e; ++i) {
|
|
||||||
if (index >= i->first && index < i->second) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addRange(unsigned start, unsigned end) {
|
|
||||||
Range range = std::make_pair(start, end);
|
|
||||||
Ranges::iterator it =
|
|
||||||
std::lower_bound(ranges.begin(), ranges.end(), range);
|
|
||||||
|
|
||||||
if (it == ranges.end()) {
|
|
||||||
it = ranges.insert(it, range);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(range.first <= it->first && "got wrong iterator?");
|
|
||||||
// merge ranges if necesary
|
|
||||||
if (range.first < it->first) {
|
|
||||||
if (range.second >= it->first) {
|
|
||||||
it->first = range.first;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
it = ranges.insert(it, range);
|
|
||||||
assert(it != ranges.end() && "wtf?");
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
mergeRangesIfNecessary(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void mergeRangesIfNecessary(Ranges::iterator it) {
|
void mergeRangesForward(Ranges::iterator it);
|
||||||
while (it != ranges.begin()) {
|
|
||||||
Ranges::iterator prev = it - 1;
|
void mergeRangesBackward(Ranges::iterator it);
|
||||||
if (prev->second < it->first) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
prev->second = it->second;
|
|
||||||
ranges.erase(it);
|
|
||||||
it = prev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StartPointComp {
|
struct StartPointComp {
|
||||||
|
|
|
@ -122,60 +122,46 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
|
||||||
|
|
||||||
LiveVariables::VarInfo& vi = lv_->getVarInfo(reg);
|
LiveVariables::VarInfo& vi = lv_->getVarInfo(reg);
|
||||||
|
|
||||||
|
Interval* interval = 0;
|
||||||
Reg2IntervalMap::iterator r2iit = r2iMap_.find(reg);
|
Reg2IntervalMap::iterator r2iit = r2iMap_.find(reg);
|
||||||
// handle multiple definition case (machine instructions violating
|
if (r2iit == r2iMap_.end()) {
|
||||||
// ssa after phi-elimination
|
|
||||||
if (r2iit != r2iMap_.end()) {
|
|
||||||
unsigned ii = r2iit->second;
|
|
||||||
Interval& interval = intervals_[ii];
|
|
||||||
unsigned end = getInstructionIndex(mbb->back()) + 1;
|
|
||||||
DEBUG(std::cerr << "\t\t\t\tadding range: ["
|
|
||||||
<< instrIndex << ',' << end << "]\n");
|
|
||||||
interval.addRange(instrIndex, end);
|
|
||||||
DEBUG(std::cerr << "\t\t\t\t" << interval << '\n');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// add new interval
|
// add new interval
|
||||||
intervals_.push_back(Interval(reg));
|
intervals_.push_back(Interval(reg));
|
||||||
Interval& interval = intervals_.back();
|
|
||||||
// update interval index for this register
|
// update interval index for this register
|
||||||
r2iMap_[reg] = intervals_.size() - 1;
|
r2iMap_[reg] = intervals_.size() - 1;
|
||||||
|
interval = &intervals_.back();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
interval = &intervals_[r2iit->second];
|
||||||
|
}
|
||||||
|
|
||||||
for (MbbIndex2MbbMap::iterator
|
for (MbbIndex2MbbMap::iterator
|
||||||
it = mbbi2mbbMap_.begin(), itEnd = mbbi2mbbMap_.end();
|
it = mbbi2mbbMap_.begin(), itEnd = mbbi2mbbMap_.end();
|
||||||
it != itEnd; ++it) {
|
it != itEnd; ++it) {
|
||||||
unsigned liveBlockIndex = it->first;
|
unsigned liveBlockIndex = it->first;
|
||||||
MachineBasicBlock* liveBlock = it->second;
|
MachineBasicBlock* liveBlock = it->second;
|
||||||
if (liveBlockIndex < vi.AliveBlocks.size() &&
|
if (liveBlockIndex < vi.AliveBlocks.size() &&
|
||||||
vi.AliveBlocks[liveBlockIndex]) {
|
vi.AliveBlocks[liveBlockIndex]) {
|
||||||
unsigned start = getInstructionIndex(liveBlock->front());
|
unsigned start = getInstructionIndex(liveBlock->front());
|
||||||
unsigned end = getInstructionIndex(liveBlock->back()) + 1;
|
unsigned end = getInstructionIndex(liveBlock->back()) + 1;
|
||||||
DEBUG(std::cerr << "\t\t\t\tadding range: ["
|
interval->addRange(start, end);
|
||||||
<< start << ',' << end << "]\n");
|
|
||||||
interval.addRange(start, end);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool killedInDefiningBasicBlock = false;
|
bool killedInDefiningBasicBlock = false;
|
||||||
for (int i = 0, e = vi.Kills.size(); i != e; ++i) {
|
for (int i = 0, e = vi.Kills.size(); i != e; ++i) {
|
||||||
MachineBasicBlock* killerBlock = vi.Kills[i].first;
|
MachineBasicBlock* killerBlock = vi.Kills[i].first;
|
||||||
MachineInstr* killerInstr = vi.Kills[i].second;
|
MachineInstr* killerInstr = vi.Kills[i].second;
|
||||||
killedInDefiningBasicBlock |= mbb == killerBlock;
|
killedInDefiningBasicBlock |= mbb == killerBlock;
|
||||||
unsigned start = (mbb == killerBlock ?
|
unsigned start = (mbb == killerBlock ?
|
||||||
instrIndex :
|
instrIndex :
|
||||||
getInstructionIndex(killerBlock->front()));
|
getInstructionIndex(killerBlock->front()));
|
||||||
unsigned end = getInstructionIndex(killerInstr) + 1;
|
unsigned end = getInstructionIndex(killerInstr) + 1;
|
||||||
DEBUG(std::cerr << "\t\t\t\tadding range: ["
|
}
|
||||||
<< start << ',' << end << "]\n");
|
|
||||||
interval.addRange(start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!killedInDefiningBasicBlock) {
|
if (!killedInDefiningBasicBlock) {
|
||||||
unsigned end = getInstructionIndex(mbb->back()) + 1;
|
unsigned end = getInstructionIndex(mbb->back()) + 1;
|
||||||
interval.addRange(instrIndex, end);
|
interval->addRange(instrIndex, end);
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG(std::cerr << "\t\t\t\t" << interval << '\n');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,20 +206,14 @@ exit:
|
||||||
if (r2iit != r2iMap_.end()) {
|
if (r2iit != r2iMap_.end()) {
|
||||||
unsigned ii = r2iit->second;
|
unsigned ii = r2iit->second;
|
||||||
Interval& interval = intervals_[ii];
|
Interval& interval = intervals_[ii];
|
||||||
DEBUG(std::cerr << "\t\t\t\tadding range: ["
|
|
||||||
<< start << ',' << end << "]\n");
|
|
||||||
interval.addRange(start, end);
|
interval.addRange(start, end);
|
||||||
DEBUG(std::cerr << "\t\t\t\t" << interval << '\n');
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
intervals_.push_back(Interval(reg));
|
intervals_.push_back(Interval(reg));
|
||||||
Interval& interval = intervals_.back();
|
Interval& interval = intervals_.back();
|
||||||
// update interval index for this register
|
// update interval index for this register
|
||||||
r2iMap_[reg] = intervals_.size() - 1;
|
r2iMap_[reg] = intervals_.size() - 1;
|
||||||
DEBUG(std::cerr << "\t\t\t\tadding range: ["
|
|
||||||
<< start << ',' << end << "]\n");
|
|
||||||
interval.addRange(start, end);
|
interval.addRange(start, end);
|
||||||
DEBUG(std::cerr << "\t\t\t\t" << interval << '\n');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,6 +290,42 @@ void LiveIntervals::computeIntervals()
|
||||||
std::ostream_iterator<Interval>(std::cerr, "\n")));
|
std::ostream_iterator<Interval>(std::cerr, "\n")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LiveIntervals::Interval::addRange(unsigned start, unsigned end)
|
||||||
|
{
|
||||||
|
DEBUG(std::cerr << "\t\t\t\tadding range: [" << start <<','<< end << "]\n");
|
||||||
|
//assert(start < end && "invalid range?");
|
||||||
|
Range range = std::make_pair(start, end);
|
||||||
|
Ranges::iterator it =
|
||||||
|
ranges.insert(std::upper_bound(ranges.begin(), ranges.end(), range),
|
||||||
|
range);
|
||||||
|
|
||||||
|
DEBUG(std::cerr << "\t\t\t\tbefore merge forward: " << *this << '\n');
|
||||||
|
mergeRangesForward(it);
|
||||||
|
DEBUG(std::cerr << "\t\t\t\tbefore merge backward: " << *this << '\n');
|
||||||
|
mergeRangesBackward(it);
|
||||||
|
DEBUG(std::cerr << "\t\t\t\tafter merging: " << *this << '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
void LiveIntervals::Interval::mergeRangesForward(Ranges::iterator it)
|
||||||
|
{
|
||||||
|
for (Ranges::iterator next = it + 1;
|
||||||
|
next != ranges.end() && it->second >= next->first; ) {
|
||||||
|
it->second = std::max(it->second, next->second);
|
||||||
|
next = ranges.erase(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LiveIntervals::Interval::mergeRangesBackward(Ranges::iterator it)
|
||||||
|
{
|
||||||
|
for (Ranges::iterator prev = it - 1;
|
||||||
|
it != ranges.begin() && it->first <= prev->second; ) {
|
||||||
|
it->first = std::min(it->first, prev->first);
|
||||||
|
it->second = std::max(it->second, prev->second);
|
||||||
|
it = ranges.erase(prev);
|
||||||
|
prev = it - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& llvm::operator<<(std::ostream& os,
|
std::ostream& llvm::operator<<(std::ostream& os,
|
||||||
const LiveIntervals::Interval& li)
|
const LiveIntervals::Interval& li)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue