[llvm] r286945 - [tablegen] Extract portions of AsmMatcherEmitter for re-use by another generator. NFC.

Daniel Sanders via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 15 01:51:03 PST 2016


Author: dsanders
Date: Tue Nov 15 03:51:02 2016
New Revision: 286945

URL: http://llvm.org/viewvc/llvm-project?rev=286945&view=rev
Log:
[tablegen] Extract portions of AsmMatcherEmitter for re-use by another generator. NFC.

Summary:
This change is preparation for a change that will allow targets to verify that the instructions
they emit meet the predicates they specify. This is useful to ensure that C++
legalization/lowering/instruction-selection doesn't incorrectly select code for a different
subtarget than intended. Such cases are not caught by the integrated assembler when emitting
instructions directly to an object file.

Reviewers: qcolombet

Subscribers: qcolombet, beanz, mgorny, llvm-commits, modocache

Differential Revision: https://reviews.llvm.org/D25614

Added:
    llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp
    llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h
Modified:
    llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
    llvm/trunk/utils/TableGen/CMakeLists.txt

Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=286945&r1=286944&r2=286945&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Tue Nov 15 03:51:02 2016
@@ -97,6 +97,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "CodeGenTarget.h"
+#include "SubtargetFeatureInfo.h"
 #include "llvm/ADT/CachedHashString.h"
 #include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/STLExtras.h"
@@ -127,7 +128,6 @@ MatchPrefix("match-prefix", cl::init("")
 
 namespace {
 class AsmMatcherInfo;
-struct SubtargetFeatureInfo;
 
 // Register sets are used as keys in some second-order sets TableGen creates
 // when generating its data structures. This means that the order of two
@@ -652,28 +652,6 @@ private:
   void addAsmOperand(StringRef Token, bool IsIsolatedToken = false);
 };
 
-/// SubtargetFeatureInfo - Helper class for storing information on a subtarget
-/// feature which participates in instruction matching.
-struct SubtargetFeatureInfo {
-  /// \brief The predicate record for this feature.
-  Record *TheDef;
-
-  /// \brief An unique index assigned to represent this feature.
-  uint64_t Index;
-
-  SubtargetFeatureInfo(Record *D, uint64_t Idx) : TheDef(D), Index(Idx) {}
-
-  /// \brief The name of the enumerated constant identifying this feature.
-  std::string getEnumName() const {
-    return "Feature_" + TheDef->getName();
-  }
-
-  void dump() const {
-    errs() << getEnumName() << " " << Index << "\n";
-    TheDef->dump();
-  }
-};
-
 struct OperandMatchEntry {
   unsigned OperandMask;
   const MatchableInfo* MI;
@@ -753,7 +731,7 @@ public:
                  CodeGenTarget &Target,
                  RecordKeeper &Records);
 
-  /// buildInfo - Construct the various tables used during matching.
+  /// Construct the various tables used during matching.
   void buildInfo();
 
   /// buildOperandMatchInfo - Build the necessary information to handle user
@@ -1436,21 +1414,13 @@ void AsmMatcherInfo::buildOperandMatchIn
 
 void AsmMatcherInfo::buildInfo() {
   // Build information about all of the AssemblerPredicates.
-  std::vector<Record*> AllPredicates =
-    Records.getAllDerivedDefinitions("Predicate");
-  for (Record *Pred : AllPredicates) {
-    // Ignore predicates that are not intended for the assembler.
-    if (!Pred->getValueAsBit("AssemblerMatcherPredicate"))
-      continue;
-
-    if (Pred->getName().empty())
-      PrintFatalError(Pred->getLoc(), "Predicate has no name!");
-
-    SubtargetFeatures.insert(std::make_pair(
-        Pred, SubtargetFeatureInfo(Pred, SubtargetFeatures.size())));
-    DEBUG(SubtargetFeatures.find(Pred)->second.dump());
-    assert(SubtargetFeatures.size() <= 64 && "Too many subtarget features!");
-  }
+  const std::vector<std::pair<Record *, SubtargetFeatureInfo>>
+      &SubtargetFeaturePairs = SubtargetFeatureInfo::getAll(Records);
+  SubtargetFeatures.insert(SubtargetFeaturePairs.begin(),
+                           SubtargetFeaturePairs.end());
+  for (const auto &Pair : SubtargetFeatures)
+    DEBUG(Pair.second.dump());
+  assert(SubtargetFeatures.size() <= 64 && "Too many subtarget features!");
 
   bool HasMnemonicFirst = AsmParser->getValueAsBit("HasMnemonicFirst");
 
@@ -2465,55 +2435,6 @@ static void emitGetSubtargetFeatureName(
   OS << "}\n\n";
 }
 
-/// emitComputeAvailableFeatures - Emit the function to compute the list of
-/// available features given a subtarget.
-static void emitComputeAvailableFeatures(AsmMatcherInfo &Info,
-                                         raw_ostream &OS) {
-  std::string ClassName =
-    Info.AsmParser->getValueAsString("AsmParserClassName");
-
-  OS << "uint64_t " << Info.Target.getName() << ClassName << "::\n"
-     << "ComputeAvailableFeatures(const FeatureBitset& FB) const {\n";
-  OS << "  uint64_t Features = 0;\n";
-  for (const auto &SF : Info.SubtargetFeatures) {
-    const SubtargetFeatureInfo &SFI = SF.second;
-
-    OS << "  if (";
-    std::string CondStorage =
-      SFI.TheDef->getValueAsString("AssemblerCondString");
-    StringRef Conds = CondStorage;
-    std::pair<StringRef,StringRef> Comma = Conds.split(',');
-    bool First = true;
-    do {
-      if (!First)
-        OS << " && ";
-
-      bool Neg = false;
-      StringRef Cond = Comma.first;
-      if (Cond[0] == '!') {
-        Neg = true;
-        Cond = Cond.substr(1);
-      }
-
-      OS << "(";
-      if (Neg)
-        OS << "!";
-      OS << "FB[" << Info.Target.getName() << "::" << Cond << "])";
-
-      if (Comma.second.empty())
-        break;
-
-      First = false;
-      Comma = Comma.second.split(',');
-    } while (true);
-
-    OS << ")\n";
-    OS << "    Features |= " << SFI.getEnumName() << ";\n";
-  }
-  OS << "  return Features;\n";
-  OS << "}\n\n";
-}
-
 static std::string GetAliasRequiredFeatures(Record *R,
                                             const AsmMatcherInfo &Info) {
   std::vector<Record*> ReqFeatures = R->getValueAsListOfDefs("Predicates");
@@ -2969,7 +2890,8 @@ void AsmMatcherEmitter::run(raw_ostream
   emitValidateOperandClass(Info, OS);
 
   // Emit the available features compute function.
-  emitComputeAvailableFeatures(Info, OS);
+  SubtargetFeatureInfo::emitComputeAvailableFeatures(
+      Info.Target.getName(), ClassName, Info.SubtargetFeatures, OS);
 
   StringToOffsetTable StringTable;
 

Modified: llvm/trunk/utils/TableGen/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CMakeLists.txt?rev=286945&r1=286944&r2=286945&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CMakeLists.txt (original)
+++ llvm/trunk/utils/TableGen/CMakeLists.txt Tue Nov 15 03:51:02 2016
@@ -29,6 +29,7 @@ add_tablegen(llvm-tblgen LLVM
   RegisterInfoEmitter.cpp
   SearchableTableEmitter.cpp
   SubtargetEmitter.cpp
+  SubtargetFeatureInfo.cpp
   TableGen.cpp
   X86DisassemblerTables.cpp
   X86ModRMFilters.cpp

Added: llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp?rev=286945&view=auto
==============================================================================
--- llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp (added)
+++ llvm/trunk/utils/TableGen/SubtargetFeatureInfo.cpp Tue Nov 15 03:51:02 2016
@@ -0,0 +1,89 @@
+//===- SubtargetFeatureInfo.cpp - Helpers for subtarget features ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SubtargetFeatureInfo.h"
+
+#include "llvm/TableGen/Record.h"
+
+#include <map>
+
+using namespace llvm;
+
+void SubtargetFeatureInfo::dump() const {
+  errs() << getEnumName() << " " << Index << "\n";
+  TheDef->dump();
+}
+
+std::vector<std::pair<Record *, SubtargetFeatureInfo>>
+SubtargetFeatureInfo::getAll(const RecordKeeper &Records) {
+  std::vector<std::pair<Record *, SubtargetFeatureInfo>> SubtargetFeatures;
+  std::vector<Record *> AllPredicates =
+      Records.getAllDerivedDefinitions("Predicate");
+  for (Record *Pred : AllPredicates) {
+    // Ignore predicates that are not intended for the assembler.
+    //
+    // The "AssemblerMatcherPredicate" string should be promoted to an argument
+    // if we re-use the machinery for non-assembler purposes in future.
+    if (!Pred->getValueAsBit("AssemblerMatcherPredicate"))
+      continue;
+
+    if (Pred->getName().empty())
+      PrintFatalError(Pred->getLoc(), "Predicate has no name!");
+
+    SubtargetFeatures.emplace_back(
+        Pred, SubtargetFeatureInfo(Pred, SubtargetFeatures.size()));
+  }
+  return SubtargetFeatures;
+}
+
+void SubtargetFeatureInfo::emitComputeAvailableFeatures(
+    StringRef TargetName, StringRef ClassName,
+    std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
+    raw_ostream &OS) {
+  OS << "uint64_t " << TargetName << ClassName << "::\n"
+     << "ComputeAvailableFeatures(const FeatureBitset& FB) const {\n";
+  OS << "  uint64_t Features = 0;\n";
+  for (const auto &SF : SubtargetFeatures) {
+    const SubtargetFeatureInfo &SFI = SF.second;
+
+    OS << "  if (";
+    std::string CondStorage =
+        SFI.TheDef->getValueAsString("AssemblerCondString");
+    StringRef Conds = CondStorage;
+    std::pair<StringRef, StringRef> Comma = Conds.split(',');
+    bool First = true;
+    do {
+      if (!First)
+        OS << " && ";
+
+      bool Neg = false;
+      StringRef Cond = Comma.first;
+      if (Cond[0] == '!') {
+        Neg = true;
+        Cond = Cond.substr(1);
+      }
+
+      OS << "(";
+      if (Neg)
+        OS << "!";
+      OS << "FB[" << TargetName << "::" << Cond << "])";
+
+      if (Comma.second.empty())
+        break;
+
+      First = false;
+      Comma = Comma.second.split(',');
+    } while (true);
+
+    OS << ")\n";
+    OS << "    Features |= " << SFI.getEnumName() << ";\n";
+  }
+  OS << "  return Features;\n";
+  OS << "}\n\n";
+}

Added: llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h?rev=286945&view=auto
==============================================================================
--- llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h (added)
+++ llvm/trunk/utils/TableGen/SubtargetFeatureInfo.h Tue Nov 15 03:51:02 2016
@@ -0,0 +1,57 @@
+//===- SubtargetFeatureInfo.h - Helpers for subtarget features ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_UTIL_TABLEGEN_SUBTARGETFEATUREINFO_H
+#define LLVM_UTIL_TABLEGEN_SUBTARGETFEATUREINFO_H
+
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+
+#include <map>
+
+namespace llvm {
+class Record;
+class RecordKeeper;
+
+/// Helper class for storing information on a subtarget feature which
+/// participates in instruction matching.
+struct SubtargetFeatureInfo {
+  /// \brief The predicate record for this feature.
+  Record *TheDef;
+
+  /// \brief An unique index assigned to represent this feature.
+  uint64_t Index;
+
+  SubtargetFeatureInfo(Record *D, uint64_t Idx) : TheDef(D), Index(Idx) {}
+
+  /// \brief The name of the enumerated constant identifying this feature.
+  std::string getEnumName() const { return "Feature_" + TheDef->getName(); }
+
+  void dump() const;
+  static std::vector<std::pair<Record *, SubtargetFeatureInfo>>
+  getAll(const RecordKeeper &Records);
+
+  /// Emit the function to compute the list of available features given a
+  /// subtarget.
+  ///
+  /// \param TargetName The name of the target as used in class prefixes (e.g.
+  ///                   <TargetName>Subtarget)
+  /// \param ClassName  The name of the class (without the <Target> prefix)
+  ///                   that will contain the generated functions.
+  /// \param SubtargetFeatures A map of TableGen records to the
+  ///                          SubtargetFeatureInfo equivalent.
+  static void emitComputeAvailableFeatures(
+      StringRef TargetName, StringRef ClassName,
+      std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
+          &SubtargetFeatures,
+      raw_ostream &OS);
+};
+} // end namespace llvm
+
+#endif // LLVM_UTIL_TABLEGEN_SUBTARGETFEATUREINFO_H




More information about the llvm-commits mailing list