aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/DecoderEmitter.cpp
diff options
context:
space:
mode:
authorRahul Joshi <rjoshi@nvidia.com>2025-09-15 19:23:07 -0700
committerGitHub <noreply@github.com>2025-09-15 19:23:07 -0700
commitb5e06b5ede8e29a3db34ce740b249bb22dbf76a1 (patch)
tree4245ba2f97e02aed86f92770cf65be6d1b73d880 /llvm/utils/TableGen/DecoderEmitter.cpp
parentdfa5bbeafaff2bbb211cde2980cc5f29906d8fac (diff)
downloadllvm-b5e06b5ede8e29a3db34ce740b249bb22dbf76a1.zip
llvm-b5e06b5ede8e29a3db34ce740b249bb22dbf76a1.tar.gz
llvm-b5e06b5ede8e29a3db34ce740b249bb22dbf76a1.tar.bz2
[NFC][DecoderEmitter] Predicate generation code cleanup (#158140)
Eliminate `doesOpcodeNeedPredicate` and instead have `emitPredicateMatch` return true if any predicates were generated. Delegate actual predicate generation in `emitPredicateMatch` to `SubtargetFeatureInfo::emitMCPredicateCheck`. Additionally, remove the redundant parenthesis around the predicate conditions in the generated `checkDecoderPredicate` function. Note that for ARM/AMDGPU this reduces the total # of predicates generated by a few. It seems the old code would sometimes generate duplicate predicates which were identical in semantics but one had an extra pair of parentheses (i..e, `X` and `(X)`). `emitMCPredicateCheck` does not seems to have that issue.
Diffstat (limited to 'llvm/utils/TableGen/DecoderEmitter.cpp')
-rw-r--r--llvm/utils/TableGen/DecoderEmitter.cpp59
1 files changed, 16 insertions, 43 deletions
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 1829f054..97a6b58 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -16,6 +16,7 @@
#include "Common/CodeGenTarget.h"
#include "Common/InfoByHwMode.h"
#include "Common/InstructionEncoding.h"
+#include "Common/SubtargetFeatureInfo.h"
#include "Common/VarLenCodeEmitterGen.h"
#include "TableGenBackends.h"
#include "llvm/ADT/APInt.h"
@@ -519,8 +520,6 @@ private:
bool emitPredicateMatch(raw_ostream &OS, unsigned EncodingID) const;
- bool doesOpcodeNeedPredicate(unsigned EncodingID) const;
-
void emitPredicateTableEntry(unsigned EncodingID) const;
void emitSoftFailTableEntry(unsigned EncodingID) const;
@@ -839,12 +838,12 @@ void DecoderEmitter::emitPredicateFunction(formatted_raw_ostream &OS,
// The predicate function is just a big switch statement based on the
// input predicate index.
OS << "static bool checkDecoderPredicate(unsigned Idx, const FeatureBitset "
- "&Bits) {\n";
+ "&FB) {\n";
OS << " switch (Idx) {\n";
OS << " default: llvm_unreachable(\"Invalid index!\");\n";
for (const auto &[Index, Predicate] : enumerate(Predicates)) {
OS << " case " << Index << ":\n";
- OS << " return (" << Predicate << ");\n";
+ OS << " return " << Predicate << ";\n";
}
OS << " }\n";
OS << "}\n\n";
@@ -1134,41 +1133,19 @@ bool DecoderTableBuilder::emitPredicateMatchAux(const Init &Val,
return true;
}
+// Returns true if there was any predicate emitted.
bool DecoderTableBuilder::emitPredicateMatch(raw_ostream &OS,
unsigned EncodingID) const {
- const ListInit *Predicates =
- Encodings[EncodingID].getRecord()->getValueAsListInit("Predicates");
- bool IsFirstEmission = true;
- for (unsigned i = 0; i < Predicates->size(); ++i) {
- const Record *Pred = Predicates->getElementAsRecord(i);
- if (!Pred->getValue("AssemblerMatcherPredicate"))
- continue;
-
- if (!isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
- continue;
-
- if (!IsFirstEmission)
- OS << " && ";
- if (emitPredicateMatchAux(*Pred->getValueAsDag("AssemblerCondDag"),
- Predicates->size() > 1, OS))
- PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
- IsFirstEmission = false;
- }
- return !Predicates->empty();
-}
-
-bool DecoderTableBuilder::doesOpcodeNeedPredicate(unsigned EncodingID) const {
- const ListInit *Predicates =
- Encodings[EncodingID].getRecord()->getValueAsListInit("Predicates");
- for (unsigned i = 0; i < Predicates->size(); ++i) {
- const Record *Pred = Predicates->getElementAsRecord(i);
- if (!Pred->getValue("AssemblerMatcherPredicate"))
- continue;
-
- if (isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
- return true;
- }
- return false;
+ std::vector<const Record *> Predicates =
+ Encodings[EncodingID].getRecord()->getValueAsListOfDefs("Predicates");
+ auto It = llvm::find_if(Predicates, [](const Record *R) {
+ return R->getValueAsBit("AssemblerMatcherPredicate");
+ });
+ bool AnyAsmPredicate = It != Predicates.end();
+ if (!AnyAsmPredicate)
+ return false;
+ SubtargetFeatureInfo::emitMCPredicateCheck(OS, Target.getName(), Predicates);
+ return true;
}
unsigned DecoderTableBuilder::getPredicateIndex(StringRef Predicate) const {
@@ -1186,15 +1163,11 @@ unsigned DecoderTableBuilder::getPredicateIndex(StringRef Predicate) const {
}
void DecoderTableBuilder::emitPredicateTableEntry(unsigned EncodingID) const {
- if (!doesOpcodeNeedPredicate(EncodingID))
- return;
-
// Build up the predicate string.
SmallString<256> Predicate;
- // FIXME: emitPredicateMatch() functions can take a buffer directly rather
- // than a stream.
raw_svector_ostream PS(Predicate);
- emitPredicateMatch(PS, EncodingID);
+ if (!emitPredicateMatch(PS, EncodingID))
+ return;
// Figure out the index into the predicate table for the predicate just
// computed.