This patch removes redundant template argument `TargetName` from TIIPredicate.
Tablegen can always infer the target name from the context. So we don't need to
force users of TIIPredicate to always specify it.
This allows us to better modularize the tablegen class hierarchy for the
so-called "function predicates". class FunctionPredicateBase has been added; it
is currently used as a building block for TIIPredicates. However, I plan to
reuse that class to model other function predicate classes too (i.e. not just
TIIPredicates). For example, this can be a first step towards implementing
proper support for dependency breaking instructions in tablegen.
This patch also adds a verification step on TIIPredicates in tablegen.
We cannot have multiple TIIPredicates with the same name. Otherwise, this will
cause build errors later on, when tablegen'd .inc files are included by cpp
files and then compiled.
Differential Revision: https://reviews.llvm.org/D50708
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339706
91177308-0d34-0410-b5e6-
96231b3b80d8
MCStatement DefaultCase = default;
}
+// Base class for function predicates.
+class FunctionPredicateBase<string name, MCStatement body> {
+ string FunctionName = name;
+ MCStatement Body = body;
+}
+
// Check that a call to method `Name` in class "XXXGenInstrInfo" (where XXX is
-// the `Target` name) returns true.
+// 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.
-class TIIPredicate<string Target, string Name, MCStatement body>
- : MCInstPredicate {
- string TargetName = Target;
- string FunctionName = Name;
- MCStatement Body = body;
-}
+//
+// There cannot be multiple TIIPredicate definitions with the same name for the
+// same target.
+class TIIPredicate<string Name, MCStatement body>
+ : FunctionPredicateBase<Name, body>, MCInstPredicate;
// A function predicate that takes as input a machine instruction, and returns
// a boolean value.
// 3-operands LEA. Tablegen automatically generates a new method for it in
// X86GenInstrInfo.
def IsThreeOperandsLEAFn :
- TIIPredicate<"X86", "isThreeOperandsLEA", IsThreeOperandsLEABody>;
+ TIIPredicate<"isThreeOperandsLEA", IsThreeOperandsLEABody>;
// Collect optional processor description.
collectOptionalProcessorInfo();
+ // Check MCInstPredicate definitions.
+ checkMCInstPredicates();
+
checkCompleteness();
}
+void CodeGenSchedModels::checkMCInstPredicates() const {
+ RecVec MCPredicates = Records.getAllDerivedDefinitions("TIIPredicate");
+ if (MCPredicates.empty())
+ return;
+
+ // A target cannot have multiple TIIPredicate definitions with a same name.
+ llvm::StringMap<const Record *> TIIPredicates(MCPredicates.size());
+ for (const Record *TIIPred : MCPredicates) {
+ StringRef Name = TIIPred->getValueAsString("FunctionName");
+ StringMap<const Record *>::const_iterator It = TIIPredicates.find(Name);
+ if (It == TIIPredicates.end()) {
+ TIIPredicates[Name] = TIIPred;
+ continue;
+ }
+
+ PrintError(TIIPred->getLoc(),
+ "TIIPredicate " + Name + " is multiply defined.");
+ PrintNote(It->second->getLoc(),
+ " Previous definition of " + Name + " was here.");
+ PrintFatalError(TIIPred->getLoc(),
+ "Found conflicting definitions of TIIPredicate.");
+ }
+}
+
void CodeGenSchedModels::collectRetireControlUnits() {
RecVec Units = Records.getAllDerivedDefinitions("RetireControlUnit");
void inferSchedClasses();
+ void checkMCInstPredicates() const;
+
void checkCompleteness();
void inferFromRW(ArrayRef<unsigned> OperWrites, ArrayRef<unsigned> OperReads,
/// 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);
+ void emitTIIHelperMethods(raw_ostream &OS, StringRef TargetName);
/// Expand TIIPredicate definitions to functions that accept a const MCInst
/// reference.
- void emitMCIIHelperMethods(raw_ostream &OS);
+ void emitMCIIHelperMethods(raw_ostream &OS, StringRef TargetName);
void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
Record *InstrInfo,
std::map<std::vector<Record*>, unsigned> &EL,
OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n\n";
}
-void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS) {
+void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
+ StringRef TargetName) {
RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate");
if (TIIPredicates.empty())
return;
- CodeGenTarget &Target = CDP.getTargetInfo();
- const StringRef TargetName = Target.getName();
-
OS << "#ifdef GET_GENINSTRINFO_MC_DECL\n";
OS << "#undef GET_GENINSTRINFO_MC_DECL\n\n";
OS << "namespace llvm {\n";
OS << "namespace " << TargetName << "_MC {\n\n";
- PredicateExpander PE;
+ PredicateExpander PE(TargetName);
PE.setExpandForMC(true);
for (const Record *Rec : TIIPredicates) {
OS << "#endif // GET_GENISTRINFO_MC_HELPERS\n";
}
-void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS) {
+void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS,
+ StringRef TargetName) {
RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate");
if (TIIPredicates.empty())
return;
- PredicateExpander PE;
+ PredicateExpander PE(TargetName);
PE.setExpandForMC(false);
PE.setIndentLevel(2);
<< "(int CFSetupOpcode = -1, int CFDestroyOpcode = -1, int CatchRetOpcode = -1, int ReturnOpcode = -1);\n"
<< " ~" << ClassName << "() override = default;\n";
- emitTIIHelperMethods(OS);
+ emitTIIHelperMethods(OS, TargetName);
OS << "\n};\n} // end llvm namespace\n";
emitOperandTypesEnum(OS, Target);
- emitMCIIHelperMethods(OS);
+ emitMCIIHelperMethods(OS, TargetName);
}
void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
}
void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS,
- StringRef TargetName,
StringRef MethodName) {
OS << (shouldNegate() ? "!" : "");
- if (shouldExpandForMC())
- OS << TargetName << "_MC::";
- else
- OS << TargetName << "Gen"
- << "InstrInfo::";
+ OS << TargetName << (shouldExpandForMC() ? "_MC::" : "GenInstrInfo::");
OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
}
return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
if (Rec->isSubClassOf("TIIPredicate"))
- return expandTIIFunctionCall(OS, Rec->getValueAsString("TargetName"),
- Rec->getValueAsString("FunctionName"));
+ return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName"));
llvm_unreachable("No known rules to expand this MCInstPredicate");
}
bool NegatePredicate;
bool ExpandForMC;
unsigned IndentLevel;
+ StringRef TargetName;
PredicateExpander(const PredicateExpander &) = delete;
PredicateExpander &operator=(const PredicateExpander &) = delete;
public:
- PredicateExpander()
+ PredicateExpander(StringRef Target)
: EmitCallsByRef(true), NegatePredicate(false), ExpandForMC(false),
- IndentLevel(1U) {}
+ IndentLevel(1U), TargetName(Target) {}
bool isByRef() const { return EmitCallsByRef; }
bool shouldNegate() const { return NegatePredicate; }
bool shouldExpandForMC() const { return ExpandForMC; }
void expandCheckOpcode(raw_ostream &OS, const RecVec &Opcodes);
void expandPredicateSequence(raw_ostream &OS, const RecVec &Sequence,
bool IsCheckAll);
- void expandTIIFunctionCall(raw_ostream &OS, StringRef TargetName,
- StringRef MethodName);
+ void expandTIIFunctionCall(raw_ostream &OS, StringRef MethodName);
void expandCheckIsRegOperand(raw_ostream &OS, int OpIndex);
void expandCheckIsImmOperand(raw_ostream &OS, int OpIndex);
void expandCheckInvalidRegOperand(raw_ostream &OS, int OpIndex);
OS << " case " << VC << ": // " << SC.Name << '\n';
- PredicateExpander PE;
+ PredicateExpander PE(Target);
PE.setByRef(false);
PE.setExpandForMC(OnlyExpandMCInstPredicates);
for (unsigned PI : ProcIndices) {