diff options
author | Daniel Sanders <daniel_l_sanders@apple.com> | 2016-11-15 09:51:02 +0000 |
---|---|---|
committer | Daniel Sanders <daniel_l_sanders@apple.com> | 2016-11-15 09:51:02 +0000 |
commit | 57a599ec1a9846d7d8434a0ad21a45dc3bdbd56c (patch) | |
tree | 04e79bfc942d2716332a88afb3a9162b4890a118 /utils/TableGen/SubtargetFeatureInfo.cpp | |
parent | d9210062802343a6e48354dfbbaafe2bf42c2a91 (diff) |
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@286945 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen/SubtargetFeatureInfo.cpp')
-rw-r--r-- | utils/TableGen/SubtargetFeatureInfo.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/utils/TableGen/SubtargetFeatureInfo.cpp b/utils/TableGen/SubtargetFeatureInfo.cpp new file mode 100644 index 00000000000..2f9e881ef3a --- /dev/null +++ b/utils/TableGen/SubtargetFeatureInfo.cpp @@ -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"; +} |