summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Target/TargetInstrPredicate.td34
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.cpp3
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.h3
-rw-r--r--llvm/utils/TableGen/InstrInfoEmitter.cpp30
-rw-r--r--llvm/utils/TableGen/PredicateExpander.cpp52
-rw-r--r--llvm/utils/TableGen/PredicateExpander.h13
6 files changed, 111 insertions, 24 deletions
diff --git a/llvm/include/llvm/Target/TargetInstrPredicate.td b/llvm/include/llvm/Target/TargetInstrPredicate.td
index d25309a45ba..e70da009790 100644
--- a/llvm/include/llvm/Target/TargetInstrPredicate.td
+++ b/llvm/include/llvm/Target/TargetInstrPredicate.td
@@ -106,28 +106,50 @@ class CheckSameRegOperand<int First, int Second> : MCInstPredicate {
int SecondIndex = Second;
}
+// Base class for checks on register/immediate operands.
+// It allows users to define checks like:
+// MyFunction(MI->getOperand(Index).getImm()) == Val;
+//
+// In the example above, `MyFunction` is a function that takes as input an
+// immediate operand value, and returns another value. Field `FunctionMapper` is
+// the name of the function to call on the operand value.
+class CheckOperandBase<int Index, string Fn = ""> : MCOperandPredicate<Index> {
+ string FunctionMapper = Fn;
+}
+
// Check that the machine register operand at position `Index` references
// register R. This predicate assumes that we already checked that the machine
// operand at position `Index` is a register operand.
-class CheckRegOperand<int Index, Register R> : MCOperandPredicate<Index> {
+class CheckRegOperand<int Index, Register R> : CheckOperandBase<Index> {
Register Reg = R;
}
// Check if register operand at index `Index` is the invalid register.
-class CheckInvalidRegOperand<int Index> : MCOperandPredicate<Index>;
+class CheckInvalidRegOperand<int Index> : CheckOperandBase<Index>;
// Check that the operand at position `Index` is immediate `Imm`.
-class CheckImmOperand<int Index, int Imm> : MCOperandPredicate<Index> {
+// If field `FunctionMapper` is a non-empty string, then function
+// `FunctionMapper` is applied to the operand value, and the return value is then
+// compared against `Imm`.
+class CheckImmOperand<int Index, int Imm> : CheckOperandBase<Index> {
int ImmVal = Imm;
}
// Similar to CheckImmOperand, however the immediate is not a literal number.
// This is useful when we want to compare the value of an operand against an
// enum value, and we know the actual integer value of that enum.
-class CheckImmOperand_s<int Index, string Value> : MCOperandPredicate<Index> {
+class CheckImmOperand_s<int Index, string Value> : CheckOperandBase<Index> {
string ImmVal = Value;
}
+// Expands to a call to `FunctionMapper` if field `FunctionMapper` is set.
+// Otherwise, it expands to a CheckNot<CheckInvalidRegOperand<Index>>.
+class CheckRegOperandSimple<int Index> : CheckOperandBase<Index>;
+
+// Expands to a call to `FunctionMapper` if field `FunctionMapper` is set.
+// Otherwise, it simply evaluates to TruePred.
+class CheckImmOperandSimple<int Index> : CheckOperandBase<Index>;
+
// Check that the operand at position `Index` is immediate value zero.
class CheckZeroOperand<int Index> : CheckImmOperand<Index, 0>;
@@ -206,13 +228,13 @@ class FunctionPredicateBase<string name, MCStatement body> {
MCStatement Body = body;
}
-// Check that a call to method `Name` in class "XXXGenInstrInfo" (where XXX is
+// Check that a call to method `Name` in class "XXXInstrInfo" (where XXX is
// the name of a target) returns true.
//
// TIIPredicate definitions are used to model calls to the target-specific
// 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.
+// the target specific `InstrInfo` class.
//
// There cannot be multiple TIIPredicate definitions with the same name for the
// same target.
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index db0cb63ae69..88f2f0fffd6 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -7844,3 +7844,6 @@ X86InstrInfo::insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
return It;
}
+
+#define GET_TII_HELPERS
+#include "X86GenInstrInfo.inc"
diff --git a/llvm/lib/Target/X86/X86InstrInfo.h b/llvm/lib/Target/X86/X86InstrInfo.h
index 85afcf8904a..f3965db4fe7 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.h
+++ b/llvm/lib/Target/X86/X86InstrInfo.h
@@ -558,6 +558,9 @@ public:
MachineBasicBlock::iterator &It, MachineFunction &MF,
const outliner::Candidate &C) const override;
+#define GET_TII_HELPER_DECLS
+#include "X86GenInstrInfo.inc"
+
protected:
/// Commutes the operands in the given instruction by changing the operands
/// order and/or changing the instruction's opcode and/or the immediate value
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index ef8c849e25f..55b6f192c2f 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -66,7 +66,8 @@ private:
/// This method is used to custom expand TIIPredicate definitions.
/// See file llvm/Target/TargetInstPredicates.td for a description of what is
/// a TIIPredicate and how to use it.
- void emitTIIHelperMethods(raw_ostream &OS, StringRef TargetName);
+ void emitTIIHelperMethods(raw_ostream &OS, StringRef TargetName,
+ bool ExpandDefinition = true);
/// Expand TIIPredicate definitions to functions that accept a const MCInst
/// reference.
@@ -400,7 +401,8 @@ void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
}
void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS,
- StringRef TargetName) {
+ StringRef TargetName,
+ bool ExpandDefinition) {
RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate");
if (TIIPredicates.empty())
return;
@@ -410,8 +412,17 @@ void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS,
PE.setIndentLevel(2);
for (const Record *Rec : TIIPredicates) {
- OS << "\n static bool " << Rec->getValueAsString("FunctionName");
- OS << "(const MachineInstr &MI) {\n";
+ OS << "\n " << (ExpandDefinition ? "" : "static ") << "bool ";
+ if (ExpandDefinition)
+ OS << TargetName << "InstrInfo::";
+ OS << Rec->getValueAsString("FunctionName");
+ OS << "(const MachineInstr &MI)";
+ if (!ExpandDefinition) {
+ OS << ";\n";
+ continue;
+ }
+
+ OS << " {\n";
OS.indent(PE.getIndentLevel() * 2);
PE.expandStatement(OS, Rec->getValueAsDef("Body"));
@@ -517,12 +528,21 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
<< "(int CFSetupOpcode = -1, int CFDestroyOpcode = -1, int CatchRetOpcode = -1, int ReturnOpcode = -1);\n"
<< " ~" << ClassName << "() override = default;\n";
- emitTIIHelperMethods(OS, TargetName);
OS << "\n};\n} // end llvm namespace\n";
OS << "#endif // GET_INSTRINFO_HEADER\n\n";
+ OS << "#ifdef GET_TII_HELPER_DECLS\n";
+ OS << "#undef GET_TII_HELPER_DECLS\n";
+ emitTIIHelperMethods(OS, TargetName, /* ExpandDefintion = */false);
+ OS << "#endif // GET_TII_HELPER_DECLS\n\n";
+
+ OS << "#ifdef GET_TII_HELPERS\n";
+ OS << "#undef GET_TII_HELPERS\n";
+ emitTIIHelperMethods(OS, TargetName, /* ExpandDefintion = */true);
+ OS << "#endif // GET_TTI_HELPERS\n\n";
+
OS << "#ifdef GET_INSTRINFO_CTOR_DTOR\n";
OS << "#undef GET_INSTRINFO_CTOR_DTOR\n";
diff --git a/llvm/utils/TableGen/PredicateExpander.cpp b/llvm/utils/TableGen/PredicateExpander.cpp
index 83f67c023e5..ad7bf60caab 100644
--- a/llvm/utils/TableGen/PredicateExpander.cpp
+++ b/llvm/utils/TableGen/PredicateExpander.cpp
@@ -20,23 +20,43 @@ void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; }
void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; }
void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
- int ImmVal) {
+ int ImmVal,
+ StringRef FunctionMapper) {
+ if (!FunctionMapper.empty())
+ OS << FunctionMapper << "(";
OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
- << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
+ << ").getImm()";
+ OS << (FunctionMapper.empty() ? " " : ") ");
+ OS << (shouldNegate() ? "!= " : "== ") << ImmVal;
}
void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
- StringRef ImmVal) {
+ StringRef ImmVal,
+ StringRef FunctionMapper) {
+ if (!FunctionMapper.empty())
+ OS << FunctionMapper << "(";
OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
- << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
+ << ").getImm()";
+
+ OS << (FunctionMapper.empty() ? "" : ")");
+ if (ImmVal.empty())
+ return;
+ OS << (shouldNegate() ? " != " : " == ") << ImmVal;
}
void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex,
- const Record *Reg) {
+ const Record *Reg,
+ StringRef FunctionMapper) {
assert(Reg->isSubClassOf("Register") && "Expected a register Record!");
+ if (!FunctionMapper.empty())
+ OS << FunctionMapper << "(";
OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
- << ").getReg() " << (shouldNegate() ? "!= " : "== ");
+ << ").getReg()";
+ OS << (FunctionMapper.empty() ? "" : ")");
+ if (!Reg)
+ return;
+ OS << (shouldNegate() ? " != " : " == ");
const StringRef Str = Reg->getValueAsString("Namespace");
if (!Str.empty())
OS << Str << "::";
@@ -137,7 +157,7 @@ void PredicateExpander::expandPredicateSequence(raw_ostream &OS,
void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS,
StringRef MethodName) {
OS << (shouldNegate() ? "!" : "");
- OS << TargetName << (shouldExpandForMC() ? "_MC::" : "GenInstrInfo::");
+ OS << TargetName << (shouldExpandForMC() ? "_MC::" : "InstrInfo::");
OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
}
@@ -266,18 +286,30 @@ void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
if (Rec->isSubClassOf("CheckRegOperand"))
return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
- Rec->getValueAsDef("Reg"));
+ Rec->getValueAsDef("Reg"),
+ Rec->getValueAsString("FunctionMapper"));
+
+ if (Rec->isSubClassOf("CheckRegOperandSimple"))
+ return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
+ nullptr,
+ Rec->getValueAsString("FunctionMapper"));
if (Rec->isSubClassOf("CheckInvalidRegOperand"))
return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
if (Rec->isSubClassOf("CheckImmOperand"))
return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
- Rec->getValueAsInt("ImmVal"));
+ Rec->getValueAsInt("ImmVal"),
+ Rec->getValueAsString("FunctionMapper"));
if (Rec->isSubClassOf("CheckImmOperand_s"))
return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
- Rec->getValueAsString("ImmVal"));
+ Rec->getValueAsString("ImmVal"),
+ Rec->getValueAsString("FunctionMapper"));
+
+ if (Rec->isSubClassOf("CheckImmOperandSimple"))
+ return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), "",
+ Rec->getValueAsString("FunctionMapper"));
if (Rec->isSubClassOf("CheckSameRegOperand"))
return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
diff --git a/llvm/utils/TableGen/PredicateExpander.h b/llvm/utils/TableGen/PredicateExpander.h
index 255e40c4998..0f3ee6867e6 100644
--- a/llvm/utils/TableGen/PredicateExpander.h
+++ b/llvm/utils/TableGen/PredicateExpander.h
@@ -56,9 +56,16 @@ public:
using RecVec = std::vector<Record *>;
void expandTrue(raw_ostream &OS);
void expandFalse(raw_ostream &OS);
- void expandCheckImmOperand(raw_ostream &OS, int OpIndex, int ImmVal);
- void expandCheckImmOperand(raw_ostream &OS, int OpIndex, StringRef ImmVal);
- void expandCheckRegOperand(raw_ostream &OS, int OpIndex, const Record *Reg);
+ void expandCheckImmOperand(raw_ostream &OS, int OpIndex, int ImmVal,
+ StringRef FunctionMapper);
+ void expandCheckImmOperand(raw_ostream &OS, int OpIndex, StringRef ImmVal,
+ StringRef FunctionMapperer);
+ void expandCheckImmOperandSimple(raw_ostream &OS, int OpIndex,
+ StringRef FunctionMapper);
+ void expandCheckRegOperand(raw_ostream &OS, int OpIndex, const Record *Reg,
+ StringRef FunctionMapper);
+ void expandCheckRegOperandSimple(raw_ostream &OS, int OpIndex,
+ StringRef FunctionMapper);
void expandCheckSameRegOperand(raw_ostream &OS, int First, int Second);
void expandCheckNumOperands(raw_ostream &OS, int NumOps);
void expandCheckOpcode(raw_ostream &OS, const Record *Inst);
OpenPOWER on IntegriCloud