[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
llvm-svn: 339352
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index a492daa..ca9d5ed 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -389,9 +389,8 @@
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 @@
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";
}
}
diff --git a/llvm/utils/TableGen/PredicateExpander.cpp b/llvm/utils/TableGen/PredicateExpander.cpp
index 68eb327..6f61173 100644
--- a/llvm/utils/TableGen/PredicateExpander.cpp
+++ b/llvm/utils/TableGen/PredicateExpander.cpp
@@ -176,6 +176,72 @@
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();
diff --git a/llvm/utils/TableGen/PredicateExpander.h b/llvm/utils/TableGen/PredicateExpander.h
index 398b376..31952dc 100644
--- a/llvm/utils/TableGen/PredicateExpander.h
+++ b/llvm/utils/TableGen/PredicateExpander.h
@@ -79,6 +79,11 @@
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