[gicombiner] Allow generated CombinerHelpers to have additional arguments
authorDaniel Sanders <daniel_l_sanders@apple.com>
Tue, 16 Jun 2020 20:41:38 +0000 (13:41 -0700)
committerDaniel Sanders <daniel_l_sanders@apple.com>
Tue, 16 Jun 2020 21:11:37 +0000 (14:11 -0700)
Summary:
This allows combiners to delegate to other helpers or depend
on additional information. It's not great as an overall
solution though as callers must provide the argument on every call, even for
static data like an additional helper. Another patch will follow to
support additional members of the generated combiner.

Reviewers: aditya_nandakumar, bogner, aemerson, paquette, volkan, arsenm

Reviewed By: aditya_nandakumar

Subscribers: wdng, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D81862

llvm/include/llvm/Target/GlobalISel/Combine.td
llvm/utils/TableGen/GICombinerEmitter.cpp

index b411851..7803ce1 100644 (file)
@@ -27,6 +27,11 @@ class GICombineGroup<list<GICombine> rules> : GICombine {
   let Rules = rules;
 }
 
+class GICombinerHelperArg<string type, string name> {
+  string Type = type;
+  string Name = name;
+}
+
 // Declares a combiner helper class
 class GICombinerHelper<string classname, list<GICombine> rules>
     : GICombineGroup<rules> {
@@ -35,6 +40,9 @@ class GICombinerHelper<string classname, list<GICombine> rules>
   // The name of a run-time compiler option that will be generated to disable
   // specific rules within this combiner.
   string DisableRuleOption = ?;
+  // Any additional arguments that should be appended to the tryCombine*().
+  list<GICombinerHelperArg> AdditionalArguments =
+      [GICombinerHelperArg<"CombinerHelper &", "Helper">];
 }
 class GICombineRule<dag defs, dag match, dag apply> : GICombine {
   /// Defines the external interface of the match rule. This includes:
index 8c70ed1..761ca4b 100644 (file)
@@ -841,6 +841,13 @@ void GICombinerEmitter::generateCodeForTree(raw_ostream &OS,
     OS << Indent << "return false;\n";
 }
 
+static void emitAdditionalHelperMethodArguments(raw_ostream &OS,
+                                                Record *Combiner) {
+  for (Record *Arg : Combiner->getValueAsListOfDefs("AdditionalArguments"))
+    OS << ",\n    " << Arg->getValueAsString("Type")
+       << Arg->getValueAsString("Name");
+}
+
 void GICombinerEmitter::run(raw_ostream &OS) {
   gatherRules(Rules, Combiner->getValueAsListOfDefs("Rules"));
   if (StopAfterParse) {
@@ -901,9 +908,10 @@ void GICombinerEmitter::run(raw_ostream &OS) {
      << "  bool tryCombineAll(\n"
      << "    GISelChangeObserver &Observer,\n"
      << "    MachineInstr &MI,\n"
-     << "    MachineIRBuilder &B,\n"
-     << "    CombinerHelper &Helper) const;\n"
-     << "};\n\n";
+     << "    MachineIRBuilder &B";
+  emitAdditionalHelperMethodArguments(OS, Combiner);
+  OS << ") const;\n";
+  OS << "};\n\n";
 
   emitNameMatcher(OS);
 
@@ -958,8 +966,9 @@ void GICombinerEmitter::run(raw_ostream &OS) {
   OS << "bool " << getClassName() << "::tryCombineAll(\n"
      << "    GISelChangeObserver &Observer,\n"
      << "    MachineInstr &MI,\n"
-     << "    MachineIRBuilder &B,\n"
-     << "    CombinerHelper &Helper) const {\n"
+     << "    MachineIRBuilder &B";
+  emitAdditionalHelperMethodArguments(OS, Combiner);
+  OS << ") const {\n"
      << "  MachineBasicBlock *MBB = MI.getParent();\n"
      << "  MachineFunction *MF = MBB->getParent();\n"
      << "  MachineRegisterInfo &MRI = MF->getRegInfo();\n"