#define CODEGEN_REGISTERS_H
#include "SetTheory.h"
-#include "llvm/TableGen/Record.h"
-#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/TableGen/Record.h"
#include <cstdlib>
#include <map>
-#include <string>
#include <set>
+#include <string>
#include <vector>
namespace llvm {
/// CodeGenSubRegIndex - Represents a sub-register index.
class CodeGenSubRegIndex {
Record *const TheDef;
+ std::string Name;
+ std::string Namespace;
public:
+ uint16_t Size;
+ uint16_t Offset;
const unsigned EnumValue;
+ unsigned LaneMask;
+
+ // Are all super-registers containing this SubRegIndex covered by their
+ // sub-registers?
+ bool AllSuperRegsCovered;
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.
// Returns NULL if this and Idx don't compose.
CodeGenSubRegIndex *compose(CodeGenSubRegIndex *Idx) const {
CompMap::const_iterator I = Composed.find(Idx);
- return I == Composed.end() ? 0 : I->second;
+ return I == Composed.end() ? nullptr : I->second;
}
// Add a composite subreg index: this+A = B.
assert(A && B);
std::pair<CompMap::iterator, bool> Ins =
Composed.insert(std::make_pair(A, B));
- return (Ins.second || Ins.first->second == B) ? 0 : Ins.first->second;
+ // Synthetic subreg indices that aren't contiguous (for instance ARM
+ // register tuples) don't have a bit range, so it's OK to let
+ // B->Offset == -1. For the other cases, accumulate the offset and set
+ // the size here. Only do so if there is no offset yet though.
+ if ((Offset != (uint16_t)-1 && A->Offset != (uint16_t)-1) &&
+ (B->Offset == (uint16_t)-1)) {
+ B->Offset = Offset + A->Offset;
+ B->Size = A->Size;
+ }
+ return (Ins.second || Ins.first->second == B) ? nullptr
+ : Ins.first->second;
}
// 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;
};
// 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);
// 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;
public:
unsigned EnumValue;
std::string Namespace;
- std::vector<MVT::SimpleValueType> VTs;
+ SmallVector<MVT::SimpleValueType, 4> VTs;
unsigned SpillSize;
unsigned SpillAlignment;
int CopyCost;
const std::string &getName() const { return Name; }
std::string getQualifiedName() const;
- const std::vector<MVT::SimpleValueType> &getValueTypes() const {return VTs;}
+ ArrayRef<MVT::SimpleValueType> getValueTypes() const {return VTs;}
unsigned getNumValueTypes() const { return VTs.size(); }
MVT::SimpleValueType getValueTypeNum(unsigned VTNum) const {
// getSubClasses - Returns a constant BitVector of subclasses indexed by
// EnumValue.
- // The SubClasses vector includs an entry for this class.
+ // The SubClasses vector includes an entry for this class.
const BitVector &getSubClasses() const { return SubClasses; }
// getSuperClasses - Returns a list of super classes ordered by EnumValue.
unsigned SpillSize;
unsigned SpillAlignment;
- Key(const Key &O)
- : Members(O.Members),
- SpillSize(O.SpillSize),
- SpillAlignment(O.SpillAlignment) {}
-
Key(const CodeGenRegister::Set *M, unsigned S = 0, unsigned A = 0)
: Members(M), SpillSize(S), SpillAlignment(A) {}
// these two registers and their super-registers.
const CodeGenRegister *Roots[2];
- RegUnit() : Weight(0) { Roots[0] = Roots[1] = 0; }
+ // Index into RegClassUnitSets where we can find the list of UnitSets that
+ // contain this unit.
+ unsigned RegClassUnitSetsIdx;
+
+ RegUnit() : Weight(0), RegClassUnitSetsIdx(0) {
+ Roots[0] = Roots[1] = nullptr;
+ }
ArrayRef<const CodeGenRegister*> getRoots() const {
assert(!(Roots[1] && !Roots[0]) && "Invalid roots array");
std::string Name;
std::vector<unsigned> Units;
+ unsigned Weight; // Cache the sum of all unit weights.
+ unsigned Order; // Cache the sort key.
+
+ RegUnitSet() : Weight(0), Order(0) {}
};
// Base vector for identifying TopoSigs. The contents uniquely identify a
// 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;
// Map RegisterClass index to the index of the RegUnitSet that contains the
// class's units and any inferred RegUnit supersets.
+ //
+ // NOTE: This could grow beyond the number of register classes when we map
+ // register units to lists of unit sets. If the list of unit sets does not
+ // already exist for a register class, we create a new entry in this vector.
std::vector<std::vector<unsigned> > RegClassUnitSets;
+ // Give each register unit set an order based on sorting criteria.
+ std::vector<unsigned> RegUnitSetOrder;
+
// Add RC to *2RC maps.
void addToMaps(CodeGenRegisterClass*);
// 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*);
// Find or create a sub-register index representing the concatenation of
// non-overlapping sibling indices.
CodeGenSubRegIndex *
- getConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex*, 8>&);
+ getConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex *, 8>&);
void
- addConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex*, 8> &Parts,
+ addConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex *, 8> &Parts,
CodeGenSubRegIndex *Idx) {
ConcatIdx.insert(std::make_pair(Parts, Idx));
}
const std::vector<CodeGenRegister*> &getRegisters() { return Registers; }
+ const StringMap<CodeGenRegister*> &getRegistersByName() {
+ return RegistersByName;
+ }
// Find a register from its Record def.
CodeGenRegister *getReg(Record*);
// Create a native register unit that is associated with one or two root
// registers.
- unsigned newRegUnit(CodeGenRegister *R0, CodeGenRegister *R1 = 0) {
+ unsigned newRegUnit(CodeGenRegister *R0, CodeGenRegister *R1 = nullptr) {
RegUnits.resize(RegUnits.size() + 1);
RegUnits.back().Roots[0] = R0;
RegUnits.back().Roots[1] = R1;
return RUID < NumNativeRegUnits;
}
+ unsigned getNumNativeRegUnits() const {
+ return NumNativeRegUnits;
+ }
+
RegUnit &getRegUnit(unsigned RUID) { return RegUnits[RUID]; }
const RegUnit &getRegUnit(unsigned RUID) const { return RegUnits[RUID]; }
return Weight;
}
+ unsigned getRegSetIDAt(unsigned Order) const {
+ return RegUnitSetOrder[Order];
+ }
+ const RegUnitSet &getRegSetAt(unsigned Order) const {
+ return RegUnitSets[RegUnitSetOrder[Order]];
+ }
+
// Increase a RegUnitWeight.
void increaseRegUnitWeight(unsigned RUID, unsigned Inc) {
getRegUnit(RUID).Weight += Inc;
unsigned getNumRegPressureSets() const { return RegUnitSets.size(); }
// Get a set of register unit IDs for a given dimension of pressure.
- RegUnitSet getRegPressureSet(unsigned Idx) const {
+ const RegUnitSet &getRegPressureSet(unsigned Idx) const {
return RegUnitSets[Idx];
}
+ // The number of pressure set lists may be larget than the number of
+ // register classes if some register units appeared in a list of sets that
+ // did not correspond to an existing register class.
+ unsigned getNumRegClassPressureSetLists() const {
+ return RegClassUnitSets.size();
+ }
+
// Get a list of pressure set IDs for a register class. Liveness of a
// register in this class impacts each pressure set in this list by the
// weight of the register. An exact solution requires all registers in a
// This is used to compute the mask of call-preserved registers from a list
// of callee-saves.
BitVector computeCoveredRegisters(ArrayRef<Record*> Regs);
+
+ // Bit mask of lanes that cover their registers. A sub-register index whose
+ // LaneMask is contained in CoveringLanes will be completely covered by
+ // another sub-register with the same or larger lane mask.
+ unsigned CoveringLanes;
};
}