summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2018-08-09 15:32:48 +0000
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2018-08-09 15:32:48 +0000
commitf3bde0485c2451487c0debc8719d290d56eb7009 (patch)
treee52c0416302bc835bbd0477b54b260a2b5cf5017
parent879c1421301af0880d711320bcc0df0d911b16a8 (diff)
downloadbcm5719-llvm-f3bde0485c2451487c0debc8719d290d56eb7009.tar.gz
bcm5719-llvm-f3bde0485c2451487c0debc8719d290d56eb7009.zip
[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
-rw-r--r--llvm/include/llvm/Target/TargetInstrPredicate.td34
-rw-r--r--llvm/lib/Target/X86/X86SchedPredicates.td17
-rw-r--r--llvm/utils/TableGen/InstrInfoEmitter.cpp10
-rw-r--r--llvm/utils/TableGen/PredicateExpander.cpp66
-rw-r--r--llvm/utils/TableGen/PredicateExpander.h5
5 files changed, 119 insertions, 13 deletions
diff --git a/llvm/include/llvm/Target/TargetInstrPredicate.td b/llvm/include/llvm/Target/TargetInstrPredicate.td
index 8d57cae02d2..8925e4b0b39 100644
--- a/llvm/include/llvm/Target/TargetInstrPredicate.td
+++ b/llvm/include/llvm/Target/TargetInstrPredicate.td
@@ -169,6 +169,35 @@ class CheckAll<list<MCInstPredicate> Sequence>
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> Sequence>
// 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
diff --git a/llvm/lib/Target/X86/X86SchedPredicates.td b/llvm/lib/Target/X86/X86SchedPredicates.td
index 27aaeb19358..abb86119d45 100644
--- a/llvm/lib/Target/X86/X86SchedPredicates.td
+++ b/llvm/lib/Target/X86/X86SchedPredicates.td
@@ -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: CheckAll<[
]>
]>;
+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>;
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index a492daac0d0..ca9d5ed262d 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -389,9 +389,8 @@ void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS) {
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::emitTIIHelperMethods(raw_ostream &OS) {
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 68eb32794a0..6f611737a43 100644
--- a/llvm/utils/TableGen/PredicateExpander.cpp
+++ b/llvm/utils/TableGen/PredicateExpander.cpp
@@ -176,6 +176,72 @@ void PredicateExpander::expandCheckNonPortable(formatted_raw_ostream &OS,
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 398b376f7a8..31952dc690e 100644
--- a/llvm/utils/TableGen/PredicateExpander.h
+++ b/llvm/utils/TableGen/PredicateExpander.h
@@ -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
OpenPOWER on IntegriCloud