OSDN Git Service

[Tablegen][MCInstPredicate] Removed redundant template argument from class TIIPredica...
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Tue, 14 Aug 2018 18:36:54 +0000 (18:36 +0000)
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Tue, 14 Aug 2018 18:36:54 +0000 (18:36 +0000)
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

include/llvm/Target/TargetInstrPredicate.td
lib/Target/X86/X86SchedPredicates.td
utils/TableGen/CodeGenSchedule.cpp
utils/TableGen/CodeGenSchedule.h
utils/TableGen/InstrInfoEmitter.cpp
utils/TableGen/PredicateExpander.cpp
utils/TableGen/PredicateExpander.h
utils/TableGen/SubtargetEmitter.cpp

index 8925e4b..4191efb 100644 (file)
@@ -198,19 +198,24 @@ class MCOpcodeSwitchStatement<list<MCOpcodeSwitchCase> cases,
   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.
index abb8611..11b567c 100644 (file)
@@ -53,4 +53,4 @@ def IsThreeOperandsLEABody :
 // 3-operands LEA.  Tablegen automatically generates a new method for it in
 // X86GenInstrInfo.
 def IsThreeOperandsLEAFn :
-    TIIPredicate<"X86", "isThreeOperandsLEA", IsThreeOperandsLEABody>;
+    TIIPredicate<"isThreeOperandsLEA", IsThreeOperandsLEABody>;
index 9331fad..7b96f08 100644 (file)
@@ -222,9 +222,36 @@ CodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK,
   // 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");
 
index 07c1159..112ae08 100644 (file)
@@ -465,6 +465,8 @@ private:
 
   void inferSchedClasses();
 
+  void checkMCInstPredicates() const;
+  
   void checkCompleteness();
 
   void inferFromRW(ArrayRef<unsigned> OperWrites, ArrayRef<unsigned> OperReads,
index 2f2d301..3468015 100644 (file)
@@ -66,11 +66,11 @@ 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);
+  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,
@@ -351,14 +351,12 @@ void InstrInfoEmitter::emitOperandTypesEnum(raw_ostream &OS,
   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";
 
@@ -383,7 +381,7 @@ void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS) {
   OS << "namespace llvm {\n";
   OS << "namespace " << TargetName << "_MC {\n\n";
 
-  PredicateExpander PE;
+  PredicateExpander PE(TargetName);
   PE.setExpandForMC(true);
 
   for (const Record *Rec : TIIPredicates) {
@@ -401,12 +399,13 @@ void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS) {
   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);
 
@@ -518,7 +517,7 @@ 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);
+  emitTIIHelperMethods(OS, TargetName);
 
   OS << "\n};\n} // end llvm namespace\n";
 
@@ -545,7 +544,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
 
   emitOperandTypesEnum(OS, Target);
 
-  emitMCIIHelperMethods(OS);
+  emitMCIIHelperMethods(OS, TargetName);
 }
 
 void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
index ab0e67a..0882ab8 100644 (file)
@@ -134,14 +134,9 @@ void PredicateExpander::expandPredicateSequence(raw_ostream &OS,
 }
 
 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)");
 }
 
@@ -313,8 +308,7 @@ void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
     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");
 }
index b39452f..9337a0f 100644 (file)
@@ -30,14 +30,15 @@ class PredicateExpander {
   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; }
@@ -65,8 +66,7 @@ public:
   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);
index 1651891..5153bba 100644 (file)
@@ -1616,7 +1616,7 @@ void SubtargetEmitter::emitSchedModelHelpersImpl(
 
     OS << "  case " << VC << ": // " << SC.Name << '\n';
 
-    PredicateExpander PE;
+    PredicateExpander PE(Target);
     PE.setByRef(false);
     PE.setExpandForMC(OnlyExpandMCInstPredicates);
     for (unsigned PI : ProcIndices) {