[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