misched prep: Cleanup ScheduleDAGInstrs interface.

ScheduleDAGInstrs will be the main interface for MI-level
schedulers. Make sure it's readable: one page of protected fields, one
page of public methids.

llvm-svn: 152258
This commit is contained in:
Andrew Trick 2012-03-07 23:00:57 +00:00
parent 67561b3ef2
commit 926d4736ed
2 changed files with 81 additions and 75 deletions

View File

@ -137,13 +137,13 @@ void ScheduleDAGInstrs::finishBlock() {
}
/// Initialize the map with the number of registers.
void ScheduleDAGInstrs::Reg2SUnitsMap::setRegLimit(unsigned Limit) {
void Reg2SUnitsMap::setRegLimit(unsigned Limit) {
PhysRegSet.setUniverse(Limit);
SUnits.resize(Limit);
}
/// Clear the map without deallocating storage.
void ScheduleDAGInstrs::Reg2SUnitsMap::clear() {
void Reg2SUnitsMap::clear() {
for (const_iterator I = reg_begin(), E = reg_end(); I != E; ++I) {
SUnits[*I].clear();
}

View File

@ -98,6 +98,70 @@ namespace llvm {
}
};
/// An individual mapping from virtual register number to SUnit.
struct VReg2SUnit {
unsigned VirtReg;
SUnit *SU;
VReg2SUnit(unsigned reg, SUnit *su): VirtReg(reg), SU(su) {}
unsigned getSparseSetKey() const {
return TargetRegisterInfo::virtReg2Index(VirtReg);
}
};
/// Combine a SparseSet with a 1x1 vector to track physical registers.
/// The SparseSet allows iterating over the (few) live registers for quickly
/// comparing against a regmask or clearing the set.
///
/// Storage for the map is allocated once for the pass. The map can be
/// cleared between scheduling regions without freeing unused entries.
class Reg2SUnitsMap {
SparseSet<unsigned> PhysRegSet;
std::vector<std::vector<SUnit*> > SUnits;
public:
typedef SparseSet<unsigned>::const_iterator const_iterator;
// Allow iteration over register numbers (keys) in the map. If needed, we
// can provide an iterator over SUnits (values) as well.
const_iterator reg_begin() const { return PhysRegSet.begin(); }
const_iterator reg_end() const { return PhysRegSet.end(); }
/// Initialize the map with the number of registers.
/// If the map is already large enough, no allocation occurs.
/// For simplicity we expect the map to be empty().
void setRegLimit(unsigned Limit);
/// Returns true if the map is empty.
bool empty() const { return PhysRegSet.empty(); }
/// Clear the map without deallocating storage.
void clear();
bool contains(unsigned Reg) const { return PhysRegSet.count(Reg); }
/// If this register is mapped, return its existing SUnits vector.
/// Otherwise map the register and return an empty SUnits vector.
std::vector<SUnit *> &operator[](unsigned Reg) {
bool New = PhysRegSet.insert(Reg).second;
assert((!New || SUnits[Reg].empty()) && "stale SUnits vector");
(void)New;
return SUnits[Reg];
}
/// Erase an existing element without freeing memory.
void erase(unsigned Reg) {
PhysRegSet.erase(Reg);
SUnits[Reg].clear();
}
};
/// Use SparseSet as a SparseMap by relying on the fact that it never
/// compares ValueT's, only unsigned keys. This allows the set to be cleared
/// between scheduling regions in constant time as long as ValueT does not
/// require a destructor.
typedef SparseSet<VReg2SUnit> VReg2SUnitMap;
/// ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of
/// MachineInstrs.
class LLVM_LIBRARY_VISIBILITY ScheduleDAGInstrs : public ScheduleDAG {
@ -136,51 +200,6 @@ namespace llvm {
/// the def-side latency only.
bool UnitLatencies;
/// Combine a SparseSet with a 1x1 vector to track physical registers.
/// The SparseSet allows iterating over the (few) live registers for quickly
/// comparing against a regmask or clearing the set.
///
/// Storage for the map is allocated once for the pass. The map can be
/// cleared between scheduling regions without freeing unused entries.
class Reg2SUnitsMap {
SparseSet<unsigned> PhysRegSet;
std::vector<std::vector<SUnit*> > SUnits;
public:
typedef SparseSet<unsigned>::const_iterator const_iterator;
// Allow iteration over register numbers (keys) in the map. If needed, we
// can provide an iterator over SUnits (values) as well.
const_iterator reg_begin() const { return PhysRegSet.begin(); }
const_iterator reg_end() const { return PhysRegSet.end(); }
/// Initialize the map with the number of registers.
/// If the map is already large enough, no allocation occurs.
/// For simplicity we expect the map to be empty().
void setRegLimit(unsigned Limit);
/// Returns true if the map is empty.
bool empty() const { return PhysRegSet.empty(); }
/// Clear the map without deallocating storage.
void clear();
bool contains(unsigned Reg) const { return PhysRegSet.count(Reg); }
/// If this register is mapped, return its existing SUnits vector.
/// Otherwise map the register and return an empty SUnits vector.
std::vector<SUnit *> &operator[](unsigned Reg) {
bool New = PhysRegSet.insert(Reg).second;
assert((!New || SUnits[Reg].empty()) && "stale SUnits vector");
(void)New;
return SUnits[Reg];
}
/// Erase an existing element without freeing memory.
void erase(unsigned Reg) {
PhysRegSet.erase(Reg);
SUnits[Reg].clear();
}
};
/// Defs, Uses - Remember where defs and uses of each register are as we
/// iterate upward through the instructions. This is allocated here instead
/// of inside BuildSchedGraph to avoid the need for it to be initialized and
@ -188,22 +207,6 @@ namespace llvm {
Reg2SUnitsMap Defs;
Reg2SUnitsMap Uses;
/// An individual mapping from virtual register number to SUnit.
struct VReg2SUnit {
unsigned VirtReg;
SUnit *SU;
VReg2SUnit(unsigned reg, SUnit *su): VirtReg(reg), SU(su) {}
unsigned getSparseSetKey() const {
return TargetRegisterInfo::virtReg2Index(VirtReg);
}
};
/// Use SparseSet as a SparseMap by relying on the fact that it never
/// compares ValueT's, only unsigned keys. This allows the set to be cleared
/// between scheduling regions in constant time as long as ValueT does not
/// require a destructor.
typedef SparseSet<VReg2SUnit> VReg2SUnitMap;
/// Track the last instructon in this region defining each virtual register.
VReg2SUnitMap VRegDefs;
@ -238,17 +241,7 @@ namespace llvm {
MachineBasicBlock::iterator end() const { return End; }
/// NewSUnit - Creates a new SUnit and return a ptr to it.
///
SUnit *newSUnit(MachineInstr *MI) {
#ifndef NDEBUG
const SUnit *Addr = SUnits.empty() ? 0 : &SUnits[0];
#endif
SUnits.push_back(SUnit(MI, (unsigned)SUnits.size()));
assert((Addr == 0 || Addr == &SUnits[0]) &&
"SUnits std::vector reallocated on the fly!");
SUnits.back().OrigNode = &SUnits.back();
return &SUnits.back();
}
SUnit *newSUnit(MachineInstr *MI);
/// startBlock - Prepare to perform scheduling in the given block.
///
@ -323,6 +316,19 @@ namespace llvm {
return VRegDefs.find(TargetRegisterInfo::virtReg2Index(VirtReg));
}
};
}
/// NewSUnit - Creates a new SUnit and return a ptr to it.
///
inline SUnit *ScheduleDAGInstrs::newSUnit(MachineInstr *MI) {
#ifndef NDEBUG
const SUnit *Addr = SUnits.empty() ? 0 : &SUnits[0];
#endif
SUnits.push_back(SUnit(MI, (unsigned)SUnits.size()));
assert((Addr == 0 || Addr == &SUnits[0]) &&
"SUnits std::vector reallocated on the fly!");
SUnits.back().OrigNode = &SUnits.back();
return &SUnits.back();
}
} // namespace llvm
#endif