summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/utils/TableGen/CodeGenRegisters.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/utils/TableGen/CodeGenRegisters.h')
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenRegisters.h115
1 files changed, 83 insertions, 32 deletions
diff --git a/contrib/llvm/utils/TableGen/CodeGenRegisters.h b/contrib/llvm/utils/TableGen/CodeGenRegisters.h
index 09341f0..5edbf47 100644
--- a/contrib/llvm/utils/TableGen/CodeGenRegisters.h
+++ b/contrib/llvm/utils/TableGen/CodeGenRegisters.h
@@ -16,8 +16,11 @@
#define CODEGEN_REGISTERS_H
#include "Record.h"
+#include "SetTheory.h"
#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SetVector.h"
#include <cstdlib>
#include <map>
#include <string>
@@ -49,16 +52,44 @@ namespace llvm {
return SubRegs;
}
+ // Add sub-registers to OSet following a pre-order defined by the .td file.
+ void addSubRegsPreOrder(SetVector<CodeGenRegister*> &OSet) const;
+
+ // List of super-registers in topological order, small to large.
+ typedef std::vector<CodeGenRegister*> SuperRegList;
+
+ // Get the list of super-registers.
+ // This is only valid after computeDerivedInfo has visited all registers.
+ const SuperRegList &getSuperRegs() const {
+ assert(SubRegsComplete && "Must precompute sub-registers");
+ return SuperRegs;
+ }
+
+ // Order CodeGenRegister pointers by EnumValue.
+ struct Less {
+ bool operator()(const CodeGenRegister *A,
+ const CodeGenRegister *B) const {
+ return A->EnumValue < B->EnumValue;
+ }
+ };
+
+ // Canonically ordered set.
+ typedef std::set<const CodeGenRegister*, Less> Set;
+
private:
bool SubRegsComplete;
SubRegMap SubRegs;
+ SuperRegList SuperRegs;
};
- struct CodeGenRegisterClass {
+ class CodeGenRegisterClass {
+ CodeGenRegister::Set Members;
+ const std::vector<Record*> *Elements;
+ std::vector<SmallVector<Record*, 16> > AltOrders;
+ public:
Record *TheDef;
std::string Namespace;
- std::vector<Record*> Elements;
std::vector<MVT::SimpleValueType> VTs;
unsigned SpillSize;
unsigned SpillAlignment;
@@ -66,7 +97,7 @@ namespace llvm {
bool Allocatable;
// Map SubRegIndex -> RegisterClass
DenseMap<Record*,Record*> SubRegClasses;
- std::string MethodProtos, MethodBodies;
+ std::string AltOrderSelect;
const std::string &getName() const;
const std::vector<MVT::SimpleValueType> &getValueTypes() const {return VTs;}
@@ -79,13 +110,10 @@ namespace llvm {
abort();
}
- bool containsRegister(Record *R) const {
- for (unsigned i = 0, e = Elements.size(); i != e; ++i)
- if (Elements[i] == R) return true;
- return false;
- }
+ // Return true if this this class contains the register.
+ bool contains(const CodeGenRegister*) const;
- // Returns true if RC is a strict subclass.
+ // Returns true if RC is a subclass.
// RC is a sub-class of this class if it is a valid replacement for any
// instruction operand where a register of this classis required. It must
// satisfy these conditions:
@@ -94,40 +122,38 @@ namespace llvm {
// 2. The RC spill size must not be smaller than our spill size.
// 3. RC spill alignment must be compatible with ours.
//
- bool hasSubClass(const CodeGenRegisterClass *RC) const {
-
- if (RC->Elements.size() > Elements.size() ||
- (SpillAlignment && RC->SpillAlignment % SpillAlignment) ||
- SpillSize > RC->SpillSize)
- return false;
-
- std::set<Record*> RegSet;
- for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
- Record *Reg = Elements[i];
- RegSet.insert(Reg);
- }
-
- for (unsigned i = 0, e = RC->Elements.size(); i != e; ++i) {
- Record *Reg = RC->Elements[i];
- if (!RegSet.count(Reg))
- return false;
- }
-
- return true;
+ bool hasSubClass(const CodeGenRegisterClass *RC) const;
+
+ // Returns an ordered list of class members.
+ // The order of registers is the same as in the .td file.
+ // No = 0 is the default allocation order, No = 1 is the first alternative.
+ ArrayRef<Record*> getOrder(unsigned No = 0) const {
+ if (No == 0)
+ return *Elements;
+ else
+ return AltOrders[No - 1];
}
- CodeGenRegisterClass(Record *R);
+ // Return the total number of allocation orders available.
+ unsigned getNumOrders() const { return 1 + AltOrders.size(); }
+
+ CodeGenRegisterClass(CodeGenRegBank&, Record *R);
};
// CodeGenRegBank - Represent a target's registers and the relations between
// them.
class CodeGenRegBank {
RecordKeeper &Records;
+ SetTheory Sets;
+
std::vector<Record*> SubRegIndices;
unsigned NumNamedIndices;
- std::vector<CodeGenRegister> Registers;
+ std::vector<CodeGenRegister*> Registers;
DenseMap<Record*, CodeGenRegister*> Def2Reg;
+ std::vector<CodeGenRegisterClass> RegClasses;
+ DenseMap<Record*, CodeGenRegisterClass*> Def2RC;
+
// Composite SubRegIndex instances.
// Map (SubRegIndex, SubRegIndex) -> SubRegIndex.
typedef DenseMap<std::pair<Record*, Record*>, Record*> CompositeMap;
@@ -139,6 +165,8 @@ namespace llvm {
public:
CodeGenRegBank(RecordKeeper&);
+ SetTheory &getSets() { return Sets; }
+
// Sub-register indices. The first NumNamedIndices are defined by the user
// in the .td files. The rest are synthesized such that all sub-registers
// have a unique name.
@@ -151,13 +179,36 @@ namespace llvm {
// Find or create a sub-register index representing the A+B composition.
Record *getCompositeSubRegIndex(Record *A, Record *B, bool create = false);
- const std::vector<CodeGenRegister> &getRegisters() { return Registers; }
+ const std::vector<CodeGenRegister*> &getRegisters() { return Registers; }
// Find a register from its Record def.
CodeGenRegister *getReg(Record*);
+ const std::vector<CodeGenRegisterClass> &getRegClasses() {
+ return RegClasses;
+ }
+
+ // Find a register class from its def.
+ CodeGenRegisterClass *getRegClass(Record*);
+
+ /// getRegisterClassForRegister - Find the register class that contains the
+ /// specified physical register. If the register is not in a register
+ /// class, return null. If the register is in multiple classes, and the
+ /// classes have a superset-subset relationship and the same set of types,
+ /// return the superclass. Otherwise return null.
+ const CodeGenRegisterClass* getRegClassForRegister(Record *R);
+
// Computed derived records such as missing sub-register indices.
void computeDerivedInfo();
+
+ // Compute full overlap sets for every register. These sets include the
+ // rarely used aliases that are neither sub nor super-registers.
+ //
+ // Map[R1].count(R2) is reflexive and symmetric, but not transitive.
+ //
+ // If R1 is a sub-register of R2, Map[R1] is a subset of Map[R2].
+ void computeOverlaps(std::map<const CodeGenRegister*,
+ CodeGenRegister::Set> &Map);
};
}
OpenPOWER on IntegriCloud