18dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner//===- CodeGenRegisters.h - Register and RegisterClass Info -----*- C++ -*-===//
23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
38dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner//                     The LLVM Compiler Infrastructure
48dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner//
53060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// This file is distributed under the University of Illinois Open Source
63060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// License. See LICENSE.TXT for details.
73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
88dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner//===----------------------------------------------------------------------===//
98dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner//
108dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner// This file defines structures to encapsulate information gleaned from the
118dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner// target register and register class definitions.
128dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner//
138dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner//===----------------------------------------------------------------------===//
148dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner
158dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner#ifndef CODEGEN_REGISTERS_H
168dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner#define CODEGEN_REGISTERS_H
178dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner
1859f26aadce1bb985b9befe841fc106c891e1c728Jakob Stoklund Olesen#include "SetTheory.h"
19ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen#include "llvm/ADT/ArrayRef.h"
20203e0b17dd6049d64cb4ed7c4da09747204e6463Jakob Stoklund Olesen#include "llvm/ADT/BitVector.h"
2109bc0298650c76db1a06e20ca84c1dcb34071600Jakob Stoklund Olesen#include "llvm/ADT/DenseMap.h"
22026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen#include "llvm/ADT/SetVector.h"
234ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/CodeGen/ValueTypes.h"
24655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper#include "llvm/Support/ErrorHandling.h"
254ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include "llvm/TableGen/Record.h"
26b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen#include <cstdlib>
27b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen#include <map>
28a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher#include <set>
294ffd89fa4d2788611187d1a534d2ed46adf1702cChandler Carruth#include <string>
30b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen#include <vector>
318dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner
328dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattnernamespace llvm {
33b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen  class CodeGenRegBank;
348dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner
355fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen  /// CodeGenSubRegIndex - Represents a sub-register index.
365fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen  class CodeGenSubRegIndex {
375fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    Record *const TheDef;
38c97eda2c9e34f4c491f59bbac81af2fd63fef49dJakob Stoklund Olesen    std::string Name;
39c97eda2c9e34f4c491f59bbac81af2fd63fef49dJakob Stoklund Olesen    std::string Namespace;
405fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen
415fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen  public:
42b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    const unsigned EnumValue;
43a6035773d8d29827a124e65c258adbf0dcbb1a5aJakob Stoklund Olesen    unsigned LaneMask;
44b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen
455fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    CodeGenSubRegIndex(Record *R, unsigned Enum);
46c97eda2c9e34f4c491f59bbac81af2fd63fef49dJakob Stoklund Olesen    CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum);
475fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen
48c97eda2c9e34f4c491f59bbac81af2fd63fef49dJakob Stoklund Olesen    const std::string &getName() const { return Name; }
49c97eda2c9e34f4c491f59bbac81af2fd63fef49dJakob Stoklund Olesen    const std::string &getNamespace() const { return Namespace; }
505fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    std::string getQualifiedName() const;
515fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen
525fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    // Order CodeGenSubRegIndex pointers by EnumValue.
535fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    struct Less {
545fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen      bool operator()(const CodeGenSubRegIndex *A,
555fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen                      const CodeGenSubRegIndex *B) const {
565fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen        assert(A && B);
575fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen        return A->EnumValue < B->EnumValue;
585fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen      }
595fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    };
6090498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen
6190498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen    // Map of composite subreg indices.
6290498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen    typedef std::map<CodeGenSubRegIndex*, CodeGenSubRegIndex*, Less> CompMap;
6390498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen
6490498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen    // Returns the subreg index that results from composing this with Idx.
6590498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen    // Returns NULL if this and Idx don't compose.
6690498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen    CodeGenSubRegIndex *compose(CodeGenSubRegIndex *Idx) const {
6790498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen      CompMap::const_iterator I = Composed.find(Idx);
6890498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen      return I == Composed.end() ? 0 : I->second;
6990498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen    }
7090498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen
7190498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen    // Add a composite subreg index: this+A = B.
7290498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen    // Return a conflicting composite, or NULL
7390498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen    CodeGenSubRegIndex *addComposite(CodeGenSubRegIndex *A,
7490498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen                                     CodeGenSubRegIndex *B) {
75fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen      assert(A && B);
7690498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen      std::pair<CompMap::iterator, bool> Ins =
7790498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen        Composed.insert(std::make_pair(A, B));
7890498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen      return (Ins.second || Ins.first->second == B) ? 0 : Ins.first->second;
7990498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen    }
8090498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen
81b5af2d943ed568f2f4cac545b6dfb150ae9d73aaJakob Stoklund Olesen    // Update the composite maps of components specified in 'ComposedOf'.
82b5af2d943ed568f2f4cac545b6dfb150ae9d73aaJakob Stoklund Olesen    void updateComponents(CodeGenRegBank&);
83b5af2d943ed568f2f4cac545b6dfb150ae9d73aaJakob Stoklund Olesen
8490498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen    // Return the map of composites.
8590498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen    const CompMap &getComposites() const { return Composed; }
8690498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen
87a6035773d8d29827a124e65c258adbf0dcbb1a5aJakob Stoklund Olesen    // Compute LaneMask from Composed. Return LaneMask.
88a6035773d8d29827a124e65c258adbf0dcbb1a5aJakob Stoklund Olesen    unsigned computeLaneMask();
89a6035773d8d29827a124e65c258adbf0dcbb1a5aJakob Stoklund Olesen
9090498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen  private:
9190498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen    CompMap Composed;
925fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen  };
935fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen
948dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner  /// CodeGenRegister - Represents a register definition.
958dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner  struct CodeGenRegister {
968dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner    Record *TheDef;
9717fad045cccf34822d3163ada9e70a8f4528746eJim Grosbach    unsigned EnumValue;
986bfba2e5af163442a1c6b11fe14aa9df9101cfd7Jakob Stoklund Olesen    unsigned CostPerUse;
9931867660cb81ea2b1d1a6ffa7d09c91acb754a8bJakob Stoklund Olesen    bool CoveredBySubRegs;
100b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
101b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Map SubRegIndex -> Register.
1025fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    typedef std::map<CodeGenSubRegIndex*, CodeGenRegister*,
1035fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen                     CodeGenSubRegIndex::Less> SubRegMap;
104b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
105b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    CodeGenRegister(Record *R, unsigned Enum);
106b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
107b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    const std::string &getName() const;
108b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
109148f392195dec8772ab4c5ac0d0c3b85fba0e5f8Jakob Stoklund Olesen    // Extract more information from TheDef. This is used to build an object
110148f392195dec8772ab4c5ac0d0c3b85fba0e5f8Jakob Stoklund Olesen    // graph after all CodeGenRegister objects have been created.
111148f392195dec8772ab4c5ac0d0c3b85fba0e5f8Jakob Stoklund Olesen    void buildObjectGraph(CodeGenRegBank&);
112148f392195dec8772ab4c5ac0d0c3b85fba0e5f8Jakob Stoklund Olesen
113da2be824346c316c6fc840de7b8493e3d587e785Jakob Stoklund Olesen    // Lazily compute a map of all sub-registers.
114b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // This includes unique entries for all sub-sub-registers.
115da2be824346c316c6fc840de7b8493e3d587e785Jakob Stoklund Olesen    const SubRegMap &computeSubRegs(CodeGenRegBank&);
116b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
117fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    // Compute extra sub-registers by combining the existing sub-registers.
118fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    void computeSecondarySubRegs(CodeGenRegBank&);
119fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen
12079e2045531cb4d1978be42591e9254c38a463d30Jakob Stoklund Olesen    // Add this as a super-register to all sub-registers after the sub-register
12179e2045531cb4d1978be42591e9254c38a463d30Jakob Stoklund Olesen    // graph has been built.
122b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    void computeSuperRegs(CodeGenRegBank&);
12379e2045531cb4d1978be42591e9254c38a463d30Jakob Stoklund Olesen
124b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    const SubRegMap &getSubRegs() const {
125b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen      assert(SubRegsComplete && "Must precompute sub-registers");
126b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen      return SubRegs;
127b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    }
128b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
129026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    // Add sub-registers to OSet following a pre-order defined by the .td file.
130c6a96ff6aeeb77e1007364e5603b72f3ab4cc7bdJakob Stoklund Olesen    void addSubRegsPreOrder(SetVector<const CodeGenRegister*> &OSet,
1315fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen                            CodeGenRegBank&) const;
132026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen
133ca313e1efa98910a7a5e7f4bf2ac1a70adb6e4feJakob Stoklund Olesen    // Return the sub-register index naming Reg as a sub-register of this
134ca313e1efa98910a7a5e7f4bf2ac1a70adb6e4feJakob Stoklund Olesen    // register. Returns NULL if Reg is not a sub-register.
135ca313e1efa98910a7a5e7f4bf2ac1a70adb6e4feJakob Stoklund Olesen    CodeGenSubRegIndex *getSubRegIndex(const CodeGenRegister *Reg) const {
136ca313e1efa98910a7a5e7f4bf2ac1a70adb6e4feJakob Stoklund Olesen      return SubReg2Idx.lookup(Reg);
137ca313e1efa98910a7a5e7f4bf2ac1a70adb6e4feJakob Stoklund Olesen    }
138ca313e1efa98910a7a5e7f4bf2ac1a70adb6e4feJakob Stoklund Olesen
139c6a96ff6aeeb77e1007364e5603b72f3ab4cc7bdJakob Stoklund Olesen    typedef std::vector<const CodeGenRegister*> SuperRegList;
140026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen
141fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    // Get the list of super-registers in topological order, small to large.
142fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    // This is valid after computeSubRegs visits all registers during RegBank
143fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    // construction.
144026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    const SuperRegList &getSuperRegs() const {
145026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen      assert(SubRegsComplete && "Must precompute sub-registers");
146026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen      return SuperRegs;
147026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    }
148026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen
14931d938a6b1173c642f975d78417459d4d8cd3677Jakob Stoklund Olesen    // Get the list of ad hoc aliases. The graph is symmetric, so the list
15031d938a6b1173c642f975d78417459d4d8cd3677Jakob Stoklund Olesen    // contains all registers in 'Aliases', and all registers that mention this
15131d938a6b1173c642f975d78417459d4d8cd3677Jakob Stoklund Olesen    // register in 'Aliases'.
15231d938a6b1173c642f975d78417459d4d8cd3677Jakob Stoklund Olesen    ArrayRef<CodeGenRegister*> getExplicitAliases() const {
15331d938a6b1173c642f975d78417459d4d8cd3677Jakob Stoklund Olesen      return ExplicitAliases;
15431d938a6b1173c642f975d78417459d4d8cd3677Jakob Stoklund Olesen    }
15531d938a6b1173c642f975d78417459d4d8cd3677Jakob Stoklund Olesen
156b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    // Get the topological signature of this register. This is a small integer
157b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    // less than RegBank.getNumTopoSigs(). Registers with the same TopoSig have
158b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    // identical sub-register structure. That is, they support the same set of
159b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    // sub-register indices mapping to the same kind of sub-registers
160b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    // (TopoSig-wise).
161b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    unsigned getTopoSig() const {
162b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen      assert(SuperRegsComplete && "TopoSigs haven't been computed yet.");
163b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen      return TopoSig;
164b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    }
165b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen
166dd9a50196cd75dbcb2bd604754cd62f8c1f30357Andrew Trick    // List of register units in ascending order.
167dd9a50196cd75dbcb2bd604754cd62f8c1f30357Andrew Trick    typedef SmallVector<unsigned, 16> RegUnitList;
168dd9a50196cd75dbcb2bd604754cd62f8c1f30357Andrew Trick
169f52baf72c116d9cf8680d25a8e751ce354c7d44bJakob Stoklund Olesen    // How many entries in RegUnitList are native?
170f52baf72c116d9cf8680d25a8e751ce354c7d44bJakob Stoklund Olesen    unsigned NumNativeRegUnits;
171f52baf72c116d9cf8680d25a8e751ce354c7d44bJakob Stoklund Olesen
172dd9a50196cd75dbcb2bd604754cd62f8c1f30357Andrew Trick    // Get the list of register units.
173f52baf72c116d9cf8680d25a8e751ce354c7d44bJakob Stoklund Olesen    // This is only valid after computeSubRegs() completes.
174dd9a50196cd75dbcb2bd604754cd62f8c1f30357Andrew Trick    const RegUnitList &getRegUnits() const { return RegUnits; }
175dd9a50196cd75dbcb2bd604754cd62f8c1f30357Andrew Trick
176f52baf72c116d9cf8680d25a8e751ce354c7d44bJakob Stoklund Olesen    // Get the native register units. This is a prefix of getRegUnits().
177f52baf72c116d9cf8680d25a8e751ce354c7d44bJakob Stoklund Olesen    ArrayRef<unsigned> getNativeRegUnits() const {
178f52baf72c116d9cf8680d25a8e751ce354c7d44bJakob Stoklund Olesen      return makeArrayRef(RegUnits).slice(0, NumNativeRegUnits);
179f52baf72c116d9cf8680d25a8e751ce354c7d44bJakob Stoklund Olesen    }
180f52baf72c116d9cf8680d25a8e751ce354c7d44bJakob Stoklund Olesen
181d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    // Inherit register units from subregisters.
182d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    // Return true if the RegUnits changed.
183d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    bool inheritRegUnits(CodeGenRegBank &RegBank);
184d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick
185d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    // Adopt a register unit for pressure tracking.
18694c22716d60ff5edf6a98a3c67e0faa001be1142Sylvestre Ledru    // A unit is adopted iff its unit number is >= NumNativeRegUnits.
187d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    void adoptRegUnit(unsigned RUID) { RegUnits.push_back(RUID); }
188d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick
189d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    // Get the sum of this register's register unit weights.
190d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    unsigned getWeight(const CodeGenRegBank &RegBank) const;
191d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick
192026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    // Order CodeGenRegister pointers by EnumValue.
193026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    struct Less {
194ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen      bool operator()(const CodeGenRegister *A,
195ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen                      const CodeGenRegister *B) const {
196babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen        assert(A && B);
197026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen        return A->EnumValue < B->EnumValue;
198026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen      }
199026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    };
200026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen
201026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    // Canonically ordered set.
202ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    typedef std::set<const CodeGenRegister*, Less> Set;
203026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen
2043778aeb74864390bf763424c45cc355ac330fbc9Jakob Stoklund Olesen    // Compute the set of registers overlapping this.
2053778aeb74864390bf763424c45cc355ac330fbc9Jakob Stoklund Olesen    void computeOverlaps(Set &Overlaps, const CodeGenRegBank&) const;
2063778aeb74864390bf763424c45cc355ac330fbc9Jakob Stoklund Olesen
207b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen  private:
208b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    bool SubRegsComplete;
20979e2045531cb4d1978be42591e9254c38a463d30Jakob Stoklund Olesen    bool SuperRegsComplete;
210b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    unsigned TopoSig;
211148f392195dec8772ab4c5ac0d0c3b85fba0e5f8Jakob Stoklund Olesen
212148f392195dec8772ab4c5ac0d0c3b85fba0e5f8Jakob Stoklund Olesen    // The sub-registers explicit in the .td file form a tree.
213148f392195dec8772ab4c5ac0d0c3b85fba0e5f8Jakob Stoklund Olesen    SmallVector<CodeGenSubRegIndex*, 8> ExplicitSubRegIndices;
214148f392195dec8772ab4c5ac0d0c3b85fba0e5f8Jakob Stoklund Olesen    SmallVector<CodeGenRegister*, 8> ExplicitSubRegs;
215148f392195dec8772ab4c5ac0d0c3b85fba0e5f8Jakob Stoklund Olesen
21631d938a6b1173c642f975d78417459d4d8cd3677Jakob Stoklund Olesen    // Explicit ad hoc aliases, symmetrized to form an undirected graph.
21731d938a6b1173c642f975d78417459d4d8cd3677Jakob Stoklund Olesen    SmallVector<CodeGenRegister*, 8> ExplicitAliases;
21831d938a6b1173c642f975d78417459d4d8cd3677Jakob Stoklund Olesen
219fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    // Super-registers where this is the first explicit sub-register.
220fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    SuperRegList LeadingSuperRegs;
221fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen
222b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    SubRegMap SubRegs;
223026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    SuperRegList SuperRegs;
224ca313e1efa98910a7a5e7f4bf2ac1a70adb6e4feJakob Stoklund Olesen    DenseMap<const CodeGenRegister*, CodeGenSubRegIndex*> SubReg2Idx;
225dd9a50196cd75dbcb2bd604754cd62f8c1f30357Andrew Trick    RegUnitList RegUnits;
2268dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner  };
2278dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner
2288dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner
229ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen  class CodeGenRegisterClass {
230ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    CodeGenRegister::Set Members;
231cc0c975b7db95ce6bc865c56a3016bf0d4f83304Jakob Stoklund Olesen    // Allocation orders. Order[0] always contains all registers in Members.
232cc0c975b7db95ce6bc865c56a3016bf0d4f83304Jakob Stoklund Olesen    std::vector<SmallVector<Record*, 16> > Orders;
233203e0b17dd6049d64cb4ed7c4da09747204e6463Jakob Stoklund Olesen    // Bit mask of sub-classes including this, indexed by their EnumValue.
234203e0b17dd6049d64cb4ed7c4da09747204e6463Jakob Stoklund Olesen    BitVector SubClasses;
235f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    // List of super-classes, topologocally ordered to have the larger classes
236f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    // first.  This is the same as sorting by EnumValue.
237f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    SmallVector<CodeGenRegisterClass*, 4> SuperClasses;
238056afeface2ac98664ed8fa4799b46178a4a6fe3Chris Lattner    Record *TheDef;
2396fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    std::string Name;
240babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
241babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // For a synthesized class, inherit missing properties from the nearest
242babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // super-class.
243babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    void inheritProperties(CodeGenRegBank&);
244babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
245570f9a972e02830d1ca223743dd6b4cc4fdf9549Jakob Stoklund Olesen    // Map SubRegIndex -> sub-class.  This is the largest sub-class where all
246570f9a972e02830d1ca223743dd6b4cc4fdf9549Jakob Stoklund Olesen    // registers have a SubRegIndex sub-register.
2475fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    DenseMap<CodeGenSubRegIndex*, CodeGenRegisterClass*> SubClassWithSubReg;
248845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen
249570f9a972e02830d1ca223743dd6b4cc4fdf9549Jakob Stoklund Olesen    // Map SubRegIndex -> set of super-reg classes.  This is all register
250570f9a972e02830d1ca223743dd6b4cc4fdf9549Jakob Stoklund Olesen    // classes SuperRC such that:
251570f9a972e02830d1ca223743dd6b4cc4fdf9549Jakob Stoklund Olesen    //
252570f9a972e02830d1ca223743dd6b4cc4fdf9549Jakob Stoklund Olesen    //   R:SubRegIndex in this RC for all R in SuperRC.
253570f9a972e02830d1ca223743dd6b4cc4fdf9549Jakob Stoklund Olesen    //
2545fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    DenseMap<CodeGenSubRegIndex*,
2555fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen             SmallPtrSet<CodeGenRegisterClass*, 8> > SuperRegClasses;
256176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick
257b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    // Bit vector of TopoSigs for the registers in this class. This will be
258b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    // very sparse on regular architectures.
259b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    BitVector TopoSigs;
260b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen
2616fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen  public:
2627dcaa5b0fb56468e774044d3b887c21b2d484a1cJakob Stoklund Olesen    unsigned EnumValue;
263c67c18fd2378fd2394c42f12b67897e7eba02d5cChris Lattner    std::string Namespace;
26426369a930c523b75fe8f4ba18456ff86f68d5612Jakob Stoklund Olesen    SmallVector<MVT::SimpleValueType, 4> VTs;
265056afeface2ac98664ed8fa4799b46178a4a6fe3Chris Lattner    unsigned SpillSize;
266056afeface2ac98664ed8fa4799b46178a4a6fe3Chris Lattner    unsigned SpillAlignment;
267a3ca3149f2b59c512c50aab330b5a0d8efddeffaEvan Cheng    int CopyCost;
268f462e3fac7ac67503657d63dc35330d0b19359b3Jakob Stoklund Olesen    bool Allocatable;
26954c47c1ce94b9e549ef768e80fd004788d13ce85Jakob Stoklund Olesen    std::string AltOrderSelect;
270056afeface2ac98664ed8fa4799b46178a4a6fe3Chris Lattner
2716fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    // Return the Record that defined this class, or NULL if the class was
2726fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    // created by TableGen.
2736fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    Record *getDef() const { return TheDef; }
2746fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen
2756fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    const std::string &getName() const { return Name; }
2766fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    std::string getQualifiedName() const;
27726369a930c523b75fe8f4ba18456ff86f68d5612Jakob Stoklund Olesen    ArrayRef<MVT::SimpleValueType> getValueTypes() const {return VTs;}
2785c4736a3da04795ba8d04e152e151afd6942e2f1Chris Lattner    unsigned getNumValueTypes() const { return VTs.size(); }
2795d4314ef720630e6547fe41efec1608d4c14c78eJim Grosbach
280825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    MVT::SimpleValueType getValueTypeNum(unsigned VTNum) const {
2816510b22cec7de4f0acc9965ec24c3668a6a8a87eNate Begeman      if (VTNum < VTs.size())
2826510b22cec7de4f0acc9965ec24c3668a6a8a87eNate Begeman        return VTs[VTNum];
283655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper      llvm_unreachable("VTNum greater than number of ValueTypes in RegClass!");
2846510b22cec7de4f0acc9965ec24c3668a6a8a87eNate Begeman    }
2855d4314ef720630e6547fe41efec1608d4c14c78eJim Grosbach
286ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    // Return true if this this class contains the register.
287ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    bool contains(const CodeGenRegister*) const;
2885d4314ef720630e6547fe41efec1608d4c14c78eJim Grosbach
289ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    // Returns true if RC is a subclass.
290a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    // RC is a sub-class of this class if it is a valid replacement for any
2915d4314ef720630e6547fe41efec1608d4c14c78eJim Grosbach    // instruction operand where a register of this classis required. It must
292a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    // satisfy these conditions:
293a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    //
294a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    // 1. All RC registers are also in this.
295a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    // 2. The RC spill size must not be smaller than our spill size.
296a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    // 3. RC spill alignment must be compatible with ours.
297a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    //
29852e7dfadc65257f05480de6e70da00373a8954d1Jakob Stoklund Olesen    bool hasSubClass(const CodeGenRegisterClass *RC) const {
29952e7dfadc65257f05480de6e70da00373a8954d1Jakob Stoklund Olesen      return SubClasses.test(RC->EnumValue);
30052e7dfadc65257f05480de6e70da00373a8954d1Jakob Stoklund Olesen    }
301a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher
302845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen    // getSubClassWithSubReg - Returns the largest sub-class where all
303845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen    // registers have a SubIdx sub-register.
3045fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    CodeGenRegisterClass*
3055fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    getSubClassWithSubReg(CodeGenSubRegIndex *SubIdx) const {
306845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen      return SubClassWithSubReg.lookup(SubIdx);
307845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen    }
308845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen
3095fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    void setSubClassWithSubReg(CodeGenSubRegIndex *SubIdx,
3105fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen                               CodeGenRegisterClass *SubRC) {
311845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen      SubClassWithSubReg[SubIdx] = SubRC;
312845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen    }
313845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen
314570f9a972e02830d1ca223743dd6b4cc4fdf9549Jakob Stoklund Olesen    // getSuperRegClasses - Returns a bit vector of all register classes
315570f9a972e02830d1ca223743dd6b4cc4fdf9549Jakob Stoklund Olesen    // containing only SubIdx super-registers of this class.
3165fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    void getSuperRegClasses(CodeGenSubRegIndex *SubIdx, BitVector &Out) const;
317570f9a972e02830d1ca223743dd6b4cc4fdf9549Jakob Stoklund Olesen
318570f9a972e02830d1ca223743dd6b4cc4fdf9549Jakob Stoklund Olesen    // addSuperRegClass - Add a class containing only SudIdx super-registers.
3195fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    void addSuperRegClass(CodeGenSubRegIndex *SubIdx,
3205fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen                          CodeGenRegisterClass *SuperRC) {
321570f9a972e02830d1ca223743dd6b4cc4fdf9549Jakob Stoklund Olesen      SuperRegClasses[SubIdx].insert(SuperRC);
322570f9a972e02830d1ca223743dd6b4cc4fdf9549Jakob Stoklund Olesen    }
323570f9a972e02830d1ca223743dd6b4cc4fdf9549Jakob Stoklund Olesen
324f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    // getSubClasses - Returns a constant BitVector of subclasses indexed by
325f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    // EnumValue.
326f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    // The SubClasses vector includs an entry for this class.
327830378f6628ad3af1d0293a0b605065532f99e43Eli Friedman    const BitVector &getSubClasses() const { return SubClasses; }
328f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen
329f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    // getSuperClasses - Returns a list of super classes ordered by EnumValue.
330f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    // The array does not include an entry for this class.
331f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    ArrayRef<CodeGenRegisterClass*> getSuperClasses() const {
332f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen      return SuperClasses;
333f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    }
334f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen
335ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    // Returns an ordered list of class members.
336ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    // The order of registers is the same as in the .td file.
337b4c704877d1600852a55ab7bef2918a7c0af5e0dJakob Stoklund Olesen    // No = 0 is the default allocation order, No = 1 is the first alternative.
338b4c704877d1600852a55ab7bef2918a7c0af5e0dJakob Stoklund Olesen    ArrayRef<Record*> getOrder(unsigned No = 0) const {
339cc0c975b7db95ce6bc865c56a3016bf0d4f83304Jakob Stoklund Olesen        return Orders[No];
340a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    }
3416510b22cec7de4f0acc9965ec24c3668a6a8a87eNate Begeman
342b4c704877d1600852a55ab7bef2918a7c0af5e0dJakob Stoklund Olesen    // Return the total number of allocation orders available.
343cc0c975b7db95ce6bc865c56a3016bf0d4f83304Jakob Stoklund Olesen    unsigned getNumOrders() const { return Orders.size(); }
344b4c704877d1600852a55ab7bef2918a7c0af5e0dJakob Stoklund Olesen
34552e7dfadc65257f05480de6e70da00373a8954d1Jakob Stoklund Olesen    // Get the set of registers.  This set contains the same registers as
34652e7dfadc65257f05480de6e70da00373a8954d1Jakob Stoklund Olesen    // getOrder(0).
34752e7dfadc65257f05480de6e70da00373a8954d1Jakob Stoklund Olesen    const CodeGenRegister::Set &getMembers() const { return Members; }
34852e7dfadc65257f05480de6e70da00373a8954d1Jakob Stoklund Olesen
349b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    // Get a bit vector of TopoSigs present in this register class.
350b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    const BitVector &getTopoSigs() const { return TopoSigs; }
351b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen
352ec14cd7ddc66d47cd7927f18d8c11844c400367eAndrew Trick    // Populate a unique sorted list of units from a register set.
353ec14cd7ddc66d47cd7927f18d8c11844c400367eAndrew Trick    void buildRegUnitSet(std::vector<unsigned> &RegUnits) const;
354ec14cd7ddc66d47cd7927f18d8c11844c400367eAndrew Trick
355ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    CodeGenRegisterClass(CodeGenRegBank&, Record *R);
356203e0b17dd6049d64cb4ed7c4da09747204e6463Jakob Stoklund Olesen
357babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // A key representing the parts of a register class used for forming
358babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // sub-classes.  Note the ordering provided by this key is not the same as
359babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // the topological order used for the EnumValues.
360babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    struct Key {
361babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      const CodeGenRegister::Set *Members;
362babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      unsigned SpillSize;
363babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      unsigned SpillAlignment;
364babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
365babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      Key(const Key &O)
366babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen        : Members(O.Members),
367babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen          SpillSize(O.SpillSize),
368babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen          SpillAlignment(O.SpillAlignment) {}
369babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
370babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      Key(const CodeGenRegister::Set *M, unsigned S = 0, unsigned A = 0)
371babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen        : Members(M), SpillSize(S), SpillAlignment(A) {}
372babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
373babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      Key(const CodeGenRegisterClass &RC)
374babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen        : Members(&RC.getMembers()),
375babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen          SpillSize(RC.SpillSize),
376babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen          SpillAlignment(RC.SpillAlignment) {}
377babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
378babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      // Lexicographical order of (Members, SpillSize, SpillAlignment).
379babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      bool operator<(const Key&) const;
380babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    };
381babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
382babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // Create a non-user defined register class.
383a9fdbbc55f640fecd3bb8df12fd205694c2f71a2Jakob Stoklund Olesen    CodeGenRegisterClass(CodeGenRegBank&, StringRef Name, Key Props);
384babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
385203e0b17dd6049d64cb4ed7c4da09747204e6463Jakob Stoklund Olesen    // Called by CodeGenRegBank::CodeGenRegBank().
386babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    static void computeSubClasses(CodeGenRegBank&);
3878dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner  };
388dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen
38940c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen  // Register units are used to model interference and register pressure.
39040c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen  // Every register is assigned one or more register units such that two
39140c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen  // registers overlap if and only if they have a register unit in common.
39240c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen  //
39340c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen  // Normally, one register unit is created per leaf register. Non-leaf
39440c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen  // registers inherit the units of their sub-registers.
39540c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen  struct RegUnit {
39640c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    // Weight assigned to this RegUnit for estimating register pressure.
39740c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    // This is useful when equalizing weights in register classes with mixed
39840c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    // register topologies.
39940c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    unsigned Weight;
40040c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen
40140c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    // Each native RegUnit corresponds to one or two root registers. The full
40240c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    // set of registers containing this unit can be computed as the union of
40340c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    // these two registers and their super-registers.
40440c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    const CodeGenRegister *Roots[2];
40540c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen
406eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick    // Index into RegClassUnitSets where we can find the list of UnitSets that
407eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick    // contain this unit.
408eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick    unsigned RegClassUnitSetsIdx;
409eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick
410eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick    RegUnit() : Weight(0), RegClassUnitSetsIdx(0) { Roots[0] = Roots[1] = 0; }
41140c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen
41240c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    ArrayRef<const CodeGenRegister*> getRoots() const {
41340c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen      assert(!(Roots[1] && !Roots[0]) && "Invalid roots array");
41440c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen      return makeArrayRef(Roots, !!Roots[0] + !!Roots[1]);
41540c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    }
41640c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen  };
41740c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen
418176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick  // Each RegUnitSet is a sorted vector with a name.
419176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick  struct RegUnitSet {
420176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    typedef std::vector<unsigned>::const_iterator iterator;
421176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick
422176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    std::string Name;
423176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    std::vector<unsigned> Units;
424176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick  };
425176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick
426b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen  // Base vector for identifying TopoSigs. The contents uniquely identify a
427b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen  // TopoSig, only computeSuperRegs needs to know how.
428b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen  typedef SmallVector<unsigned, 16> TopoSigId;
429b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen
430dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen  // CodeGenRegBank - Represent a target's registers and the relations between
431dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen  // them.
432dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen  class CodeGenRegBank {
43359f26aadce1bb985b9befe841fc106c891e1c728Jakob Stoklund Olesen    SetTheory Sets;
43459f26aadce1bb985b9befe841fc106c891e1c728Jakob Stoklund Olesen
4355fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    // SubRegIndices.
4365fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    std::vector<CodeGenSubRegIndex*> SubRegIndices;
4375fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    DenseMap<Record*, CodeGenSubRegIndex*> Def2SubRegIdx;
438c97eda2c9e34f4c491f59bbac81af2fd63fef49dJakob Stoklund Olesen
439c97eda2c9e34f4c491f59bbac81af2fd63fef49dJakob Stoklund Olesen    CodeGenSubRegIndex *createSubRegIndex(StringRef Name, StringRef NameSpace);
4405fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen
441fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    typedef std::map<SmallVector<CodeGenSubRegIndex*, 8>,
442fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen                     CodeGenSubRegIndex*> ConcatIdxMap;
443fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    ConcatIdxMap ConcatIdx;
444fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen
4455fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    // Registers.
446abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen    std::vector<CodeGenRegister*> Registers;
447d2c699706ceae4a118a8dcafbef73b85093e5390Owen Anderson    StringMap<CodeGenRegister*> RegistersByName;
448b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    DenseMap<Record*, CodeGenRegister*> Def2Reg;
449d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    unsigned NumNativeRegUnits;
450d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick
451b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    std::map<TopoSigId, unsigned> TopoSigs;
452b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen
45340c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    // Includes native (0..NumNativeRegUnits-1) and adopted register units.
45440c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    SmallVector<RegUnit, 8> RegUnits;
455b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
456babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // Register classes.
45729f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen    std::vector<CodeGenRegisterClass*> RegClasses;
4587b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    DenseMap<Record*, CodeGenRegisterClass*> Def2RC;
459babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    typedef std::map<CodeGenRegisterClass::Key, CodeGenRegisterClass*> RCKeyMap;
460babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    RCKeyMap Key2RC;
461babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
462176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // Remember each unique set of register units. Initially, this contains a
463176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // unique set for each register class. Simliar sets are coalesced with
464176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // pruneUnitSets and new supersets are inferred during computeRegUnitSets.
465176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    std::vector<RegUnitSet> RegUnitSets;
466176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick
467176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // Map RegisterClass index to the index of the RegUnitSet that contains the
468176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // class's units and any inferred RegUnit supersets.
469eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick    //
470eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick    // NOTE: This could grow beyond the number of register classes when we map
471eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick    // register units to lists of unit sets. If the list of unit sets does not
472eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick    // already exist for a register class, we create a new entry in this vector.
473176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    std::vector<std::vector<unsigned> > RegClassUnitSets;
474176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick
475babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // Add RC to *2RC maps.
476babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    void addToMaps(CodeGenRegisterClass*);
477babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
4781b3d218880a7147caeb58f2604af1df26a409f7dJakob Stoklund Olesen    // Create a synthetic sub-class if it is missing.
4791b3d218880a7147caeb58f2604af1df26a409f7dJakob Stoklund Olesen    CodeGenRegisterClass *getOrCreateSubClass(const CodeGenRegisterClass *RC,
4801b3d218880a7147caeb58f2604af1df26a409f7dJakob Stoklund Olesen                                              const CodeGenRegister::Set *Membs,
4811b3d218880a7147caeb58f2604af1df26a409f7dJakob Stoklund Olesen                                              StringRef Name);
4821b3d218880a7147caeb58f2604af1df26a409f7dJakob Stoklund Olesen
483babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // Infer missing register classes.
484babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    void computeInferredRegisterClasses();
4857e56831a6804812b2295c5446a05f4ec457b6b3eJakob Stoklund Olesen    void inferCommonSubClass(CodeGenRegisterClass *RC);
486fec33444c5ca22e0338fdac0fcaee2644bd756afJakob Stoklund Olesen    void inferSubClassWithSubReg(CodeGenRegisterClass *RC);
487a9f65b9a1f57dcf546399ac32bf89d71d20df5b9Jakob Stoklund Olesen    void inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
488a9f65b9a1f57dcf546399ac32bf89d71d20df5b9Jakob Stoklund Olesen                                    unsigned FirstSubRegRC = 0);
4897b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen
490176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // Iteratively prune unit sets.
491176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    void pruneUnitSets();
492176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick
493d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    // Compute a weight for each register unit created during getSubRegs.
494d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    void computeRegUnitWeights();
495d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick
496176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // Create a RegUnitSet for each RegClass and infer superclasses.
497176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    void computeRegUnitSets();
498176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick
499b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Populate the Composite map from sub-register relationships.
500b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    void computeComposites();
501dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen
502a6035773d8d29827a124e65c258adbf0dcbb1a5aJakob Stoklund Olesen    // Compute a lane mask for each sub-register index.
503a6035773d8d29827a124e65c258adbf0dcbb1a5aJakob Stoklund Olesen    void computeSubRegIndexLaneMasks();
504a6035773d8d29827a124e65c258adbf0dcbb1a5aJakob Stoklund Olesen
505dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen  public:
506dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen    CodeGenRegBank(RecordKeeper&);
507dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen
50859f26aadce1bb985b9befe841fc106c891e1c728Jakob Stoklund Olesen    SetTheory &getSets() { return Sets; }
50959f26aadce1bb985b9befe841fc106c891e1c728Jakob Stoklund Olesen
510b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Sub-register indices. The first NumNamedIndices are defined by the user
511b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // in the .td files. The rest are synthesized such that all sub-registers
512b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // have a unique name.
5135fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    ArrayRef<CodeGenSubRegIndex*> getSubRegIndices() { return SubRegIndices; }
514dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen
5155fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    // Find a SubRegIndex form its Record def.
5165fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    CodeGenSubRegIndex *getSubRegIdx(Record*);
517dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen
518b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Find or create a sub-register index representing the A+B composition.
5195fcc156344e0d38fa5f5eab3d9193b859b27b45eJakob Stoklund Olesen    CodeGenSubRegIndex *getCompositeSubRegIndex(CodeGenSubRegIndex *A,
52090498b195ba759cf4f2a98da4e46fb9a2b580396Jakob Stoklund Olesen                                                CodeGenSubRegIndex *B);
521b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
522fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    // Find or create a sub-register index representing the concatenation of
523fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    // non-overlapping sibling indices.
524fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    CodeGenSubRegIndex *
525fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen      getConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex*, 8>&);
526fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen
527fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    void
528fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    addConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex*, 8> &Parts,
529fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen                         CodeGenSubRegIndex *Idx) {
530fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen      ConcatIdx.insert(std::make_pair(Parts, Idx));
531fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen    }
532fcad79671f22c8994663c6780862b9c38d3609c3Jakob Stoklund Olesen
533abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen    const std::vector<CodeGenRegister*> &getRegisters() { return Registers; }
534d2c699706ceae4a118a8dcafbef73b85093e5390Owen Anderson    const StringMap<CodeGenRegister*> &getRegistersByName() {
535d2c699706ceae4a118a8dcafbef73b85093e5390Owen Anderson      return RegistersByName;
536d2c699706ceae4a118a8dcafbef73b85093e5390Owen Anderson    }
537b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
538b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Find a register from its Record def.
539b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    CodeGenRegister *getReg(Record*);
540b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
541d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    // Get a Register's index into the Registers array.
542d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    unsigned getRegIndex(const CodeGenRegister *Reg) const {
543d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick      return Reg->EnumValue - 1;
544d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    }
545d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick
546b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    // Return the number of allocated TopoSigs. The first TopoSig representing
547b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    // leaf registers is allocated number 0.
548b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    unsigned getNumTopoSigs() const {
549b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen      return TopoSigs.size();
550b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    }
551b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen
552b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    // Find or create a TopoSig for the given TopoSigId.
553b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    // This function is only for use by CodeGenRegister::computeSuperRegs().
554b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    // Others should simply use Reg->getTopoSig().
555b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    unsigned getTopoSig(const TopoSigId &Id) {
556b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen      return TopoSigs.insert(std::make_pair(Id, TopoSigs.size())).first->second;
557b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen    }
558b81cbc271faed9fa633920436cd7ae49750a9a42Jakob Stoklund Olesen
55940c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    // Create a native register unit that is associated with one or two root
56040c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    // registers.
56140c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    unsigned newRegUnit(CodeGenRegister *R0, CodeGenRegister *R1 = 0) {
56240c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen      RegUnits.resize(RegUnits.size() + 1);
56340c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen      RegUnits.back().Roots[0] = R0;
56440c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen      RegUnits.back().Roots[1] = R1;
56540c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen      return RegUnits.size() - 1;
56640c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    }
56740c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen
568d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    // Create a new non-native register unit that can be adopted by a register
569d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    // to increase its pressure. Note that NumNativeRegUnits is not increased.
570d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    unsigned newRegUnit(unsigned Weight) {
57140c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen      RegUnits.resize(RegUnits.size() + 1);
57240c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen      RegUnits.back().Weight = Weight;
57340c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen      return RegUnits.size() - 1;
574d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    }
575d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick
576176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // Native units are the singular unit of a leaf register. Register aliasing
577176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // is completely characterized by native units. Adopted units exist to give
578176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // register additional weight but don't affect aliasing.
579d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    bool isNativeUnit(unsigned RUID) {
580d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick      return RUID < NumNativeRegUnits;
581d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    }
582dd9a50196cd75dbcb2bd604754cd62f8c1f30357Andrew Trick
583f52baf72c116d9cf8680d25a8e751ce354c7d44bJakob Stoklund Olesen    unsigned getNumNativeRegUnits() const {
584f52baf72c116d9cf8680d25a8e751ce354c7d44bJakob Stoklund Olesen      return NumNativeRegUnits;
585dee3be60292ecfafe584baf4ed84b634b8f4c7c7Benjamin Kramer    }
586f52baf72c116d9cf8680d25a8e751ce354c7d44bJakob Stoklund Olesen
58740c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    RegUnit &getRegUnit(unsigned RUID) { return RegUnits[RUID]; }
58840c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen    const RegUnit &getRegUnit(unsigned RUID) const { return RegUnits[RUID]; }
58940c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen
59029f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen    ArrayRef<CodeGenRegisterClass*> getRegClasses() const {
5917b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen      return RegClasses;
5927b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    }
5937b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen
5947b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    // Find a register class from its def.
5957b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    CodeGenRegisterClass *getRegClass(Record*);
5967b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen
5977b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    /// getRegisterClassForRegister - Find the register class that contains the
5987b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    /// specified physical register.  If the register is not in a register
5997b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    /// class, return null. If the register is in multiple classes, and the
6007b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    /// classes have a superset-subset relationship and the same set of types,
6017b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    /// return the superclass.  Otherwise return null.
6027b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    const CodeGenRegisterClass* getRegClassForRegister(Record *R);
6037b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen
604ec14cd7ddc66d47cd7927f18d8c11844c400367eAndrew Trick    // Get the sum of unit weights.
605ec14cd7ddc66d47cd7927f18d8c11844c400367eAndrew Trick    unsigned getRegUnitSetWeight(const std::vector<unsigned> &Units) const {
606ec14cd7ddc66d47cd7927f18d8c11844c400367eAndrew Trick      unsigned Weight = 0;
607ec14cd7ddc66d47cd7927f18d8c11844c400367eAndrew Trick      for (std::vector<unsigned>::const_iterator
608ec14cd7ddc66d47cd7927f18d8c11844c400367eAndrew Trick             I = Units.begin(), E = Units.end(); I != E; ++I)
60940c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen        Weight += getRegUnit(*I).Weight;
610ec14cd7ddc66d47cd7927f18d8c11844c400367eAndrew Trick      return Weight;
611ec14cd7ddc66d47cd7927f18d8c11844c400367eAndrew Trick    }
612ec14cd7ddc66d47cd7927f18d8c11844c400367eAndrew Trick
613176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // Increase a RegUnitWeight.
614d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    void increaseRegUnitWeight(unsigned RUID, unsigned Inc) {
61540c6fb397d1e485aef8b4e1729ba9804784990c1Jakob Stoklund Olesen      getRegUnit(RUID).Weight += Inc;
616d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick    }
617d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45Andrew Trick
618176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // Get the number of register pressure dimensions.
619176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    unsigned getNumRegPressureSets() const { return RegUnitSets.size(); }
620176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick
621176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // Get a set of register unit IDs for a given dimension of pressure.
622176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    RegUnitSet getRegPressureSet(unsigned Idx) const {
623176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick      return RegUnitSets[Idx];
624176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    }
625176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick
626eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick    // The number of pressure set lists may be larget than the number of
627eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick    // register classes if some register units appeared in a list of sets that
628eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick    // did not correspond to an existing register class.
629eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick    unsigned getNumRegClassPressureSetLists() const {
630eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick      return RegClassUnitSets.size();
631eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick    }
632eca1fcf3d2d8246c45648fea59bd21a4091f9115Andrew Trick
633176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // Get a list of pressure set IDs for a register class. Liveness of a
634176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // register in this class impacts each pressure set in this list by the
635176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // weight of the register. An exact solution requires all registers in a
636176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    // class to have the same class, but it is not strictly guaranteed.
637176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    ArrayRef<unsigned> getRCPressureSetIDs(unsigned RCIdx) const {
638176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick      return RegClassUnitSets[RCIdx];
639176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick    }
640176194d4ee2774bc135ababc5bd6c6c9f606b2a5Andrew Trick
641b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Computed derived records such as missing sub-register indices.
642b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    void computeDerivedInfo();
643026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen
644ec572539dd5660f9ca42027ac04df3a3f8c0cab1Jakob Stoklund Olesen    // Compute the set of registers completely covered by the registers in Regs.
645ec572539dd5660f9ca42027ac04df3a3f8c0cab1Jakob Stoklund Olesen    // The returned BitVector will have a bit set for each register in Regs,
646ec572539dd5660f9ca42027ac04df3a3f8c0cab1Jakob Stoklund Olesen    // all sub-registers, and all super-registers that are covered by the
647ec572539dd5660f9ca42027ac04df3a3f8c0cab1Jakob Stoklund Olesen    // registers in Regs.
648ec572539dd5660f9ca42027ac04df3a3f8c0cab1Jakob Stoklund Olesen    //
649ec572539dd5660f9ca42027ac04df3a3f8c0cab1Jakob Stoklund Olesen    // This is used to compute the mask of call-preserved registers from a list
650ec572539dd5660f9ca42027ac04df3a3f8c0cab1Jakob Stoklund Olesen    // of callee-saves.
651ec572539dd5660f9ca42027ac04df3a3f8c0cab1Jakob Stoklund Olesen    BitVector computeCoveredRegisters(ArrayRef<Record*> Regs);
652dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen  };
6538dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner}
6548dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner
6558dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner#endif
656