+ Key(const CodeGenRegister::Set *M, unsigned S = 0, unsigned A = 0)
+ : Members(M), SpillSize(S), SpillAlignment(A) {}
+
+ Key(const CodeGenRegisterClass &RC)
+ : Members(&RC.getMembers()),
+ SpillSize(RC.SpillSize),
+ SpillAlignment(RC.SpillAlignment) {}
+
+ // Lexicographical order of (Members, SpillSize, SpillAlignment).
+ bool operator<(const Key&) const;
+ };
+
+ // Create a non-user defined register class.
+ 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];
+
+ // 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");
+ 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;
+
+ 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
+ // TopoSig, only computeSuperRegs needs to know how.
+ typedef SmallVector<unsigned, 16> TopoSigId;
+
+ // CodeGenRegBank - Represent a target's registers and the relations between
+ // them.
+ class CodeGenRegBank {
+ SetTheory Sets;
+
+ std::deque<CodeGenSubRegIndex> SubRegIndices;
+ DenseMap<Record*, CodeGenSubRegIndex*> Def2SubRegIdx;
+
+ CodeGenSubRegIndex *createSubRegIndex(StringRef Name, StringRef NameSpace);
+
+ typedef std::map<SmallVector<CodeGenSubRegIndex*, 8>,
+ CodeGenSubRegIndex*> ConcatIdxMap;
+ ConcatIdxMap ConcatIdx;
+
+ // Registers.
+ std::deque<CodeGenRegister> Registers;
+ StringMap<CodeGenRegister*> RegistersByName;
+ DenseMap<Record*, CodeGenRegister*> Def2Reg;
+ unsigned NumNativeRegUnits;
+
+ std::map<TopoSigId, unsigned> TopoSigs;
+
+ // Includes native (0..NumNativeRegUnits-1) and adopted register units.
+ SmallVector<RegUnit, 8> RegUnits;
+
+ // Register classes.
+ std::vector<CodeGenRegisterClass*> RegClasses;
+ DenseMap<Record*, CodeGenRegisterClass*> Def2RC;
+ typedef std::map<CodeGenRegisterClass::Key, CodeGenRegisterClass*> RCKeyMap;
+ RCKeyMap Key2RC;
+
+ // Remember each unique set of register units. Initially, this contains a
+ // unique set for each register class. Simliar sets are coalesced with
+ // pruneUnitSets and new supersets are inferred during computeRegUnitSets.
+ std::vector<RegUnitSet> RegUnitSets;
+
+ // 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*);
+
+ // Create a synthetic sub-class if it is missing.
+ CodeGenRegisterClass *getOrCreateSubClass(const CodeGenRegisterClass *RC,
+ const CodeGenRegister::Set *Membs,
+ StringRef Name);
+
+ // Infer missing register classes.
+ void computeInferredRegisterClasses();
+ void inferCommonSubClass(CodeGenRegisterClass *RC);
+ void inferSubClassWithSubReg(CodeGenRegisterClass *RC);
+ void inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
+ unsigned FirstSubRegRC = 0);
+
+ // Iteratively prune unit sets.
+ void pruneUnitSets();
+
+ // Compute a weight for each register unit created during getSubRegs.
+ void computeRegUnitWeights();
+
+ // Create a RegUnitSet for each RegClass and infer superclasses.
+ void computeRegUnitSets();
+
+ // Populate the Composite map from sub-register relationships.
+ void computeComposites();
+
+ // Compute a lane mask for each sub-register index.
+ void computeSubRegIndexLaneMasks();
+
+ public:
+ CodeGenRegBank(RecordKeeper&);
+
+ SetTheory &getSets() { return Sets; }
+
+ // Sub-register indices. The first NumNamedIndices are defined by the user
+ // in the .td files. The rest are synthesized such that all sub-registers
+ // have a unique name.
+ const std::deque<CodeGenSubRegIndex> &getSubRegIndices() const {
+ return SubRegIndices;
+ }
+
+ // Find a SubRegIndex form its Record def.
+ CodeGenSubRegIndex *getSubRegIdx(Record*);
+
+ // Find or create a sub-register index representing the A+B composition.
+ CodeGenSubRegIndex *getCompositeSubRegIndex(CodeGenSubRegIndex *A,
+ CodeGenSubRegIndex *B);
+
+ // Find or create a sub-register index representing the concatenation of
+ // non-overlapping sibling indices.
+ CodeGenSubRegIndex *
+ getConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex *, 8>&);
+
+ void
+ addConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex *, 8> &Parts,
+ CodeGenSubRegIndex *Idx) {
+ ConcatIdx.insert(std::make_pair(Parts, Idx));
+ }
+
+ const std::deque<CodeGenRegister> &getRegisters() { return Registers; }
+ const StringMap<CodeGenRegister*> &getRegistersByName() {
+ return RegistersByName;
+ }
+
+ // Find a register from its Record def.
+ CodeGenRegister *getReg(Record*);
+
+ // Get a Register's index into the Registers array.
+ unsigned getRegIndex(const CodeGenRegister *Reg) const {
+ return Reg->EnumValue - 1;
+ }
+
+ // Return the number of allocated TopoSigs. The first TopoSig representing
+ // leaf registers is allocated number 0.
+ unsigned getNumTopoSigs() const {
+ return TopoSigs.size();
+ }
+
+ // Find or create a TopoSig for the given TopoSigId.
+ // This function is only for use by CodeGenRegister::computeSuperRegs().
+ // Others should simply use Reg->getTopoSig().
+ unsigned getTopoSig(const TopoSigId &Id) {
+ 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 = nullptr) {
+ RegUnits.resize(RegUnits.size() + 1);
+ RegUnits.back().Roots[0] = R0;
+ RegUnits.back().Roots[1] = R1;
+ return RegUnits.size() - 1;