forked from OSchip/llvm-project
[TableGen] Allow target specific flags for RegisterClass
Analogous to the TSFlags for machine instructions, this patch introduces a bit vector for register classes to have target specific flags that become a tablegened value in TargetRegisterClass. Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D108767
This commit is contained in:
parent
89424a829f
commit
6a75041a16
|
@ -57,6 +57,8 @@ public:
|
|||
/// Classes with a higher priority value are assigned first by register
|
||||
/// allocators using a greedy heuristic. The value is in the range [0,63].
|
||||
const uint8_t AllocationPriority;
|
||||
/// Configurable target specific flags.
|
||||
const uint8_t TSFlags;
|
||||
/// Whether the class supports two (or more) disjunct subregister indices.
|
||||
const bool HasDisjunctSubRegs;
|
||||
/// Whether a combination of subregisters can cover every register in the
|
||||
|
|
|
@ -306,6 +306,9 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
|
|||
// the assembly matcher will provide a function to map from diagnostic types
|
||||
// to message strings.
|
||||
string DiagnosticString = "";
|
||||
|
||||
// Target-specific flags. This becomes the TSFlags field in TargetRegisterClass.
|
||||
bits<8> TSFlags = 0;
|
||||
}
|
||||
|
||||
// The memberList in a RegisterClass is a dag of set operations. TableGen
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// RUN: llvm-tblgen -gen-register-info -I %p/../../include -I %p/Common %s | FileCheck %s
|
||||
|
||||
// Configure and test TSFlags for a target.
|
||||
include "llvm/Target/Target.td"
|
||||
|
||||
let Namespace = "MyTarget" in {
|
||||
def R : Register<"r">;
|
||||
def D : Register<"d">;
|
||||
def S : Register<"s">;
|
||||
}
|
||||
|
||||
class MyClass <int size, list<ValueType> types, dag regList>
|
||||
: RegisterClass <"MyTarget", types, size, regList> {
|
||||
// Define the target bitfields.
|
||||
field bit A = 0;
|
||||
field bits<2> B = 0;
|
||||
|
||||
// Associate the defined bitfields to unique bit positions in TSFlags.
|
||||
let TSFlags{0} = A;
|
||||
let TSFlags{2-1} = B;
|
||||
}
|
||||
|
||||
// Default value for TSFlags.
|
||||
def MyRegs : MyClass<32, [i32], (add R)>;
|
||||
|
||||
def SRegs : MyClass<32, [i32], (add S)> {
|
||||
let A = 1;
|
||||
}
|
||||
|
||||
def DRegs : MyClass<32, [i32], (add D)>{
|
||||
let B = 3;
|
||||
}
|
||||
|
||||
def SDRegs : MyClass<32, [i32], (add D, S)>{
|
||||
let A = 1;
|
||||
let B = 3;
|
||||
}
|
||||
|
||||
def MyTarget : Target;
|
||||
|
||||
// CHECK: extern const TargetRegisterClass SDRegsRegClass = {
|
||||
// CHECK: 0x07, /* TSFlags */
|
||||
// CHECK: extern const TargetRegisterClass DRegsRegClass = {
|
||||
// CHECK: 0x06, /* TSFlags */
|
||||
// CHECK: extern const TargetRegisterClass MyRegsRegClass = {
|
||||
// CHECK: 0x00, /* TSFlags */
|
||||
// CHECK: extern const TargetRegisterClass SRegsRegClass = {
|
||||
// CHECK: 0x01, /* TSFlags */
|
|
@ -734,7 +734,7 @@ static void sortAndUniqueRegisters(CodeGenRegister::Vec &M) {
|
|||
|
||||
CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
|
||||
: TheDef(R), Name(std::string(R->getName())),
|
||||
TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1) {
|
||||
TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1), TSFlags(0) {
|
||||
GeneratePressureSet = R->getValueAsBit("GeneratePressureSet");
|
||||
std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes");
|
||||
if (TypeList.empty())
|
||||
|
@ -802,6 +802,12 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
|
|||
if (AllocationPriority < 0 || AllocationPriority > 63)
|
||||
PrintFatalError(R->getLoc(), "AllocationPriority out of range [0,63]");
|
||||
this->AllocationPriority = AllocationPriority;
|
||||
|
||||
BitsInit *TSF = R->getValueAsBitsInit("TSFlags");
|
||||
for (unsigned I = 0, E = TSF->getNumBits(); I != E; ++I) {
|
||||
BitInit *Bit = cast<BitInit>(TSF->getBit(I));
|
||||
TSFlags |= uint8_t(Bit->getValue()) << I;
|
||||
}
|
||||
}
|
||||
|
||||
// Create an inferred register class that was missing from the .td files.
|
||||
|
@ -811,7 +817,7 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
|
|||
StringRef Name, Key Props)
|
||||
: Members(*Props.Members), TheDef(nullptr), Name(std::string(Name)),
|
||||
TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1), RSI(Props.RSI),
|
||||
CopyCost(0), Allocatable(true), AllocationPriority(0) {
|
||||
CopyCost(0), Allocatable(true), AllocationPriority(0), TSFlags(0) {
|
||||
Artificial = true;
|
||||
GeneratePressureSet = false;
|
||||
for (const auto R : Members) {
|
||||
|
@ -839,6 +845,7 @@ void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) {
|
|||
});
|
||||
AltOrderSelect = Super.AltOrderSelect;
|
||||
AllocationPriority = Super.AllocationPriority;
|
||||
TSFlags = Super.TSFlags;
|
||||
GeneratePressureSet |= Super.GeneratePressureSet;
|
||||
|
||||
// Copy all allocation orders, filter out foreign registers from the larger
|
||||
|
|
|
@ -332,6 +332,7 @@ namespace llvm {
|
|||
bool Allocatable;
|
||||
StringRef AltOrderSelect;
|
||||
uint8_t AllocationPriority;
|
||||
uint8_t TSFlags;
|
||||
/// Contains the combination of the lane masks of all subregisters.
|
||||
LaneBitmask LaneMask;
|
||||
/// True if there are at least 2 subregisters which do not interfere.
|
||||
|
|
|
@ -1411,6 +1411,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||
<< SuperRegIdxSeqs.get(SuperRegIdxLists[RC.EnumValue]) << ",\n ";
|
||||
printMask(OS, RC.LaneMask);
|
||||
OS << ",\n " << (unsigned)RC.AllocationPriority << ",\n "
|
||||
<< format("0x%02x", RC.TSFlags) << ", /* TSFlags */\n "
|
||||
<< (RC.HasDisjunctSubRegs?"true":"false")
|
||||
<< ", /* HasDisjunctSubRegs */\n "
|
||||
<< (RC.CoveredBySubRegs?"true":"false")
|
||||
|
|
Loading…
Reference in New Issue