aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/DecoderEmitter.cpp
diff options
context:
space:
mode:
authorSergei Barannikov <barannikov88@gmail.com>2025-08-20 14:34:59 +0300
committerGitHub <noreply@github.com>2025-08-20 11:34:59 +0000
commit19ac1ff56e20ec1ea4db27e03c784146d44edd9e (patch)
tree7809c83c81a1b7745f77180ef9d0ef4506639ba2 /llvm/utils/TableGen/DecoderEmitter.cpp
parentb01f05977ce65dc71fed07cd64684a182e983533 (diff)
downloadllvm-19ac1ff56e20ec1ea4db27e03c784146d44edd9e.zip
llvm-19ac1ff56e20ec1ea4db27e03c784146d44edd9e.tar.gz
llvm-19ac1ff56e20ec1ea4db27e03c784146d44edd9e.tar.bz2
[TableGen][DecoderEmitter] Factor populateFixedLenEncoding (NFC) (#154511)
Also drop the debug code under `#if 0` and a seemingly outdated comment.
Diffstat (limited to 'llvm/utils/TableGen/DecoderEmitter.cpp')
-rw-r--r--llvm/utils/TableGen/DecoderEmitter.cpp220
1 files changed, 99 insertions, 121 deletions
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 1924cf8..1962055 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -156,7 +156,14 @@ public:
Name = (EncodingDef->getName() + Twine(':')).str();
Name.append(InstDef->getName());
- BitWidth = populateEncoding();
+ StringRef DecoderMethod = EncodingDef->getValueAsString("DecoderMethod");
+ if (!DecoderMethod.empty()) {
+ bool HasCompleteDecoder =
+ EncodingDef->getValueAsBit("hasCompleteDecoder");
+ Operands.push_back(OperandInfo(DecoderMethod.str(), HasCompleteDecoder));
+ }
+
+ populateEncoding();
}
/// Returns the Record this encoding originates from.
@@ -175,9 +182,9 @@ public:
ArrayRef<OperandInfo> getOperands() const { return Operands; }
private:
- void populateVarLenEncoding();
-
- unsigned populateEncoding();
+ void populateVarLenEncoding(const VarLenInst &VLI);
+ void populateFixedLenEncoding(const BitsInit &Bits);
+ void populateEncoding();
};
typedef std::vector<uint32_t> FixupList;
@@ -1862,9 +1869,7 @@ OperandInfo getOpInfo(const Record *TypeRecord) {
return OperandInfo(findOperandDecoderMethod(TypeRecord), HasCompleteDecoder);
}
-void InstructionEncoding::populateVarLenEncoding() {
- const RecordVal *RV = EncodingDef->getValue("Inst");
- VarLenInst VLI(cast<DagInit>(RV->getValue()), RV);
+void InstructionEncoding::populateVarLenEncoding(const VarLenInst &VLI) {
SmallVector<int> TiedTo;
for (const auto &[Idx, Op] : enumerate(Inst->Operands)) {
@@ -1961,28 +1966,9 @@ static void addOneOperandFields(const Record *EncodingDef, const BitsInit &Bits,
}
}
-unsigned InstructionEncoding::populateEncoding() {
- bool IsVarLenInst = isa<DagInit>(EncodingDef->getValueInit("Inst"));
+void InstructionEncoding::populateFixedLenEncoding(const BitsInit &Bits) {
const Record &Def = *Inst->TheDef;
- const BitsInit &Bits = getBitsField(*EncodingDef, "Inst");
- assert(!Bits.allInComplete() &&
- "Invalid encodings should have been filtered out");
-
- // If the instruction has specified a custom decoding hook, use that instead
- // of trying to auto-generate the decoder.
- StringRef InstDecoder = EncodingDef->getValueAsString("DecoderMethod");
- if (!InstDecoder.empty()) {
- bool HasCompleteInstDecoder =
- EncodingDef->getValueAsBit("hasCompleteDecoder");
- Operands.push_back(OperandInfo(InstDecoder.str(), HasCompleteInstDecoder));
- return Bits.getNumBits();
- }
-
- // Generate a description of the operand of the instruction that we know
- // how to decode automatically.
- // FIXME: We'll need to have a way to manually override this as needed.
-
// Gather the outputs/inputs of the instruction, so we can find their
// positions in the encoding. This assumes for now that they appear in the
// MCInst in the order that they're listed.
@@ -2015,108 +2001,100 @@ unsigned InstructionEncoding::populateEncoding() {
}
}
- if (IsVarLenInst) {
- populateVarLenEncoding();
- } else {
- // For each operand, see if we can figure out where it is encoded.
- for (const auto &Op : InOutOperands) {
- const Init *OpInit = Op.first;
- StringRef OpName = Op.second;
-
- // We're ready to find the instruction encoding locations for this
- // operand.
-
- // First, find the operand type ("OpInit"), and sub-op names
- // ("SubArgDag") if present.
- const DagInit *SubArgDag = dyn_cast<DagInit>(OpInit);
- if (SubArgDag)
- OpInit = SubArgDag->getOperator();
- const Record *OpTypeRec = cast<DefInit>(OpInit)->getDef();
- // Lookup the sub-operands from the operand type record (note that only
- // Operand subclasses have MIOperandInfo, see CodeGenInstruction.cpp).
- const DagInit *SubOps = OpTypeRec->isSubClassOf("Operand")
- ? OpTypeRec->getValueAsDag("MIOperandInfo")
- : nullptr;
-
- // Lookup the decoder method and construct a new OperandInfo to hold our
- // result.
- OperandInfo OpInfo = getOpInfo(OpTypeRec);
-
- // If we have named sub-operands...
- if (SubArgDag) {
- // Then there should not be a custom decoder specified on the top-level
- // type.
- if (!OpInfo.Decoder.empty()) {
- PrintError(EncodingDef,
- "DecoderEmitter: operand \"" + OpName + "\" has type \"" +
- OpInit->getAsString() +
- "\" with a custom DecoderMethod, but also named "
- "sub-operands.");
- continue;
- }
-
- // Decode each of the sub-ops separately.
- assert(SubOps && SubArgDag->getNumArgs() == SubOps->getNumArgs());
- for (const auto &[I, Arg] : enumerate(SubOps->getArgs())) {
- StringRef SubOpName = SubArgDag->getArgNameStr(I);
- OperandInfo SubOpInfo = getOpInfo(cast<DefInit>(Arg)->getDef());
-
- addOneOperandFields(EncodingDef, Bits, TiedNames, SubOpName,
- SubOpInfo);
- Operands.push_back(std::move(SubOpInfo));
- }
+ // For each operand, see if we can figure out where it is encoded.
+ for (const auto &Op : InOutOperands) {
+ const Init *OpInit = Op.first;
+ StringRef OpName = Op.second;
+
+ // We're ready to find the instruction encoding locations for this
+ // operand.
+
+ // First, find the operand type ("OpInit"), and sub-op names
+ // ("SubArgDag") if present.
+ const DagInit *SubArgDag = dyn_cast<DagInit>(OpInit);
+ if (SubArgDag)
+ OpInit = SubArgDag->getOperator();
+ const Record *OpTypeRec = cast<DefInit>(OpInit)->getDef();
+ // Lookup the sub-operands from the operand type record (note that only
+ // Operand subclasses have MIOperandInfo, see CodeGenInstruction.cpp).
+ const DagInit *SubOps = OpTypeRec->isSubClassOf("Operand")
+ ? OpTypeRec->getValueAsDag("MIOperandInfo")
+ : nullptr;
+
+ // Lookup the decoder method and construct a new OperandInfo to hold our
+ // result.
+ OperandInfo OpInfo = getOpInfo(OpTypeRec);
+
+ // If we have named sub-operands...
+ if (SubArgDag) {
+ // Then there should not be a custom decoder specified on the top-level
+ // type.
+ if (!OpInfo.Decoder.empty()) {
+ PrintError(EncodingDef,
+ "DecoderEmitter: operand \"" + OpName + "\" has type \"" +
+ OpInit->getAsString() +
+ "\" with a custom DecoderMethod, but also named "
+ "sub-operands.");
continue;
}
- // Otherwise, if we have an operand with sub-operands, but they aren't
- // named...
- if (SubOps && OpInfo.Decoder.empty()) {
- // If it's a single sub-operand, and no custom decoder, use the decoder
- // from the one sub-operand.
- if (SubOps->getNumArgs() == 1)
- OpInfo = getOpInfo(cast<DefInit>(SubOps->getArg(0))->getDef());
-
- // If we have multiple sub-ops, there'd better have a custom
- // decoder. (Otherwise we don't know how to populate them properly...)
- if (SubOps->getNumArgs() > 1) {
- PrintError(EncodingDef,
- "DecoderEmitter: operand \"" + OpName +
- "\" uses MIOperandInfo with multiple ops, but doesn't "
- "have a custom decoder!");
- debugDumpRecord(*EncodingDef);
- continue;
- }
- }
+ // Decode each of the sub-ops separately.
+ assert(SubOps && SubArgDag->getNumArgs() == SubOps->getNumArgs());
+ for (const auto &[I, Arg] : enumerate(SubOps->getArgs())) {
+ StringRef SubOpName = SubArgDag->getArgNameStr(I);
+ OperandInfo SubOpInfo = getOpInfo(cast<DefInit>(Arg)->getDef());
- addOneOperandFields(EncodingDef, Bits, TiedNames, OpName, OpInfo);
- // FIXME: it should be an error not to find a definition for a given
- // operand, rather than just failing to add it to the resulting
- // instruction! (This is a longstanding bug, which will be addressed in an
- // upcoming change.)
- if (OpInfo.numFields() > 0)
- Operands.push_back(std::move(OpInfo));
+ addOneOperandFields(EncodingDef, Bits, TiedNames, SubOpName, SubOpInfo);
+ Operands.push_back(std::move(SubOpInfo));
+ }
+ continue;
}
- }
-
-#if 0
- LLVM_DEBUG({
- // Dumps the instruction encoding bits.
- dumpBits(errs(), Bits);
- errs() << '\n';
-
- // Dumps the list of operand info.
- for (unsigned i = 0, e = Inst->Operands.size(); i != e; ++i) {
- const CGIOperandList::OperandInfo &Info = Inst->Operands[i];
- const std::string &OperandName = Info.Name;
- const Record &OperandDef = *Info.Rec;
-
- errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n";
+ // Otherwise, if we have an operand with sub-operands, but they aren't
+ // named...
+ if (SubOps && OpInfo.Decoder.empty()) {
+ // If it's a single sub-operand, and no custom decoder, use the decoder
+ // from the one sub-operand.
+ if (SubOps->getNumArgs() == 1)
+ OpInfo = getOpInfo(cast<DefInit>(SubOps->getArg(0))->getDef());
+
+ // If we have multiple sub-ops, there'd better have a custom
+ // decoder. (Otherwise we don't know how to populate them properly...)
+ if (SubOps->getNumArgs() > 1) {
+ PrintError(EncodingDef,
+ "DecoderEmitter: operand \"" + OpName +
+ "\" uses MIOperandInfo with multiple ops, but doesn't "
+ "have a custom decoder!");
+ debugDumpRecord(*EncodingDef);
+ continue;
}
- });
-#endif
+ }
+
+ addOneOperandFields(EncodingDef, Bits, TiedNames, OpName, OpInfo);
+ // FIXME: it should be an error not to find a definition for a given
+ // operand, rather than just failing to add it to the resulting
+ // instruction! (This is a longstanding bug, which will be addressed in an
+ // upcoming change.)
+ if (OpInfo.numFields() > 0)
+ Operands.push_back(std::move(OpInfo));
+ }
+}
- return Bits.getNumBits();
+void InstructionEncoding::populateEncoding() {
+ const RecordVal *InstField = EncodingDef->getValue("Inst");
+ if (const auto *DI = dyn_cast<DagInit>(InstField->getValue())) {
+ VarLenInst VLI(DI, InstField);
+ BitWidth = VLI.size();
+ // If the encoding has a custom decoder, don't bother parsing the operands.
+ if (Operands.empty())
+ populateVarLenEncoding(VLI);
+ } else {
+ const auto *BI = cast<BitsInit>(InstField->getValue());
+ BitWidth = BI->getNumBits();
+ // If the encoding has a custom decoder, don't bother parsing the operands.
+ if (Operands.empty())
+ populateFixedLenEncoding(*BI);
+ }
}
// emitFieldFromInstruction - Emit the templated helper function