Move some sub-register index calculations to CodeGenRegisters.cpp
[oota-llvm.git] / utils / TableGen / CodeGenRegisters.h
1 //===- CodeGenRegisters.h - Register and RegisterClass Info -----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines structures to encapsulate information gleaned from the
11 // target register and register class definitions.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef CODEGEN_REGISTERS_H
16 #define CODEGEN_REGISTERS_H
17
18 #include "llvm/CodeGen/ValueTypes.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include <string>
21 #include <vector>
22 #include <set>
23 #include <cstdlib>
24
25 namespace llvm {
26   class Record;
27   class RecordKeeper;
28
29   /// CodeGenRegister - Represents a register definition.
30   struct CodeGenRegister {
31     Record *TheDef;
32     const std::string &getName() const;
33     unsigned EnumValue;
34     unsigned CostPerUse;
35     CodeGenRegister(Record *R);
36   };
37
38
39   struct CodeGenRegisterClass {
40     Record *TheDef;
41     std::string Namespace;
42     std::vector<Record*> Elements;
43     std::vector<MVT::SimpleValueType> VTs;
44     unsigned SpillSize;
45     unsigned SpillAlignment;
46     int CopyCost;
47     bool Allocatable;
48     // Map SubRegIndex -> RegisterClass
49     DenseMap<Record*,Record*> SubRegClasses;
50     std::string MethodProtos, MethodBodies;
51
52     const std::string &getName() const;
53     const std::vector<MVT::SimpleValueType> &getValueTypes() const {return VTs;}
54     unsigned getNumValueTypes() const { return VTs.size(); }
55
56     MVT::SimpleValueType getValueTypeNum(unsigned VTNum) const {
57       if (VTNum < VTs.size())
58         return VTs[VTNum];
59       assert(0 && "VTNum greater than number of ValueTypes in RegClass!");
60       abort();
61     }
62
63     bool containsRegister(Record *R) const {
64       for (unsigned i = 0, e = Elements.size(); i != e; ++i)
65         if (Elements[i] == R) return true;
66       return false;
67     }
68
69     // Returns true if RC is a strict subclass.
70     // RC is a sub-class of this class if it is a valid replacement for any
71     // instruction operand where a register of this classis required. It must
72     // satisfy these conditions:
73     //
74     // 1. All RC registers are also in this.
75     // 2. The RC spill size must not be smaller than our spill size.
76     // 3. RC spill alignment must be compatible with ours.
77     //
78     bool hasSubClass(const CodeGenRegisterClass *RC) const {
79
80       if (RC->Elements.size() > Elements.size() ||
81           (SpillAlignment && RC->SpillAlignment % SpillAlignment) ||
82           SpillSize > RC->SpillSize)
83         return false;
84
85       std::set<Record*> RegSet;
86       for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
87         Record *Reg = Elements[i];
88         RegSet.insert(Reg);
89       }
90
91       for (unsigned i = 0, e = RC->Elements.size(); i != e; ++i) {
92         Record *Reg = RC->Elements[i];
93         if (!RegSet.count(Reg))
94           return false;
95       }
96
97       return true;
98     }
99
100     CodeGenRegisterClass(Record *R);
101   };
102
103   // CodeGenRegBank - Represent a target's registers and the relations between
104   // them.
105   class CodeGenRegBank {
106     RecordKeeper &Records;
107
108     // Sub-register indices. The first NumNamedIndices are defined by the user
109     // in the .td files. The rest are synthesized such that all sub-registers
110     // have a unique name.
111     std::vector<Record*> SubRegIndices;
112
113     unsigned NumNamedIndices;
114
115   public:
116     CodeGenRegBank(RecordKeeper&);
117
118     const std::vector<Record*> &getSubRegIndices() { return SubRegIndices; }
119
120     unsigned getNumNamedIndices() { return NumNamedIndices; }
121
122     // Map a SubRegIndex Record to its enum value.
123     unsigned getSubRegIndexNo(Record *idx);
124
125     // Create a new sub-register index representing the A+B composition.
126     Record *getCompositeSubRegIndex(Record *A, Record *B);
127   };
128 }
129
130 #endif