Skip to content

Commit b5e06b5

Browse files
authored
[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.
1 parent dfa5bbe commit b5e06b5

File tree

4 files changed

+31
-55
lines changed

4 files changed

+31
-55
lines changed

llvm/test/TableGen/AsmPredicateCombining.td

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,19 @@ def AsmPred4 : Predicate<"Pred4">, AssemblerPredicate<(all_of AsmCond4, (not (an
6363
// MATCHER-NEXT: Features.set(Feature_AsmPred4Bit);
6464

6565
def insn1 : TestInsn<1, [AsmPred1]>;
66-
// DISASS: return (Bits[arch::AsmCond1]);
66+
// DISASS: return FB[arch::AsmCond1];
6767

6868
def insn2 : TestInsn<2, [AsmPred2]>;
69-
// DISASS: return (Bits[arch::AsmCond2a] && Bits[arch::AsmCond2b])
69+
// DISASS: return FB[arch::AsmCond2a] && FB[arch::AsmCond2b];
7070

7171
def insn3 : TestInsn<3, [AsmPred3]>;
72-
// DISASS: return (Bits[arch::AsmCond3a] || Bits[arch::AsmCond3b])
72+
// DISASS: return FB[arch::AsmCond3a] || FB[arch::AsmCond3b];
7373

7474
def insn4 : TestInsn<4, [AsmPred1, AsmPred2]>;
75-
// DISASS: return (Bits[arch::AsmCond1] && (Bits[arch::AsmCond2a] && Bits[arch::AsmCond2b]))
75+
// DISASS: return FB[arch::AsmCond1] && (FB[arch::AsmCond2a] && FB[arch::AsmCond2b]);
7676

7777
def insn5 : TestInsn<5, [AsmPred1, AsmPred3]>;
78-
// DISASS: return (Bits[arch::AsmCond1] && (Bits[arch::AsmCond3a] || Bits[arch::AsmCond3b]))
78+
// DISASS: return FB[arch::AsmCond1] && (FB[arch::AsmCond3a] || FB[arch::AsmCond3b]);
7979

8080
def insn6 : TestInsn<6, []>;
8181
def : InstAlias<"alias1", (insn6 R0)> { let Predicates = [AsmPred1]; }

llvm/test/TableGen/AsmPredicateCondsEmission.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ def foo : Instruction {
2929
let Predicates = [Pred1, Pred2];
3030
}
3131

32-
// CHECK: return (Bits[arch::AssemblerCondition2]);
32+
// CHECK: return FB[arch::AssemblerCondition2];

llvm/utils/TableGen/Common/SubtargetFeatureInfo.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,9 @@ void SubtargetFeatureInfo::emitMCPredicateCheck(
190190
bool ParenIfBinOp = range_size(MCPredicates) > 1;
191191
for (const Record *R : MCPredicates) {
192192
OS << LS;
193-
emitFeaturesAux(TargetName, *R->getValueAsDag("AssemblerCondDag"),
194-
ParenIfBinOp, OS);
193+
if (emitFeaturesAux(TargetName, *R->getValueAsDag("AssemblerCondDag"),
194+
ParenIfBinOp, OS))
195+
PrintFatalError(R, "Invalid AssemblerCondDag!");
195196
}
196197
}
197198

@@ -206,12 +207,14 @@ void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
206207
OS << "const ";
207208
OS << "{\n";
208209
OS << " FeatureBitset Features;\n";
209-
for (const auto &SF : SubtargetFeatures) {
210-
const SubtargetFeatureInfo &SFI = SF.second;
210+
for (const SubtargetFeatureInfo &SFI : make_second_range(SubtargetFeatures)) {
211+
const Record *Def = SFI.TheDef;
211212

212213
OS << " if (";
213-
emitFeaturesAux(TargetName, *SFI.TheDef->getValueAsDag("AssemblerCondDag"),
214-
/*ParenIfBinOp=*/false, OS);
214+
if (emitFeaturesAux(TargetName, *Def->getValueAsDag("AssemblerCondDag"),
215+
/*ParenIfBinOp=*/false, OS))
216+
PrintFatalError(Def, "Invalid AssemblerCondDag!");
217+
215218
OS << ")\n";
216219
OS << " Features.set(" << SFI.getEnumBitName() << ");\n";
217220
}

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 16 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "Common/CodeGenTarget.h"
1717
#include "Common/InfoByHwMode.h"
1818
#include "Common/InstructionEncoding.h"
19+
#include "Common/SubtargetFeatureInfo.h"
1920
#include "Common/VarLenCodeEmitterGen.h"
2021
#include "TableGenBackends.h"
2122
#include "llvm/ADT/APInt.h"
@@ -519,8 +520,6 @@ class DecoderTableBuilder {
519520

520521
bool emitPredicateMatch(raw_ostream &OS, unsigned EncodingID) const;
521522

522-
bool doesOpcodeNeedPredicate(unsigned EncodingID) const;
523-
524523
void emitPredicateTableEntry(unsigned EncodingID) const;
525524

526525
void emitSoftFailTableEntry(unsigned EncodingID) const;
@@ -839,12 +838,12 @@ void DecoderEmitter::emitPredicateFunction(formatted_raw_ostream &OS,
839838
// The predicate function is just a big switch statement based on the
840839
// input predicate index.
841840
OS << "static bool checkDecoderPredicate(unsigned Idx, const FeatureBitset "
842-
"&Bits) {\n";
841+
"&FB) {\n";
843842
OS << " switch (Idx) {\n";
844843
OS << " default: llvm_unreachable(\"Invalid index!\");\n";
845844
for (const auto &[Index, Predicate] : enumerate(Predicates)) {
846845
OS << " case " << Index << ":\n";
847-
OS << " return (" << Predicate << ");\n";
846+
OS << " return " << Predicate << ";\n";
848847
}
849848
OS << " }\n";
850849
OS << "}\n\n";
@@ -1134,41 +1133,19 @@ bool DecoderTableBuilder::emitPredicateMatchAux(const Init &Val,
11341133
return true;
11351134
}
11361135

1136+
// Returns true if there was any predicate emitted.
11371137
bool DecoderTableBuilder::emitPredicateMatch(raw_ostream &OS,
11381138
unsigned EncodingID) const {
1139-
const ListInit *Predicates =
1140-
Encodings[EncodingID].getRecord()->getValueAsListInit("Predicates");
1141-
bool IsFirstEmission = true;
1142-
for (unsigned i = 0; i < Predicates->size(); ++i) {
1143-
const Record *Pred = Predicates->getElementAsRecord(i);
1144-
if (!Pred->getValue("AssemblerMatcherPredicate"))
1145-
continue;
1146-
1147-
if (!isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
1148-
continue;
1149-
1150-
if (!IsFirstEmission)
1151-
OS << " && ";
1152-
if (emitPredicateMatchAux(*Pred->getValueAsDag("AssemblerCondDag"),
1153-
Predicates->size() > 1, OS))
1154-
PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
1155-
IsFirstEmission = false;
1156-
}
1157-
return !Predicates->empty();
1158-
}
1159-
1160-
bool DecoderTableBuilder::doesOpcodeNeedPredicate(unsigned EncodingID) const {
1161-
const ListInit *Predicates =
1162-
Encodings[EncodingID].getRecord()->getValueAsListInit("Predicates");
1163-
for (unsigned i = 0; i < Predicates->size(); ++i) {
1164-
const Record *Pred = Predicates->getElementAsRecord(i);
1165-
if (!Pred->getValue("AssemblerMatcherPredicate"))
1166-
continue;
1167-
1168-
if (isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
1169-
return true;
1170-
}
1171-
return false;
1139+
std::vector<const Record *> Predicates =
1140+
Encodings[EncodingID].getRecord()->getValueAsListOfDefs("Predicates");
1141+
auto It = llvm::find_if(Predicates, [](const Record *R) {
1142+
return R->getValueAsBit("AssemblerMatcherPredicate");
1143+
});
1144+
bool AnyAsmPredicate = It != Predicates.end();
1145+
if (!AnyAsmPredicate)
1146+
return false;
1147+
SubtargetFeatureInfo::emitMCPredicateCheck(OS, Target.getName(), Predicates);
1148+
return true;
11721149
}
11731150

11741151
unsigned DecoderTableBuilder::getPredicateIndex(StringRef Predicate) const {
@@ -1186,15 +1163,11 @@ unsigned DecoderTableBuilder::getPredicateIndex(StringRef Predicate) const {
11861163
}
11871164

11881165
void DecoderTableBuilder::emitPredicateTableEntry(unsigned EncodingID) const {
1189-
if (!doesOpcodeNeedPredicate(EncodingID))
1190-
return;
1191-
11921166
// Build up the predicate string.
11931167
SmallString<256> Predicate;
1194-
// FIXME: emitPredicateMatch() functions can take a buffer directly rather
1195-
// than a stream.
11961168
raw_svector_ostream PS(Predicate);
1197-
emitPredicateMatch(PS, EncodingID);
1169+
if (!emitPredicateMatch(PS, EncodingID))
1170+
return;
11981171

11991172
// Figure out the index into the predicate table for the predicate just
12001173
// computed.

0 commit comments

Comments
 (0)