[llvm] r339352 - [MC][PredicateExpander] Extend the grammar to support simple switch and return statements.

Andrea Di Biagio via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 9 08:32:48 PDT 2018


Author: adibiagio
Date: Thu Aug  9 08:32:48 2018
New Revision: 339352

URL: http://llvm.org/viewvc/llvm-project?rev=339352&view=rev
Log:
[MC][PredicateExpander] Extend the grammar to support simple switch and return statements.

This patch introduces tablegen class MCStatement.

Currently, an MCStatement can be either a return statement, or a switch
statement.

```
MCStatement:
   MCReturnStatement
   MCOpcodeSwitchStatement
```

A MCReturnStatement expands to a return statement, and the boolean expression
associated with the return statement is described by a MCInstPredicate.

An MCOpcodeSwitchStatement is a switch statement where the condition is a check
on the machine opcode. It allows the definition of multiple checks, as well as a
default case. More details on the grammar implemented by these two new
constructs can be found in the diff for TargetInstrPredicates.td.

This patch makes it easier to read the body of auto-generated TargetInstrInfo
predicates.

In future, I plan to reuse/extend the MCStatement grammar to describe more
complex target hooks. For now, this is just a first step (mostly a minor
cosmetic change to polish the new predicates framework).

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

Modified:
    llvm/trunk/include/llvm/Target/TargetInstrPredicate.td
    llvm/trunk/lib/Target/X86/X86SchedPredicates.td
    llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp
    llvm/trunk/utils/TableGen/PredicateExpander.cpp
    llvm/trunk/utils/TableGen/PredicateExpander.h

Modified: llvm/trunk/include/llvm/Target/TargetInstrPredicate.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrPredicate.td?rev=339352&r1=339351&r2=339352&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetInstrPredicate.td (original)
+++ llvm/trunk/include/llvm/Target/TargetInstrPredicate.td Thu Aug  9 08:32:48 2018
@@ -169,6 +169,35 @@ class CheckAll<list<MCInstPredicate> Seq
 class CheckAny<list<MCInstPredicate> Sequence>
     : CheckPredicateSequence<Sequence>;
 
+
+// Used to expand the body of a function predicate. See the definition of
+// TIIPredicate below.
+class MCStatement;
+
+// Expands to a return statement. The return expression is a boolean expression
+// described by a MCInstPredicate.
+class MCReturnStatement<MCInstPredicate predicate> : MCStatement {
+  MCInstPredicate Pred = predicate;
+}
+
+// Used to automatically construct cases of a switch statement where the switch
+// variable is an instruction opcode. There is a 'case' for every opcode in the
+// `opcodes` list, and each case is associated with MCStatement `caseStmt`.
+class MCOpcodeSwitchCase<list<Instruction> opcodes, MCStatement caseStmt> {
+  list<Instruction> Opcodes = opcodes;
+  MCStatement CaseStmt = caseStmt;
+}
+
+// Expands to a switch statement. The switch variable is an instruction opcode.
+// The auto-generated switch is populated by a number of cases based on the
+// `cases` list in input. A default case is automatically generated, and it
+// evaluates to `default`.
+class MCOpcodeSwitchStatement<list<MCOpcodeSwitchCase> cases,
+                              MCStatement default> : MCStatement {
+  list<MCOpcodeSwitchCase> Cases = cases;
+  MCStatement DefaultCase = default;
+}
+
 // Check that a call to method `Name` in class "XXXGenInstrInfo" (where XXX is
 // the `Target` name) returns true.
 //
@@ -176,10 +205,11 @@ class CheckAny<list<MCInstPredicate> Seq
 // InstrInfo. A TIIPredicate is treated specially by the InstrInfoEmitter
 // tablegen backend, which will use it to automatically generate a definition in
 // the target specific `GenInstrInfo` class.
-class TIIPredicate<string Target, string Name, MCInstPredicate P> : MCInstPredicate {
+class TIIPredicate<string Target, string Name, MCStatement body>
+    : MCInstPredicate {
   string TargetName = Target;
   string FunctionName = Name;
-  MCInstPredicate Pred = P;
+  MCStatement Body = body;
 }
 
 // A function predicate that takes as input a machine instruction, and returns

Modified: llvm/trunk/lib/Target/X86/X86SchedPredicates.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86SchedPredicates.td?rev=339352&r1=339351&r2=339352&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86SchedPredicates.td (original)
+++ llvm/trunk/lib/Target/X86/X86SchedPredicates.td Thu Aug  9 08:32:48 2018
@@ -19,11 +19,9 @@
 // different zero-idioms.
 def ZeroIdiomPredicate : CheckSameRegOperand<1, 2>;
 
-// A predicate used to check if an instruction is a LEA, and if it uses all
-// three source operands: base, index, and offset.
+// A predicate used to check if a LEA instruction uses all three source
+// operands: base, index, and offset.
 def IsThreeOperandsLEAPredicate: CheckAll<[
-  CheckOpcode<[LEA32r, LEA64r, LEA64_32r, LEA16r]>,
-
   // isRegOperand(Base)
   CheckIsRegOperand<1>,
   CheckNot<CheckInvalidRegOperand<1>>,
@@ -42,8 +40,17 @@ def IsThreeOperandsLEAPredicate: CheckAl
   ]>
 ]>;
 
+def LEACases : MCOpcodeSwitchCase<
+    [LEA32r, LEA64r, LEA64_32r, LEA16r],
+    MCReturnStatement<IsThreeOperandsLEAPredicate>
+>;
+
+// Used to generate the body of a TII member function.
+def IsThreeOperandsLEABody :
+    MCOpcodeSwitchStatement<[LEACases], MCReturnStatement<FalsePred>>;
+
 // This predicate evaluates to true only if the input machine instruction is a
 // 3-operands LEA.  Tablegen automatically generates a new method for it in
 // X86GenInstrInfo.
 def IsThreeOperandsLEAFn :
-    TIIPredicate<"X86", "isThreeOperandsLEA", IsThreeOperandsLEAPredicate>;
+    TIIPredicate<"X86", "isThreeOperandsLEA", IsThreeOperandsLEABody>;

Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=339352&r1=339351&r2=339352&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Thu Aug  9 08:32:48 2018
@@ -389,9 +389,8 @@ void InstrInfoEmitter::emitMCIIHelperMet
   for (const Record *Rec : TIIPredicates) {
     FOS << "bool " << Rec->getValueAsString("FunctionName");
     FOS << "(const MCInst &MI) {\n";
-    FOS << "  return ";
-    PE.expandPredicate(FOS, Rec->getValueAsDef("Pred"));
-    FOS << ";\n}\n";
+    PE.expandStatement(FOS, Rec->getValueAsDef("Body"));
+    FOS << "\n}\n";
   }
 
   FOS << "\n} // end " << TargetName << "_MC namespace\n";
@@ -413,9 +412,8 @@ void InstrInfoEmitter::emitTIIHelperMeth
   for (const Record *Rec : TIIPredicates) {
     FOS << "\n  static bool " << Rec->getValueAsString("FunctionName");
     FOS << "(const MachineInstr &MI) {\n";
-    FOS << "    return ";
-    PE.expandPredicate(FOS, Rec->getValueAsDef("Pred"));
-    FOS << ";\n  }\n";
+    PE.expandStatement(FOS, Rec->getValueAsDef("Body"));
+    FOS << "\n  }\n";
   }
 }
 

Modified: llvm/trunk/utils/TableGen/PredicateExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/PredicateExpander.cpp?rev=339352&r1=339351&r2=339352&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/PredicateExpander.cpp (original)
+++ llvm/trunk/utils/TableGen/PredicateExpander.cpp Thu Aug  9 08:32:48 2018
@@ -176,6 +176,72 @@ void PredicateExpander::expandCheckNonPo
   OS << '(' << Code << ')';
 }
 
+void PredicateExpander::expandReturnStatement(formatted_raw_ostream &OS,
+                                              const Record *Rec) {
+  OS << "return ";
+  expandPredicate(OS, Rec);
+  OS << ";";
+}
+
+void PredicateExpander::expandOpcodeSwitchCase(formatted_raw_ostream &OS,
+                                               const Record *Rec) {
+  const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes");
+  for (const Record *Opcode : Opcodes) {
+    OS.PadToColumn(getIndentLevel() * 2);
+    OS << "case " << Opcode->getValueAsString("Namespace")
+       << "::" << Opcode->getName() << " :\n";
+  }
+
+  increaseIndentLevel();
+  expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
+  decreaseIndentLevel();
+}
+
+void PredicateExpander::expandOpcodeSwitchStatement(formatted_raw_ostream &OS,
+                                                    const RecVec &Cases,
+                                                    const Record *Default) {
+  OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
+
+  for (const Record *Rec : Cases) {
+    expandOpcodeSwitchCase(OS, Rec);
+    OS << '\n';
+  }
+
+  unsigned ColNum = getIndentLevel() * 2;
+  OS.PadToColumn(ColNum);
+
+  // Expand the default case.
+  OS << "default :\n";
+  increaseIndentLevel();
+  expandStatement(OS, Default);
+  decreaseIndentLevel();
+  OS << '\n';
+
+  OS.PadToColumn(ColNum);
+  OS << "} // end of switch-stmt";
+}
+
+void PredicateExpander::expandStatement(formatted_raw_ostream &OS,
+                                        const Record *Rec) {
+  OS.flush();
+  unsigned ColNum = getIndentLevel() * 2;
+  if (OS.getColumn() < ColNum)
+    OS.PadToColumn(ColNum);
+
+  if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) {
+    expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"),
+                                Rec->getValueAsDef("DefaultCase"));
+    return;
+  }
+
+  if (Rec->isSubClassOf("MCReturnStatement")) {
+    expandReturnStatement(OS, Rec->getValueAsDef("Pred"));
+    return;
+  }
+
+  llvm_unreachable("No known rules to expand this MCStatement");
+}
+
 void PredicateExpander::expandPredicate(formatted_raw_ostream &OS,
                                         const Record *Rec) {
   OS.flush();

Modified: llvm/trunk/utils/TableGen/PredicateExpander.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/PredicateExpander.h?rev=339352&r1=339351&r2=339352&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/PredicateExpander.h (original)
+++ llvm/trunk/utils/TableGen/PredicateExpander.h Thu Aug  9 08:32:48 2018
@@ -79,6 +79,11 @@ public:
                                     StringRef MachineInstrFn);
   void expandCheckNonPortable(formatted_raw_ostream &OS, StringRef CodeBlock);
   void expandPredicate(formatted_raw_ostream &OS, const Record *Rec);
+  void expandReturnStatement(formatted_raw_ostream &OS, const Record *Rec);
+  void expandOpcodeSwitchCase(formatted_raw_ostream &OS, const Record *Rec);
+  void expandOpcodeSwitchStatement(formatted_raw_ostream &OS,
+                                   const RecVec &Cases, const Record *Default);
+  void expandStatement(formatted_raw_ostream &OS, const Record *Rec);
 };
 
 } // namespace llvm




More information about the llvm-commits mailing list