diff --git a/llvm/test/TableGen/AsmPredicateCombining.td b/llvm/test/TableGen/AsmPredicateCombining.td index c8081a428d7bb..c68647928efce 100644 --- a/llvm/test/TableGen/AsmPredicateCombining.td +++ b/llvm/test/TableGen/AsmPredicateCombining.td @@ -63,19 +63,19 @@ def AsmPred4 : Predicate<"Pred4">, AssemblerPredicate<(all_of AsmCond4, (not (an // MATCHER-NEXT: Features.set(Feature_AsmPred4Bit); def insn1 : TestInsn<1, [AsmPred1]>; -// DISASS: return (Bits[arch::AsmCond1]); +// DISASS: return FB[arch::AsmCond1]; def insn2 : TestInsn<2, [AsmPred2]>; -// DISASS: return (Bits[arch::AsmCond2a] && Bits[arch::AsmCond2b]) +// DISASS: return FB[arch::AsmCond2a] && FB[arch::AsmCond2b]; def insn3 : TestInsn<3, [AsmPred3]>; -// DISASS: return (Bits[arch::AsmCond3a] || Bits[arch::AsmCond3b]) +// DISASS: return FB[arch::AsmCond3a] || FB[arch::AsmCond3b]; def insn4 : TestInsn<4, [AsmPred1, AsmPred2]>; -// DISASS: return (Bits[arch::AsmCond1] && (Bits[arch::AsmCond2a] && Bits[arch::AsmCond2b])) +// DISASS: return FB[arch::AsmCond1] && (FB[arch::AsmCond2a] && FB[arch::AsmCond2b]); def insn5 : TestInsn<5, [AsmPred1, AsmPred3]>; -// DISASS: return (Bits[arch::AsmCond1] && (Bits[arch::AsmCond3a] || Bits[arch::AsmCond3b])) +// DISASS: return FB[arch::AsmCond1] && (FB[arch::AsmCond3a] || FB[arch::AsmCond3b]); def insn6 : TestInsn<6, []>; def : InstAlias<"alias1", (insn6 R0)> { let Predicates = [AsmPred1]; } diff --git a/llvm/test/TableGen/AsmPredicateCondsEmission.td b/llvm/test/TableGen/AsmPredicateCondsEmission.td index 7b2ab2afa5a8d..25bc1ab95a14f 100644 --- a/llvm/test/TableGen/AsmPredicateCondsEmission.td +++ b/llvm/test/TableGen/AsmPredicateCondsEmission.td @@ -29,4 +29,4 @@ def foo : Instruction { let Predicates = [Pred1, Pred2]; } -// CHECK: return (Bits[arch::AssemblerCondition2]); +// CHECK: return FB[arch::AssemblerCondition2]; diff --git a/llvm/utils/TableGen/Common/SubtargetFeatureInfo.cpp b/llvm/utils/TableGen/Common/SubtargetFeatureInfo.cpp index bd8af32ee5096..a426bf4ef4b77 100644 --- a/llvm/utils/TableGen/Common/SubtargetFeatureInfo.cpp +++ b/llvm/utils/TableGen/Common/SubtargetFeatureInfo.cpp @@ -190,8 +190,9 @@ void SubtargetFeatureInfo::emitMCPredicateCheck( bool ParenIfBinOp = range_size(MCPredicates) > 1; for (const Record *R : MCPredicates) { OS << LS; - emitFeaturesAux(TargetName, *R->getValueAsDag("AssemblerCondDag"), - ParenIfBinOp, OS); + if (emitFeaturesAux(TargetName, *R->getValueAsDag("AssemblerCondDag"), + ParenIfBinOp, OS)) + PrintFatalError(R, "Invalid AssemblerCondDag!"); } } @@ -206,12 +207,14 @@ void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures( OS << "const "; OS << "{\n"; OS << " FeatureBitset Features;\n"; - for (const auto &SF : SubtargetFeatures) { - const SubtargetFeatureInfo &SFI = SF.second; + for (const SubtargetFeatureInfo &SFI : make_second_range(SubtargetFeatures)) { + const Record *Def = SFI.TheDef; OS << " if ("; - emitFeaturesAux(TargetName, *SFI.TheDef->getValueAsDag("AssemblerCondDag"), - /*ParenIfBinOp=*/false, OS); + if (emitFeaturesAux(TargetName, *Def->getValueAsDag("AssemblerCondDag"), + /*ParenIfBinOp=*/false, OS)) + PrintFatalError(Def, "Invalid AssemblerCondDag!"); + OS << ")\n"; OS << " Features.set(" << SFI.getEnumBitName() << ");\n"; } diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp index 1829f05432e3b..97a6b58e1bd99 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 @@ class DecoderTableBuilder { 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(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(Pred->getValue("AssemblerCondDag")->getValue())) - return true; - } - return false; + std::vector 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.