Skip to content

[TableGen] Inherit properties from the nearest allocatable superclass. #127018

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 25, 2025

Conversation

petechou
Copy link
Contributor

Previously isAlocatable was updated to allow inheritance from any
superclass for a generated register class, but other properties are
still inherited from its nearest superclass. This could cause
a generated regclass inherit undesired properties, e.g., tsflags, from
an unallocatable superclass due to the topological inheritance order.

This change updates to inherit properties from the nearest allocatable
superclass if possible and includes a test to demonstrate a potential
incorrect inheritance of tsflags.

Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot
Copy link
Member

llvmbot commented Feb 13, 2025

@llvm/pr-subscribers-tablegen

Author: Pete Chou (petechou)

Changes

Previously isAlocatable was updated to allow inheritance from any
superclass for a generated register class, but other properties are
still inherited from its nearest superclass. This could cause
a generated regclass inherit undesired properties, e.g., tsflags, from
an unallocatable superclass due to the topological inheritance order.

This change updates to inherit properties from the nearest allocatable
superclass if possible and includes a test to demonstrate a potential
incorrect inheritance of tsflags.


Full diff: https://github.com/llvm/llvm-project/pull/127018.diff

2 Files Affected:

  • (added) llvm/test/TableGen/RegisterInfoEmitter-inherit-properties.td (+87)
  • (modified) llvm/utils/TableGen/Common/CodeGenRegisters.cpp (+11-7)
diff --git a/llvm/test/TableGen/RegisterInfoEmitter-inherit-properties.td b/llvm/test/TableGen/RegisterInfoEmitter-inherit-properties.td
new file mode 100644
index 0000000000000..9ca3478662ce9
--- /dev/null
+++ b/llvm/test/TableGen/RegisterInfoEmitter-inherit-properties.td
@@ -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 */
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
index 973c86c6e5a55..0304846ba1ea5 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
@@ -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 = std::find_if(
+      SuperClasses.rbegin(), SuperClasses.rend(),
+      [&](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;

@petechou
Copy link
Contributor Author

I am probably working on a related issue that's discussed in https://reviews.llvm.org/D105967. f5917e0 is not enough to resolve my case and there's also a question about the inheritance of other properties raised in the code review. I feel it makes sense to inherit from the nearest allocatable super-class if isAllocatable could be set based on the property of any super-class. Appreciate any comment or feedback. Thanks.

@petechou
Copy link
Contributor Author

@perlfu Appreciate it if you can take a look. Thanks.

@bader bader requested a review from perlfu February 14, 2025 16:42
Copy link
Contributor

@perlfu perlfu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - thanks this makes sense to me

However, we should just get a few more eyes on the review in case.

@perlfu perlfu requested review from kparzysz and jayfoad February 19, 2025 02:42
@petechou petechou force-pushed the dev-tblgen-inheritproperties-fix branch from 6015660 to 81204a8 Compare February 19, 2025 23:22
@petechou
Copy link
Contributor Author

Rebase only.
Thanks for the code review. @kparzysz @jayfoad @perlfu Please let me know if any additional comment. Could you please also help merge the pr if it looks good to you as I don't have the write permission? Thanks.

@petechou
Copy link
Contributor Author

Ping

1 similar comment
@petechou
Copy link
Contributor Author

Ping

Comment on lines 872 to 874
auto NearestAllocSCRIt = std::find_if(
SuperClasses.rbegin(), SuperClasses.rend(),
[&](const CodeGenRegisterClass *S) { return S->Allocatable; });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: you could use llvm::find_if(SuperClasses, [&]...) instead of std::find_if.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your suggestion. Update to use llvm::find_if with reverse as we want to find the last occurrence.

Copy link
Contributor

@kparzysz kparzysz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable to me.

Previously isAlocatable was updated to allow inheritance from any
superclass for a generated register class, but other properties are
still inherited from its nearest superclass. This could cause
a generated regclass inherit undesired properties, e.g., tsflags, from
an unallocatable superclass due to the topological inheritance order.

This change updates to inherit properties from the nearest allocatable
superclass if possible and includes a test to demonstrate a potential
incorrect inheritance of tsflags.
@petechou petechou force-pushed the dev-tblgen-inheritproperties-fix branch from 7c0d076 to 82f5587 Compare March 25, 2025 19:14
Copy link
Contributor Author

@petechou petechou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rebase + fix comment.
@kparzysz Please help merge the pr if the update looks good to you. Thanks!

Comment on lines 872 to 874
auto NearestAllocSCRIt = std::find_if(
SuperClasses.rbegin(), SuperClasses.rend(),
[&](const CodeGenRegisterClass *S) { return S->Allocatable; });
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your suggestion. Update to use llvm::find_if with reverse as we want to find the last occurrence.

@kparzysz kparzysz merged commit a074831 into llvm:main Mar 25, 2025
11 checks passed
Copy link

@petechou Congratulations on having your first Pull Request (PR) merged into the LLVM Project!

Your changes will be combined with recent changes from other authors, then tested by our build bots. If there is a problem with a build, you may receive a report in an email or a comment on this PR.

Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues.

How to do this, and the rest of the post-merge process, is covered in detail here.

If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of LLVM development. You can fix your changes and open a new PR to merge them again.

If you don't get any reports, no action is required from you. Your changes are working as expected, well done!

@petechou petechou deleted the dev-tblgen-inheritproperties-fix branch March 25, 2025 22:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants