Skip to content

Commit 19ac1ff

Browse files
authored
[TableGen][DecoderEmitter] Factor populateFixedLenEncoding (NFC) (#154511)
Also drop the debug code under `#if 0` and a seemingly outdated comment.
1 parent b01f059 commit 19ac1ff

File tree

1 file changed

+99
-121
lines changed

1 file changed

+99
-121
lines changed

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 99 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,14 @@ class InstructionEncoding {
156156
Name = (EncodingDef->getName() + Twine(':')).str();
157157
Name.append(InstDef->getName());
158158

159-
BitWidth = populateEncoding();
159+
StringRef DecoderMethod = EncodingDef->getValueAsString("DecoderMethod");
160+
if (!DecoderMethod.empty()) {
161+
bool HasCompleteDecoder =
162+
EncodingDef->getValueAsBit("hasCompleteDecoder");
163+
Operands.push_back(OperandInfo(DecoderMethod.str(), HasCompleteDecoder));
164+
}
165+
166+
populateEncoding();
160167
}
161168

162169
/// Returns the Record this encoding originates from.
@@ -175,9 +182,9 @@ class InstructionEncoding {
175182
ArrayRef<OperandInfo> getOperands() const { return Operands; }
176183

177184
private:
178-
void populateVarLenEncoding();
179-
180-
unsigned populateEncoding();
185+
void populateVarLenEncoding(const VarLenInst &VLI);
186+
void populateFixedLenEncoding(const BitsInit &Bits);
187+
void populateEncoding();
181188
};
182189

183190
typedef std::vector<uint32_t> FixupList;
@@ -1862,9 +1869,7 @@ OperandInfo getOpInfo(const Record *TypeRecord) {
18621869
return OperandInfo(findOperandDecoderMethod(TypeRecord), HasCompleteDecoder);
18631870
}
18641871

1865-
void InstructionEncoding::populateVarLenEncoding() {
1866-
const RecordVal *RV = EncodingDef->getValue("Inst");
1867-
VarLenInst VLI(cast<DagInit>(RV->getValue()), RV);
1872+
void InstructionEncoding::populateVarLenEncoding(const VarLenInst &VLI) {
18681873
SmallVector<int> TiedTo;
18691874

18701875
for (const auto &[Idx, Op] : enumerate(Inst->Operands)) {
@@ -1961,28 +1966,9 @@ static void addOneOperandFields(const Record *EncodingDef, const BitsInit &Bits,
19611966
}
19621967
}
19631968

1964-
unsigned InstructionEncoding::populateEncoding() {
1965-
bool IsVarLenInst = isa<DagInit>(EncodingDef->getValueInit("Inst"));
1969+
void InstructionEncoding::populateFixedLenEncoding(const BitsInit &Bits) {
19661970
const Record &Def = *Inst->TheDef;
19671971

1968-
const BitsInit &Bits = getBitsField(*EncodingDef, "Inst");
1969-
assert(!Bits.allInComplete() &&
1970-
"Invalid encodings should have been filtered out");
1971-
1972-
// If the instruction has specified a custom decoding hook, use that instead
1973-
// of trying to auto-generate the decoder.
1974-
StringRef InstDecoder = EncodingDef->getValueAsString("DecoderMethod");
1975-
if (!InstDecoder.empty()) {
1976-
bool HasCompleteInstDecoder =
1977-
EncodingDef->getValueAsBit("hasCompleteDecoder");
1978-
Operands.push_back(OperandInfo(InstDecoder.str(), HasCompleteInstDecoder));
1979-
return Bits.getNumBits();
1980-
}
1981-
1982-
// Generate a description of the operand of the instruction that we know
1983-
// how to decode automatically.
1984-
// FIXME: We'll need to have a way to manually override this as needed.
1985-
19861972
// Gather the outputs/inputs of the instruction, so we can find their
19871973
// positions in the encoding. This assumes for now that they appear in the
19881974
// MCInst in the order that they're listed.
@@ -2015,108 +2001,100 @@ unsigned InstructionEncoding::populateEncoding() {
20152001
}
20162002
}
20172003

2018-
if (IsVarLenInst) {
2019-
populateVarLenEncoding();
2020-
} else {
2021-
// For each operand, see if we can figure out where it is encoded.
2022-
for (const auto &Op : InOutOperands) {
2023-
const Init *OpInit = Op.first;
2024-
StringRef OpName = Op.second;
2025-
2026-
// We're ready to find the instruction encoding locations for this
2027-
// operand.
2028-
2029-
// First, find the operand type ("OpInit"), and sub-op names
2030-
// ("SubArgDag") if present.
2031-
const DagInit *SubArgDag = dyn_cast<DagInit>(OpInit);
2032-
if (SubArgDag)
2033-
OpInit = SubArgDag->getOperator();
2034-
const Record *OpTypeRec = cast<DefInit>(OpInit)->getDef();
2035-
// Lookup the sub-operands from the operand type record (note that only
2036-
// Operand subclasses have MIOperandInfo, see CodeGenInstruction.cpp).
2037-
const DagInit *SubOps = OpTypeRec->isSubClassOf("Operand")
2038-
? OpTypeRec->getValueAsDag("MIOperandInfo")
2039-
: nullptr;
2040-
2041-
// Lookup the decoder method and construct a new OperandInfo to hold our
2042-
// result.
2043-
OperandInfo OpInfo = getOpInfo(OpTypeRec);
2044-
2045-
// If we have named sub-operands...
2046-
if (SubArgDag) {
2047-
// Then there should not be a custom decoder specified on the top-level
2048-
// type.
2049-
if (!OpInfo.Decoder.empty()) {
2050-
PrintError(EncodingDef,
2051-
"DecoderEmitter: operand \"" + OpName + "\" has type \"" +
2052-
OpInit->getAsString() +
2053-
"\" with a custom DecoderMethod, but also named "
2054-
"sub-operands.");
2055-
continue;
2056-
}
2057-
2058-
// Decode each of the sub-ops separately.
2059-
assert(SubOps && SubArgDag->getNumArgs() == SubOps->getNumArgs());
2060-
for (const auto &[I, Arg] : enumerate(SubOps->getArgs())) {
2061-
StringRef SubOpName = SubArgDag->getArgNameStr(I);
2062-
OperandInfo SubOpInfo = getOpInfo(cast<DefInit>(Arg)->getDef());
2063-
2064-
addOneOperandFields(EncodingDef, Bits, TiedNames, SubOpName,
2065-
SubOpInfo);
2066-
Operands.push_back(std::move(SubOpInfo));
2067-
}
2004+
// For each operand, see if we can figure out where it is encoded.
2005+
for (const auto &Op : InOutOperands) {
2006+
const Init *OpInit = Op.first;
2007+
StringRef OpName = Op.second;
2008+
2009+
// We're ready to find the instruction encoding locations for this
2010+
// operand.
2011+
2012+
// First, find the operand type ("OpInit"), and sub-op names
2013+
// ("SubArgDag") if present.
2014+
const DagInit *SubArgDag = dyn_cast<DagInit>(OpInit);
2015+
if (SubArgDag)
2016+
OpInit = SubArgDag->getOperator();
2017+
const Record *OpTypeRec = cast<DefInit>(OpInit)->getDef();
2018+
// Lookup the sub-operands from the operand type record (note that only
2019+
// Operand subclasses have MIOperandInfo, see CodeGenInstruction.cpp).
2020+
const DagInit *SubOps = OpTypeRec->isSubClassOf("Operand")
2021+
? OpTypeRec->getValueAsDag("MIOperandInfo")
2022+
: nullptr;
2023+
2024+
// Lookup the decoder method and construct a new OperandInfo to hold our
2025+
// result.
2026+
OperandInfo OpInfo = getOpInfo(OpTypeRec);
2027+
2028+
// If we have named sub-operands...
2029+
if (SubArgDag) {
2030+
// Then there should not be a custom decoder specified on the top-level
2031+
// type.
2032+
if (!OpInfo.Decoder.empty()) {
2033+
PrintError(EncodingDef,
2034+
"DecoderEmitter: operand \"" + OpName + "\" has type \"" +
2035+
OpInit->getAsString() +
2036+
"\" with a custom DecoderMethod, but also named "
2037+
"sub-operands.");
20682038
continue;
20692039
}
20702040

2071-
// Otherwise, if we have an operand with sub-operands, but they aren't
2072-
// named...
2073-
if (SubOps && OpInfo.Decoder.empty()) {
2074-
// If it's a single sub-operand, and no custom decoder, use the decoder
2075-
// from the one sub-operand.
2076-
if (SubOps->getNumArgs() == 1)
2077-
OpInfo = getOpInfo(cast<DefInit>(SubOps->getArg(0))->getDef());
2078-
2079-
// If we have multiple sub-ops, there'd better have a custom
2080-
// decoder. (Otherwise we don't know how to populate them properly...)
2081-
if (SubOps->getNumArgs() > 1) {
2082-
PrintError(EncodingDef,
2083-
"DecoderEmitter: operand \"" + OpName +
2084-
"\" uses MIOperandInfo with multiple ops, but doesn't "
2085-
"have a custom decoder!");
2086-
debugDumpRecord(*EncodingDef);
2087-
continue;
2088-
}
2089-
}
2041+
// Decode each of the sub-ops separately.
2042+
assert(SubOps && SubArgDag->getNumArgs() == SubOps->getNumArgs());
2043+
for (const auto &[I, Arg] : enumerate(SubOps->getArgs())) {
2044+
StringRef SubOpName = SubArgDag->getArgNameStr(I);
2045+
OperandInfo SubOpInfo = getOpInfo(cast<DefInit>(Arg)->getDef());
20902046

2091-
addOneOperandFields(EncodingDef, Bits, TiedNames, OpName, OpInfo);
2092-
// FIXME: it should be an error not to find a definition for a given
2093-
// operand, rather than just failing to add it to the resulting
2094-
// instruction! (This is a longstanding bug, which will be addressed in an
2095-
// upcoming change.)
2096-
if (OpInfo.numFields() > 0)
2097-
Operands.push_back(std::move(OpInfo));
2047+
addOneOperandFields(EncodingDef, Bits, TiedNames, SubOpName, SubOpInfo);
2048+
Operands.push_back(std::move(SubOpInfo));
2049+
}
2050+
continue;
20982051
}
2099-
}
2100-
2101-
#if 0
2102-
LLVM_DEBUG({
2103-
// Dumps the instruction encoding bits.
2104-
dumpBits(errs(), Bits);
21052052

2106-
errs() << '\n';
2107-
2108-
// Dumps the list of operand info.
2109-
for (unsigned i = 0, e = Inst->Operands.size(); i != e; ++i) {
2110-
const CGIOperandList::OperandInfo &Info = Inst->Operands[i];
2111-
const std::string &OperandName = Info.Name;
2112-
const Record &OperandDef = *Info.Rec;
2113-
2114-
errs() << "\t" << OperandName << " (" << OperandDef.getName() << ")\n";
2053+
// Otherwise, if we have an operand with sub-operands, but they aren't
2054+
// named...
2055+
if (SubOps && OpInfo.Decoder.empty()) {
2056+
// If it's a single sub-operand, and no custom decoder, use the decoder
2057+
// from the one sub-operand.
2058+
if (SubOps->getNumArgs() == 1)
2059+
OpInfo = getOpInfo(cast<DefInit>(SubOps->getArg(0))->getDef());
2060+
2061+
// If we have multiple sub-ops, there'd better have a custom
2062+
// decoder. (Otherwise we don't know how to populate them properly...)
2063+
if (SubOps->getNumArgs() > 1) {
2064+
PrintError(EncodingDef,
2065+
"DecoderEmitter: operand \"" + OpName +
2066+
"\" uses MIOperandInfo with multiple ops, but doesn't "
2067+
"have a custom decoder!");
2068+
debugDumpRecord(*EncodingDef);
2069+
continue;
21152070
}
2116-
});
2117-
#endif
2071+
}
2072+
2073+
addOneOperandFields(EncodingDef, Bits, TiedNames, OpName, OpInfo);
2074+
// FIXME: it should be an error not to find a definition for a given
2075+
// operand, rather than just failing to add it to the resulting
2076+
// instruction! (This is a longstanding bug, which will be addressed in an
2077+
// upcoming change.)
2078+
if (OpInfo.numFields() > 0)
2079+
Operands.push_back(std::move(OpInfo));
2080+
}
2081+
}
21182082

2119-
return Bits.getNumBits();
2083+
void InstructionEncoding::populateEncoding() {
2084+
const RecordVal *InstField = EncodingDef->getValue("Inst");
2085+
if (const auto *DI = dyn_cast<DagInit>(InstField->getValue())) {
2086+
VarLenInst VLI(DI, InstField);
2087+
BitWidth = VLI.size();
2088+
// If the encoding has a custom decoder, don't bother parsing the operands.
2089+
if (Operands.empty())
2090+
populateVarLenEncoding(VLI);
2091+
} else {
2092+
const auto *BI = cast<BitsInit>(InstField->getValue());
2093+
BitWidth = BI->getNumBits();
2094+
// If the encoding has a custom decoder, don't bother parsing the operands.
2095+
if (Operands.empty())
2096+
populateFixedLenEncoding(*BI);
2097+
}
21202098
}
21212099

21222100
// emitFieldFromInstruction - Emit the templated helper function

0 commit comments

Comments
 (0)