/// CodeGenSubRegIndex - Represents a sub-register index.
class CodeGenSubRegIndex {
Record *const TheDef;
+ std::string Name;
+ std::string Namespace;
public:
const unsigned EnumValue;
+ unsigned LaneMask;
CodeGenSubRegIndex(Record *R, unsigned Enum);
+ CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum);
- const std::string &getName() const;
- std::string getNamespace() const;
+ const std::string &getName() const { return Name; }
+ const std::string &getNamespace() const { return Namespace; }
std::string getQualifiedName() const;
// Order CodeGenSubRegIndex pointers by EnumValue.
// Update the composite maps of components specified in 'ComposedOf'.
void updateComponents(CodeGenRegBank&);
- // Clean out redundant composite mappings.
- void cleanComposites();
-
// Return the map of composites.
const CompMap &getComposites() const { return Composed; }
+ // Compute LaneMask from Composed. Return LaneMask.
+ unsigned computeLaneMask();
+
private:
CompMap Composed;
};
return SuperRegs;
}
+ // Get the list of ad hoc aliases. The graph is symmetric, so the list
+ // contains all registers in 'Aliases', and all registers that mention this
+ // register in 'Aliases'.
+ ArrayRef<CodeGenRegister*> getExplicitAliases() const {
+ return ExplicitAliases;
+ }
+
// Get the topological signature of this register. This is a small integer
// less than RegBank.getNumTopoSigs(). Registers with the same TopoSig have
// identical sub-register structure. That is, they support the same set of
// List of register units in ascending order.
typedef SmallVector<unsigned, 16> RegUnitList;
+ // How many entries in RegUnitList are native?
+ unsigned NumNativeRegUnits;
+
// Get the list of register units.
- // This is only valid after getSubRegs() completes.
+ // This is only valid after computeSubRegs() completes.
const RegUnitList &getRegUnits() const { return RegUnits; }
+ // Get the native register units. This is a prefix of getRegUnits().
+ ArrayRef<unsigned> getNativeRegUnits() const {
+ return makeArrayRef(RegUnits).slice(0, NumNativeRegUnits);
+ }
+
// Inherit register units from subregisters.
// Return true if the RegUnits changed.
bool inheritRegUnits(CodeGenRegBank &RegBank);
// Adopt a register unit for pressure tracking.
- // A unit is adopted iff its unit number is >= NumNativeRegUnits.
+ // A unit is adopted if its unit number is >= NumNativeRegUnits.
void adoptRegUnit(unsigned RUID) { RegUnits.push_back(RUID); }
// Get the sum of this register's register unit weights.
// Canonically ordered set.
typedef std::set<const CodeGenRegister*, Less> Set;
+ // Compute the set of registers overlapping this.
+ void computeOverlaps(Set &Overlaps, const CodeGenRegBank&) const;
+
private:
bool SubRegsComplete;
bool SuperRegsComplete;
SmallVector<CodeGenSubRegIndex*, 8> ExplicitSubRegIndices;
SmallVector<CodeGenRegister*, 8> ExplicitSubRegs;
+ // Explicit ad hoc aliases, symmetrized to form an undirected graph.
+ SmallVector<CodeGenRegister*, 8> ExplicitAliases;
+
// Super-registers where this is the first explicit sub-register.
SuperRegList LeadingSuperRegs;
};
// Create a non-user defined register class.
- CodeGenRegisterClass(StringRef Name, Key Props);
+ CodeGenRegisterClass(CodeGenRegBank&, StringRef Name, Key Props);
// Called by CodeGenRegBank::CodeGenRegBank().
static void computeSubClasses(CodeGenRegBank&);
};
+ // Register units are used to model interference and register pressure.
+ // Every register is assigned one or more register units such that two
+ // registers overlap if and only if they have a register unit in common.
+ //
+ // Normally, one register unit is created per leaf register. Non-leaf
+ // registers inherit the units of their sub-registers.
+ struct RegUnit {
+ // Weight assigned to this RegUnit for estimating register pressure.
+ // This is useful when equalizing weights in register classes with mixed
+ // register topologies.
+ unsigned Weight;
+
+ // Each native RegUnit corresponds to one or two root registers. The full
+ // set of registers containing this unit can be computed as the union of
+ // these two registers and their super-registers.
+ const CodeGenRegister *Roots[2];
+
+ RegUnit() : Weight(0) { Roots[0] = Roots[1] = 0; }
+
+ ArrayRef<const CodeGenRegister*> getRoots() const {
+ assert(!(Roots[1] && !Roots[0]) && "Invalid roots array");
+ return makeArrayRef(Roots, !!Roots[0] + !!Roots[1]);
+ }
+ };
+
// Each RegUnitSet is a sorted vector with a name.
struct RegUnitSet {
typedef std::vector<unsigned>::const_iterator iterator;
// CodeGenRegBank - Represent a target's registers and the relations between
// them.
class CodeGenRegBank {
- RecordKeeper &Records;
SetTheory Sets;
// SubRegIndices.
std::vector<CodeGenSubRegIndex*> SubRegIndices;
DenseMap<Record*, CodeGenSubRegIndex*> Def2SubRegIdx;
- unsigned NumNamedIndices;
+
+ CodeGenSubRegIndex *createSubRegIndex(StringRef Name, StringRef NameSpace);
typedef std::map<SmallVector<CodeGenSubRegIndex*, 8>,
CodeGenSubRegIndex*> ConcatIdxMap;
// Registers.
std::vector<CodeGenRegister*> Registers;
+ StringMap<CodeGenRegister*> RegistersByName;
DenseMap<Record*, CodeGenRegister*> Def2Reg;
unsigned NumNativeRegUnits;
- unsigned NumRegUnits; // # native + adopted register units.
std::map<TopoSigId, unsigned> TopoSigs;
- // Map each register unit to a weight (for register pressure).
- // Includes native and adopted register units.
- std::vector<unsigned> RegUnitWeights;
+ // Includes native (0..NumNativeRegUnits-1) and adopted register units.
+ SmallVector<RegUnit, 8> RegUnits;
// Register classes.
std::vector<CodeGenRegisterClass*> RegClasses;
// Populate the Composite map from sub-register relationships.
void computeComposites();
+ // Compute a lane mask for each sub-register index.
+ void computeSubRegIndexLaneMasks();
+
public:
CodeGenRegBank(RecordKeeper&);
// in the .td files. The rest are synthesized such that all sub-registers
// have a unique name.
ArrayRef<CodeGenSubRegIndex*> getSubRegIndices() { return SubRegIndices; }
- unsigned getNumNamedIndices() { return NumNamedIndices; }
// Find a SubRegIndex form its Record def.
CodeGenSubRegIndex *getSubRegIdx(Record*);
}
const std::vector<CodeGenRegister*> &getRegisters() { return Registers; }
+ const StringMap<CodeGenRegister*> &getRegistersByName() {
+ return RegistersByName;
+ }
// Find a register from its Record def.
CodeGenRegister *getReg(Record*);
return TopoSigs.insert(std::make_pair(Id, TopoSigs.size())).first->second;
}
+ // Create a native register unit that is associated with one or two root
+ // registers.
+ unsigned newRegUnit(CodeGenRegister *R0, CodeGenRegister *R1 = 0) {
+ RegUnits.resize(RegUnits.size() + 1);
+ RegUnits.back().Roots[0] = R0;
+ RegUnits.back().Roots[1] = R1;
+ return RegUnits.size() - 1;
+ }
+
// Create a new non-native register unit that can be adopted by a register
// to increase its pressure. Note that NumNativeRegUnits is not increased.
unsigned newRegUnit(unsigned Weight) {
- if (!RegUnitWeights.empty()) {
- assert(Weight && "should only add allocatable units");
- RegUnitWeights.resize(NumRegUnits+1);
- RegUnitWeights[NumRegUnits] = Weight;
- }
- return NumRegUnits++;
+ RegUnits.resize(RegUnits.size() + 1);
+ RegUnits.back().Weight = Weight;
+ return RegUnits.size() - 1;
}
// Native units are the singular unit of a leaf register. Register aliasing
return RUID < NumNativeRegUnits;
}
+ unsigned getNumNativeRegUnits() const {
+ return NumNativeRegUnits;
+ }
+
+ RegUnit &getRegUnit(unsigned RUID) { return RegUnits[RUID]; }
+ const RegUnit &getRegUnit(unsigned RUID) const { return RegUnits[RUID]; }
+
ArrayRef<CodeGenRegisterClass*> getRegClasses() const {
return RegClasses;
}
/// return the superclass. Otherwise return null.
const CodeGenRegisterClass* getRegClassForRegister(Record *R);
- // Get a register unit's weight. Zero for unallocatable registers.
- unsigned getRegUnitWeight(unsigned RUID) const {
- return RegUnitWeights[RUID];
- }
-
// Get the sum of unit weights.
unsigned getRegUnitSetWeight(const std::vector<unsigned> &Units) const {
unsigned Weight = 0;
for (std::vector<unsigned>::const_iterator
I = Units.begin(), E = Units.end(); I != E; ++I)
- Weight += getRegUnitWeight(*I);
+ Weight += getRegUnit(*I).Weight;
return Weight;
}
// Increase a RegUnitWeight.
void increaseRegUnitWeight(unsigned RUID, unsigned Inc) {
- RegUnitWeights[RUID] += Inc;
+ getRegUnit(RUID).Weight += Inc;
}
// Get the number of register pressure dimensions.
// Computed derived records such as missing sub-register indices.
void computeDerivedInfo();
- // Compute full overlap sets for every register. These sets include the
- // rarely used aliases that are neither sub nor super-registers.
- //
- // Map[R1].count(R2) is reflexive and symmetric, but not transitive.
- //
- // If R1 is a sub-register of R2, Map[R1] is a subset of Map[R2].
- void computeOverlaps(std::map<const CodeGenRegister*,
- CodeGenRegister::Set> &Map);
-
// Compute the set of registers completely covered by the registers in Regs.
// The returned BitVector will have a bit set for each register in Regs,
// all sub-registers, and all super-registers that are covered by the