diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-10-04 15:28:49 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-10-04 15:28:49 +0000 |
commit | babf0569e2e4f204f9a304416cc4acc349d8f836 (patch) | |
tree | a47b47efc8a5d4334c3f5bf0ace78ee018f7e141 /utils/TableGen/CodeGenRegisters.h | |
parent | 01faf432d9d81212b492f326594d43a951fe64f0 (diff) | |
download | llvm-babf0569e2e4f204f9a304416cc4acc349d8f836.tar.gz llvm-babf0569e2e4f204f9a304416cc4acc349d8f836.tar.bz2 llvm-babf0569e2e4f204f9a304416cc4acc349d8f836.tar.xz |
Teach TableGen to infer missing register classes.
The set of register classes should be closed under sub-register
operations and intersections. That will allow the register allocator to
model combinations of constraints accurately.
This patch implements the easiest form of register class inference: For
every register class, and for every sub-register SubIdx, the subset of
registers in RC that have a SubIdx sub-register should also be a register
class.
This does create some new register classes for the targets in the tree:
ARM gets a new QQQQPR_with_ssub_0. This class was omitted from the .td
file on purpose because it only has two registers. InstrEmitter and
RegisterCoalescer have safeguards against selecting too small register
classes, so it is harmless.
PowerPC gets a G8RC_with_sub_32 class because LR is not a sub_32
sub-register of LR8. I think that might be an omission?
X86 puts RIP in the GR64 class, and since that register doesn't have
8-bit sub-registers, we get:
GR64_with_sub_8bit
GR64_TC_with_sub_8bit
GR64_NOREX_with_sub_8bit
GR64_TC_with_sub_8bit_hi
The various CodeGen classes have already been fixed so adding new
register classes should not affect compile time.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141084 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen/CodeGenRegisters.h')
-rw-r--r-- | utils/TableGen/CodeGenRegisters.h | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index 6e8d6c04e0..72c8ac0502 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -70,6 +70,7 @@ namespace llvm { struct Less { bool operator()(const CodeGenRegister *A, const CodeGenRegister *B) const { + assert(A && B); return A->EnumValue < B->EnumValue; } }; @@ -95,6 +96,11 @@ namespace llvm { SmallVector<CodeGenRegisterClass*, 4> SuperClasses; Record *TheDef; std::string Name; + + // For a synthesized class, inherit missing properties from the nearest + // super-class. + void inheritProperties(CodeGenRegBank&); + public: unsigned EnumValue; std::string Namespace; @@ -166,8 +172,36 @@ namespace llvm { CodeGenRegisterClass(CodeGenRegBank&, Record *R); + // A key representing the parts of a register class used for forming + // sub-classes. Note the ordering provided by this key is not the same as + // the topological order used for the EnumValues. + struct Key { + const CodeGenRegister::Set *Members; + unsigned SpillSize; + unsigned SpillAlignment; + + Key(const Key &O) + : Members(O.Members), + SpillSize(O.SpillSize), + SpillAlignment(O.SpillAlignment) {} + + Key(const CodeGenRegister::Set *M, unsigned S = 0, unsigned A = 0) + : Members(M), SpillSize(S), SpillAlignment(A) {} + + Key(const CodeGenRegisterClass &RC) + : Members(&RC.getMembers()), + SpillSize(RC.SpillSize), + SpillAlignment(RC.SpillAlignment) {} + + // Lexicographical order of (Members, SpillSize, SpillAlignment). + bool operator<(const Key&) const; + }; + + // Create a non-user defined register class. + CodeGenRegisterClass(StringRef Name, Key Props); + // Called by CodeGenRegBank::CodeGenRegBank(). - static void computeSubClasses(ArrayRef<CodeGenRegisterClass*>); + static void computeSubClasses(CodeGenRegBank&); }; // CodeGenRegBank - Represent a target's registers and the relations between @@ -181,8 +215,17 @@ namespace llvm { std::vector<CodeGenRegister*> Registers; DenseMap<Record*, CodeGenRegister*> Def2Reg; + // Register classes. std::vector<CodeGenRegisterClass*> RegClasses; DenseMap<Record*, CodeGenRegisterClass*> Def2RC; + typedef std::map<CodeGenRegisterClass::Key, CodeGenRegisterClass*> RCKeyMap; + RCKeyMap Key2RC; + + // Add RC to *2RC maps. + void addToMaps(CodeGenRegisterClass*); + + // Infer missing register classes. + void computeInferredRegisterClasses(); // Composite SubRegIndex instances. // Map (SubRegIndex, SubRegIndex) -> SubRegIndex. |