Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions llvm/test/TableGen/RegisterInfoEmitter-inherit-properties.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// RUN: llvm-tblgen -gen-register-info -I %p/../../include -I %p/Common %s | FileCheck %s

// This file tests that a synthesized sub-regclass can inherit properties, e.g.,
// tsflags in this case, from the correct super-regclass.

include "llvm/Target/Target.td"

class MyReg<string n, list<Register> subregs = []>
: Register<n> {
let Namespace = "Test";
let SubRegs = subregs;
let CoveredBySubRegs = 1;
}

class MyClass<int align, list<ValueType> types, dag registers>
: RegisterClass<"Test", types, align, registers> {
field bit isA = 0;
field bit isB = 0;
let TSFlags{0} = isA;
let TSFlags{1} = isB;
}

def sub0 : SubRegIndex<32, 0>;
def sub1 : SubRegIndex<32, 32>;
def sub2 : SubRegIndex<32, 64>;

foreach Num=0-7 in {
def A#Num : MyReg<"a"#Num>;
}

foreach Num=0-3 in {
def B#Num : MyReg<"b"#Num>;
}

class AClass<int align, list<ValueType> types, dag registers>
: MyClass<align, types, registers> {
let isA = 1;
}

class BClass<int align, list<ValueType> types, dag registers>
: MyClass<align, types, registers> {
let isB = 1;
}

def APair : RegisterTuples<[sub0, sub1],
[(add A0, A2, A4, A6), (add A1, A3, A5, A7)]>;
def BPair : RegisterTuples<[sub0, sub1],
[(add B0, B2), (add B1, B3)]>;
def ARC2 : AClass<32, [untyped], (add APair)>;
def BRC2 : BClass<32, [untyped], (add BPair)>;
def ABRC2 : MyClass<32, [untyped], (add ARC2, BRC2)> {
let isAllocatable = 0;
}

def ATuple : RegisterTuples<[sub0, sub1, sub2],
[(add A0, A1, A2, A3, A4, A5),
(add A1, A2, A3, A4, A5, A6),
(add A2, A3, A4, A5, A6, A7)]>;

def BTuple : RegisterTuples<[sub0, sub1, sub2],
[(add B0, B1), (add B1, B2), (add B2, B3)]>;

def ARC3 : AClass<32, [untyped], (add ATuple)>;
def BRC3 : BClass<32, [untyped], (add BTuple)>;
def ABRC3 : MyClass<32, [untyped], (add ARC3, BRC3)> {
let isAllocatable = 0;
}

def TestTarget : Target;

// CHECK: static unsigned const ARC3_with_sub0_sub1Superclasses[] = {
// CHECK-NEXT: Test::ABRC3RegClassID,
// CHECK-NEXT: Test::ARC3RegClassID,
// CHECK-NEXT: Test::ABRC3_with_sub0_sub1RegClassID,
// CHECK-NEXT: };

// CHECK: static unsigned const ARC3_with_sub1_sub2Superclasses[] = {
// CHECK-NEXT: Test::ABRC3RegClassID,
// CHECK-NEXT: Test::ARC3RegClassID,
// CHECK-NEXT: Test::ABRC3_with_sub1_sub2RegClassID,
// CHECK-NEXT: };

// CHECK: extern const TargetRegisterClass ARC3_with_sub0_sub1RegClass = {
// CHECK: 0x01, /* TSFlags */

// CHECK: extern const TargetRegisterClass ARC3_with_sub1_sub2RegClass = {
// CHECK: 0x01, /* TSFlags */
18 changes: 11 additions & 7 deletions llvm/utils/TableGen/Common/CodeGenRegisters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -861,23 +861,27 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
}
}

// Compute inherited propertied for a synthesized register class.
// Compute inherited properties for a synthesized register class.
void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) {
assert(!getDef() && "Only synthesized classes can inherit properties");
assert(!SuperClasses.empty() && "Synthesized class without super class");

// The last super-class is the smallest one.
CodeGenRegisterClass &Super = *SuperClasses.back();
// The last super-class is the smallest one in topological order. Check for
// allocatable super-classes and inherit from the nearest allocatable one if
// any.
auto NearestAllocSCRIt =
find_if(reverse(SuperClasses),
[&](const CodeGenRegisterClass *S) { return S->Allocatable; });
CodeGenRegisterClass &Super = NearestAllocSCRIt == SuperClasses.rend()
? *SuperClasses.back()
: **NearestAllocSCRIt;

// Most properties are copied directly.
// Exceptions are members, size, and alignment
Namespace = Super.Namespace;
VTs = Super.VTs;
CopyCost = Super.CopyCost;
// Check for allocatable superclasses.
Allocatable = any_of(SuperClasses, [&](const CodeGenRegisterClass *S) {
return S->Allocatable;
});
Allocatable = Super.Allocatable;
AltOrderSelect = Super.AltOrderSelect;
AllocationPriority = Super.AllocationPriority;
GlobalPriority = Super.GlobalPriority;
Expand Down
Loading