CodeGenRegisters.h revision fec33444c5ca22e0338fdac0fcaee2644bd756af
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"
197c788888872233748da10a8177a9a1eb176c1bc8Peter Collingbourne#include "llvm/TableGen/Record.h"
20ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov#include "llvm/CodeGen/ValueTypes.h"
21ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen#include "llvm/ADT/ArrayRef.h"
22203e0b17dd6049d64cb4ed7c4da09747204e6463Jakob Stoklund Olesen#include "llvm/ADT/BitVector.h"
2309bc0298650c76db1a06e20ca84c1dcb34071600Jakob Stoklund Olesen#include "llvm/ADT/DenseMap.h"
24026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen#include "llvm/ADT/SetVector.h"
25b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen#include <cstdlib>
26b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen#include <map>
278dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner#include <string>
28a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher#include <set>
29b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen#include <vector>
308dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner
318dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattnernamespace llvm {
32b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen  class CodeGenRegBank;
338dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner
348dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner  /// CodeGenRegister - Represents a register definition.
358dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner  struct CodeGenRegister {
368dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner    Record *TheDef;
3717fad045cccf34822d3163ada9e70a8f4528746eJim Grosbach    unsigned EnumValue;
386bfba2e5af163442a1c6b11fe14aa9df9101cfd7Jakob Stoklund Olesen    unsigned CostPerUse;
39b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
40b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Map SubRegIndex -> Register.
41b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    typedef std::map<Record*, CodeGenRegister*, LessRecord> SubRegMap;
42b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
43b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    CodeGenRegister(Record *R, unsigned Enum);
44b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
45b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    const std::string &getName() const;
46b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
47b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Get a map of sub-registers computed lazily.
48b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // This includes unique entries for all sub-sub-registers.
49b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    const SubRegMap &getSubRegs(CodeGenRegBank&);
50b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
51b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    const SubRegMap &getSubRegs() const {
52b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen      assert(SubRegsComplete && "Must precompute sub-registers");
53b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen      return SubRegs;
54b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    }
55b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
56026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    // Add sub-registers to OSet following a pre-order defined by the .td file.
57026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    void addSubRegsPreOrder(SetVector<CodeGenRegister*> &OSet) const;
58026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen
59026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    // List of super-registers in topological order, small to large.
60026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    typedef std::vector<CodeGenRegister*> SuperRegList;
61026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen
62026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    // Get the list of super-registers.
63026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    // This is only valid after computeDerivedInfo has visited all registers.
64026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    const SuperRegList &getSuperRegs() const {
65026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen      assert(SubRegsComplete && "Must precompute sub-registers");
66026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen      return SuperRegs;
67026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    }
68026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen
69026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    // Order CodeGenRegister pointers by EnumValue.
70026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    struct Less {
71ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen      bool operator()(const CodeGenRegister *A,
72ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen                      const CodeGenRegister *B) const {
73babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen        assert(A && B);
74026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen        return A->EnumValue < B->EnumValue;
75026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen      }
76026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    };
77026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen
78026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    // Canonically ordered set.
79ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    typedef std::set<const CodeGenRegister*, Less> Set;
80026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen
81b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen  private:
82b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    bool SubRegsComplete;
83b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    SubRegMap SubRegs;
84026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    SuperRegList SuperRegs;
858dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner  };
868dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner
878dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner
88ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen  class CodeGenRegisterClass {
89ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    CodeGenRegister::Set Members;
90cc0c975b7db95ce6bc865c56a3016bf0d4f83304Jakob Stoklund Olesen    // Allocation orders. Order[0] always contains all registers in Members.
91cc0c975b7db95ce6bc865c56a3016bf0d4f83304Jakob Stoklund Olesen    std::vector<SmallVector<Record*, 16> > Orders;
92203e0b17dd6049d64cb4ed7c4da09747204e6463Jakob Stoklund Olesen    // Bit mask of sub-classes including this, indexed by their EnumValue.
93203e0b17dd6049d64cb4ed7c4da09747204e6463Jakob Stoklund Olesen    BitVector SubClasses;
94f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    // List of super-classes, topologocally ordered to have the larger classes
95f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    // first.  This is the same as sorting by EnumValue.
96f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    SmallVector<CodeGenRegisterClass*, 4> SuperClasses;
97056afeface2ac98664ed8fa4799b46178a4a6fe3Chris Lattner    Record *TheDef;
986fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    std::string Name;
99babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
100babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // For a synthesized class, inherit missing properties from the nearest
101babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // super-class.
102babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    void inheritProperties(CodeGenRegBank&);
103babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
104845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen    // Map SubRegIndex -> sub-class
105845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen    DenseMap<Record*, CodeGenRegisterClass*> SubClassWithSubReg;
106845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen
1076fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen  public:
1087dcaa5b0fb56468e774044d3b887c21b2d484a1cJakob Stoklund Olesen    unsigned EnumValue;
109c67c18fd2378fd2394c42f12b67897e7eba02d5cChris Lattner    std::string Namespace;
110825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    std::vector<MVT::SimpleValueType> VTs;
111056afeface2ac98664ed8fa4799b46178a4a6fe3Chris Lattner    unsigned SpillSize;
112056afeface2ac98664ed8fa4799b46178a4a6fe3Chris Lattner    unsigned SpillAlignment;
113a3ca3149f2b59c512c50aab330b5a0d8efddeffaEvan Cheng    int CopyCost;
114f462e3fac7ac67503657d63dc35330d0b19359b3Jakob Stoklund Olesen    bool Allocatable;
11509bc0298650c76db1a06e20ca84c1dcb34071600Jakob Stoklund Olesen    // Map SubRegIndex -> RegisterClass
11609bc0298650c76db1a06e20ca84c1dcb34071600Jakob Stoklund Olesen    DenseMap<Record*,Record*> SubRegClasses;
11754c47c1ce94b9e549ef768e80fd004788d13ce85Jakob Stoklund Olesen    std::string AltOrderSelect;
118056afeface2ac98664ed8fa4799b46178a4a6fe3Chris Lattner
1196fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    // Return the Record that defined this class, or NULL if the class was
1206fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    // created by TableGen.
1216fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    Record *getDef() const { return TheDef; }
1226fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen
1236fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    const std::string &getName() const { return Name; }
1246fea31e7300fe012b0b2984d6bc0338d02b054d3Jakob Stoklund Olesen    std::string getQualifiedName() const;
125825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    const std::vector<MVT::SimpleValueType> &getValueTypes() const {return VTs;}
1265c4736a3da04795ba8d04e152e151afd6942e2f1Chris Lattner    unsigned getNumValueTypes() const { return VTs.size(); }
1275d4314ef720630e6547fe41efec1608d4c14c78eJim Grosbach
128825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    MVT::SimpleValueType getValueTypeNum(unsigned VTNum) const {
1296510b22cec7de4f0acc9965ec24c3668a6a8a87eNate Begeman      if (VTNum < VTs.size())
1306510b22cec7de4f0acc9965ec24c3668a6a8a87eNate Begeman        return VTs[VTNum];
1316510b22cec7de4f0acc9965ec24c3668a6a8a87eNate Begeman      assert(0 && "VTNum greater than number of ValueTypes in RegClass!");
1326510b22cec7de4f0acc9965ec24c3668a6a8a87eNate Begeman      abort();
1336510b22cec7de4f0acc9965ec24c3668a6a8a87eNate Begeman    }
1345d4314ef720630e6547fe41efec1608d4c14c78eJim Grosbach
135ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    // Return true if this this class contains the register.
136ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    bool contains(const CodeGenRegister*) const;
1375d4314ef720630e6547fe41efec1608d4c14c78eJim Grosbach
138ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    // Returns true if RC is a subclass.
139a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    // RC is a sub-class of this class if it is a valid replacement for any
1405d4314ef720630e6547fe41efec1608d4c14c78eJim Grosbach    // instruction operand where a register of this classis required. It must
141a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    // satisfy these conditions:
142a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    //
143a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    // 1. All RC registers are also in this.
144a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    // 2. The RC spill size must not be smaller than our spill size.
145a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    // 3. RC spill alignment must be compatible with ours.
146a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    //
14752e7dfadc65257f05480de6e70da00373a8954d1Jakob Stoklund Olesen    bool hasSubClass(const CodeGenRegisterClass *RC) const {
14852e7dfadc65257f05480de6e70da00373a8954d1Jakob Stoklund Olesen      return SubClasses.test(RC->EnumValue);
14952e7dfadc65257f05480de6e70da00373a8954d1Jakob Stoklund Olesen    }
150a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher
151845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen    // getSubClassWithSubReg - Returns the largest sub-class where all
152845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen    // registers have a SubIdx sub-register.
153845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen    CodeGenRegisterClass *getSubClassWithSubReg(Record *SubIdx) const {
154845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen      return SubClassWithSubReg.lookup(SubIdx);
155845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen    }
156845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen
157845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen    void setSubClassWithSubReg(Record *SubIdx, CodeGenRegisterClass *SubRC) {
158845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen      SubClassWithSubReg[SubIdx] = SubRC;
159845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen    }
160845d2c0c776abce551d16f7b1b7dc1f4d4df1a27Jakob Stoklund Olesen
161f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    // getSubClasses - Returns a constant BitVector of subclasses indexed by
162f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    // EnumValue.
163f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    // The SubClasses vector includs an entry for this class.
164830378f6628ad3af1d0293a0b605065532f99e43Eli Friedman    const BitVector &getSubClasses() const { return SubClasses; }
165f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen
166f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    // getSuperClasses - Returns a list of super classes ordered by EnumValue.
167f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    // The array does not include an entry for this class.
168f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    ArrayRef<CodeGenRegisterClass*> getSuperClasses() const {
169f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen      return SuperClasses;
170f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen    }
171f9a4bb78dadc12c7c1e604c6f17b63a71305c2caJakob Stoklund Olesen
172ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    // Returns an ordered list of class members.
173ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    // The order of registers is the same as in the .td file.
174b4c704877d1600852a55ab7bef2918a7c0af5e0dJakob Stoklund Olesen    // No = 0 is the default allocation order, No = 1 is the first alternative.
175b4c704877d1600852a55ab7bef2918a7c0af5e0dJakob Stoklund Olesen    ArrayRef<Record*> getOrder(unsigned No = 0) const {
176cc0c975b7db95ce6bc865c56a3016bf0d4f83304Jakob Stoklund Olesen        return Orders[No];
177a2c9188560eb9a7d494960fefd28cf0998d9a78fEric Christopher    }
1786510b22cec7de4f0acc9965ec24c3668a6a8a87eNate Begeman
179b4c704877d1600852a55ab7bef2918a7c0af5e0dJakob Stoklund Olesen    // Return the total number of allocation orders available.
180cc0c975b7db95ce6bc865c56a3016bf0d4f83304Jakob Stoklund Olesen    unsigned getNumOrders() const { return Orders.size(); }
181b4c704877d1600852a55ab7bef2918a7c0af5e0dJakob Stoklund Olesen
18252e7dfadc65257f05480de6e70da00373a8954d1Jakob Stoklund Olesen    // Get the set of registers.  This set contains the same registers as
18352e7dfadc65257f05480de6e70da00373a8954d1Jakob Stoklund Olesen    // getOrder(0).
18452e7dfadc65257f05480de6e70da00373a8954d1Jakob Stoklund Olesen    const CodeGenRegister::Set &getMembers() const { return Members; }
18552e7dfadc65257f05480de6e70da00373a8954d1Jakob Stoklund Olesen
186ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen    CodeGenRegisterClass(CodeGenRegBank&, Record *R);
187203e0b17dd6049d64cb4ed7c4da09747204e6463Jakob Stoklund Olesen
188babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // A key representing the parts of a register class used for forming
189babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // sub-classes.  Note the ordering provided by this key is not the same as
190babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // the topological order used for the EnumValues.
191babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    struct Key {
192babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      const CodeGenRegister::Set *Members;
193babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      unsigned SpillSize;
194babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      unsigned SpillAlignment;
195babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
196babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      Key(const Key &O)
197babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen        : Members(O.Members),
198babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen          SpillSize(O.SpillSize),
199babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen          SpillAlignment(O.SpillAlignment) {}
200babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
201babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      Key(const CodeGenRegister::Set *M, unsigned S = 0, unsigned A = 0)
202babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen        : Members(M), SpillSize(S), SpillAlignment(A) {}
203babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
204babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      Key(const CodeGenRegisterClass &RC)
205babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen        : Members(&RC.getMembers()),
206babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen          SpillSize(RC.SpillSize),
207babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen          SpillAlignment(RC.SpillAlignment) {}
208babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
209babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      // Lexicographical order of (Members, SpillSize, SpillAlignment).
210babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen      bool operator<(const Key&) const;
211babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    };
212babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
213babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // Create a non-user defined register class.
214babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    CodeGenRegisterClass(StringRef Name, Key Props);
215babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
216203e0b17dd6049d64cb4ed7c4da09747204e6463Jakob Stoklund Olesen    // Called by CodeGenRegBank::CodeGenRegBank().
217babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    static void computeSubClasses(CodeGenRegBank&);
2188dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner  };
219dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen
220dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen  // CodeGenRegBank - Represent a target's registers and the relations between
221dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen  // them.
222dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen  class CodeGenRegBank {
223dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen    RecordKeeper &Records;
22459f26aadce1bb985b9befe841fc106c891e1c728Jakob Stoklund Olesen    SetTheory Sets;
22559f26aadce1bb985b9befe841fc106c891e1c728Jakob Stoklund Olesen
226dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen    std::vector<Record*> SubRegIndices;
227dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen    unsigned NumNamedIndices;
228abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen    std::vector<CodeGenRegister*> Registers;
229b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    DenseMap<Record*, CodeGenRegister*> Def2Reg;
230b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
231babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // Register classes.
23229f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen    std::vector<CodeGenRegisterClass*> RegClasses;
2337b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    DenseMap<Record*, CodeGenRegisterClass*> Def2RC;
234babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    typedef std::map<CodeGenRegisterClass::Key, CodeGenRegisterClass*> RCKeyMap;
235babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    RCKeyMap Key2RC;
236babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
237babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // Add RC to *2RC maps.
238babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    void addToMaps(CodeGenRegisterClass*);
239babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen
2401b3d218880a7147caeb58f2604af1df26a409f7dJakob Stoklund Olesen    // Create a synthetic sub-class if it is missing.
2411b3d218880a7147caeb58f2604af1df26a409f7dJakob Stoklund Olesen    CodeGenRegisterClass *getOrCreateSubClass(const CodeGenRegisterClass *RC,
2421b3d218880a7147caeb58f2604af1df26a409f7dJakob Stoklund Olesen                                              const CodeGenRegister::Set *Membs,
2431b3d218880a7147caeb58f2604af1df26a409f7dJakob Stoklund Olesen                                              StringRef Name);
2441b3d218880a7147caeb58f2604af1df26a409f7dJakob Stoklund Olesen
245babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    // Infer missing register classes.
246babf0569e2e4f204f9a304416cc4acc349d8f836Jakob Stoklund Olesen    void computeInferredRegisterClasses();
2477e56831a6804812b2295c5446a05f4ec457b6b3eJakob Stoklund Olesen    void inferCommonSubClass(CodeGenRegisterClass *RC);
248fec33444c5ca22e0338fdac0fcaee2644bd756afJakob Stoklund Olesen    void inferSubClassWithSubReg(CodeGenRegisterClass *RC);
2497b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen
250b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Composite SubRegIndex instances.
251b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Map (SubRegIndex, SubRegIndex) -> SubRegIndex.
252b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    typedef DenseMap<std::pair<Record*, Record*>, Record*> CompositeMap;
253b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    CompositeMap Composite;
254b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
255b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Populate the Composite map from sub-register relationships.
256b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    void computeComposites();
257dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen
258dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen  public:
259dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen    CodeGenRegBank(RecordKeeper&);
260dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen
26159f26aadce1bb985b9befe841fc106c891e1c728Jakob Stoklund Olesen    SetTheory &getSets() { return Sets; }
26259f26aadce1bb985b9befe841fc106c891e1c728Jakob Stoklund Olesen
263b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Sub-register indices. The first NumNamedIndices are defined by the user
264b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // in the .td files. The rest are synthesized such that all sub-registers
265b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // have a unique name.
266dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen    const std::vector<Record*> &getSubRegIndices() { return SubRegIndices; }
267dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen    unsigned getNumNamedIndices() { return NumNamedIndices; }
268dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen
269dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen    // Map a SubRegIndex Record to its enum value.
270dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen    unsigned getSubRegIndexNo(Record *idx);
271dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen
272b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Find or create a sub-register index representing the A+B composition.
273b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    Record *getCompositeSubRegIndex(Record *A, Record *B, bool create = false);
274b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
275abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen    const std::vector<CodeGenRegister*> &getRegisters() { return Registers; }
276b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
277b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Find a register from its Record def.
278b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    CodeGenRegister *getReg(Record*);
279b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen
28029f018cee616e4082e5005bc9adee4dc777e621cJakob Stoklund Olesen    ArrayRef<CodeGenRegisterClass*> getRegClasses() const {
2817b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen      return RegClasses;
2827b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    }
2837b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen
2847b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    // Find a register class from its def.
2857b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    CodeGenRegisterClass *getRegClass(Record*);
2867b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen
2877b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    /// getRegisterClassForRegister - Find the register class that contains the
2887b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    /// specified physical register.  If the register is not in a register
2897b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    /// class, return null. If the register is in multiple classes, and the
2907b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    /// classes have a superset-subset relationship and the same set of types,
2917b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    /// return the superclass.  Otherwise return null.
2927b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen    const CodeGenRegisterClass* getRegClassForRegister(Record *R);
2937b9cafde5e3faec22bbfbbc90cca0876968abad9Jakob Stoklund Olesen
294b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    // Computed derived records such as missing sub-register indices.
295b5923db192d2aa938ff3c12aaac87d80ab649625Jakob Stoklund Olesen    void computeDerivedInfo();
296026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen
297026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    // Compute full overlap sets for every register. These sets include the
298026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    // rarely used aliases that are neither sub nor super-registers.
299026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    //
300026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    // Map[R1].count(R2) is reflexive and symmetric, but not transitive.
301026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    //
302026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    // If R1 is a sub-register of R2, Map[R1] is a subset of Map[R2].
303026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen    void computeOverlaps(std::map<const CodeGenRegister*,
304026dc223aeef2579d63f395007491e37d6cde3a0Jakob Stoklund Olesen                                  CodeGenRegister::Set> &Map);
305dc29c447136aabf05f48a7119e48065c3b4cee9bJakob Stoklund Olesen  };
3068dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner}
3078dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner
3088dab6ca9c638709e7b60b942107ab88b3ef7d06dChris Lattner#endif
309