Skip to content

Commit 9ae0bd2

Browse files
authored
[TableGen][DecoderEmitter] Move Operands to InstructionEncoding (NFCI) (#154456)
This is where they belong, no need to maintain a separate map keyed by encoding ID. `populateInstruction()` has been made a member of `InstructionEncoding` and is now called from the constructor.
1 parent d145dc1 commit 9ae0bd2

File tree

1 file changed

+42
-47
lines changed

1 file changed

+42
-47
lines changed

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 42 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ class InstructionEncoding {
140140
/// The name of this encoding (for debugging purposes).
141141
std::string Name;
142142

143+
/// The size of this encoding, in bits.
144+
unsigned BitWidth;
145+
146+
/// Information about the operands' contribution to this encoding.
147+
SmallVector<OperandInfo, 16> Operands;
148+
143149
public:
144150
InstructionEncoding(const Record *EncodingDef, const CodeGenInstruction *Inst)
145151
: EncodingDef(EncodingDef), Inst(Inst) {
@@ -149,6 +155,8 @@ class InstructionEncoding {
149155
if (EncodingDef != InstDef)
150156
Name = (EncodingDef->getName() + Twine(':')).str();
151157
Name.append(InstDef->getName());
158+
159+
BitWidth = populateEncoding();
152160
}
153161

154162
/// Returns the Record this encoding originates from.
@@ -159,6 +167,17 @@ class InstructionEncoding {
159167

160168
/// Returns the name of this encoding, for debugging purposes.
161169
StringRef getName() const { return Name; }
170+
171+
/// Returns the size of this encoding, in bits.
172+
unsigned getBitWidth() const { return BitWidth; }
173+
174+
/// Returns information about the operands' contribution to this encoding.
175+
ArrayRef<OperandInfo> getOperands() const { return Operands; }
176+
177+
private:
178+
void populateVarLenEncoding();
179+
180+
unsigned populateEncoding();
162181
};
163182

164183
typedef std::vector<uint32_t> FixupList;
@@ -522,9 +541,6 @@ class FilterChooser {
522541
// Vector of encoding IDs for this filter chooser to work on.
523542
ArrayRef<unsigned> EncodingIDs;
524543

525-
// Lookup table for the operand decoding of instructions.
526-
const std::map<unsigned, std::vector<OperandInfo>> &Operands;
527-
528544
// The selected filter, if any.
529545
std::unique_ptr<Filter> BestFilter;
530546

@@ -549,21 +565,19 @@ class FilterChooser {
549565

550566
public:
551567
FilterChooser(ArrayRef<InstructionEncoding> Encodings,
552-
ArrayRef<unsigned> EncodingIDs,
553-
const std::map<unsigned, std::vector<OperandInfo>> &Ops,
554-
unsigned BW, const DecoderEmitter *E)
555-
: Encodings(Encodings), EncodingIDs(EncodingIDs), Operands(Ops),
568+
ArrayRef<unsigned> EncodingIDs, unsigned BW,
569+
const DecoderEmitter *E)
570+
: Encodings(Encodings), EncodingIDs(EncodingIDs),
556571
FilterBitValues(BW, BitValue::BIT_UNFILTERED), Parent(nullptr),
557572
BitWidth(BW), Emitter(E) {
558573
doFilter();
559574
}
560575

561576
FilterChooser(ArrayRef<InstructionEncoding> Encodings,
562577
ArrayRef<unsigned> EncodingIDs,
563-
const std::map<unsigned, std::vector<OperandInfo>> &Ops,
564578
const std::vector<BitValue> &ParentFilterBitValues,
565579
const FilterChooser &parent)
566-
: Encodings(Encodings), EncodingIDs(EncodingIDs), Operands(Ops),
580+
: Encodings(Encodings), EncodingIDs(EncodingIDs),
567581
FilterBitValues(ParentFilterBitValues), Parent(&parent),
568582
BitWidth(parent.BitWidth), Emitter(parent.Emitter) {
569583
doFilter();
@@ -728,8 +742,8 @@ void Filter::recurse() {
728742

729743
// Delegates to an inferior filter chooser for further processing on this
730744
// group of instructions whose segment values are variable.
731-
VariableFC = std::make_unique<FilterChooser>(
732-
Owner.Encodings, VariableIDs, Owner.Operands, BitValueArray, Owner);
745+
VariableFC = std::make_unique<FilterChooser>(Owner.Encodings, VariableIDs,
746+
BitValueArray, Owner);
733747
}
734748

735749
// No need to recurse for a singleton filtered instruction.
@@ -750,9 +764,8 @@ void Filter::recurse() {
750764
// Delegates to an inferior filter chooser for further processing on this
751765
// category of instructions.
752766
FilterChooserMap.try_emplace(
753-
FilterVal,
754-
std::make_unique<FilterChooser>(Owner.Encodings, EncodingIDs,
755-
Owner.Operands, BitValueArray, Owner));
767+
FilterVal, std::make_unique<FilterChooser>(Owner.Encodings, EncodingIDs,
768+
BitValueArray, Owner));
756769
}
757770
}
758771

@@ -1235,7 +1248,7 @@ bool FilterChooser::emitDecoder(raw_ostream &OS, indent Indent,
12351248
unsigned EncodingID) const {
12361249
bool HasCompleteDecoder = true;
12371250

1238-
for (const OperandInfo &Op : Operands.find(EncodingID)->second) {
1251+
for (const OperandInfo &Op : Encodings[EncodingID].getOperands()) {
12391252
// If a custom instruction decoder was specified, use that.
12401253
if (Op.numFields() == 0 && !Op.Decoder.empty()) {
12411254
HasCompleteDecoder = Op.HasCompleteDecoder;
@@ -1849,9 +1862,7 @@ OperandInfo getOpInfo(const Record *TypeRecord) {
18491862
return OperandInfo(findOperandDecoderMethod(TypeRecord), HasCompleteDecoder);
18501863
}
18511864

1852-
static void parseVarLenInstOperand(const Record *EncodingDef,
1853-
std::vector<OperandInfo> &Operands,
1854-
const CodeGenInstruction *Inst) {
1865+
void InstructionEncoding::populateVarLenEncoding() {
18551866
const RecordVal *RV = EncodingDef->getValue("Inst");
18561867
VarLenInst VLI(cast<DagInit>(RV->getValue()), RV);
18571868
SmallVector<int> TiedTo;
@@ -1950,21 +1961,13 @@ static void addOneOperandFields(const Record *EncodingDef, const BitsInit &Bits,
19501961
}
19511962
}
19521963

1953-
static unsigned populateInstruction(
1954-
const CodeGenTarget &Target, const Record *EncodingDef,
1955-
const CodeGenInstruction *Inst, unsigned EncodingID,
1956-
std::map<unsigned, std::vector<OperandInfo>> &EncodingOperands,
1957-
bool IsVarLenInst) {
1964+
unsigned InstructionEncoding::populateEncoding() {
1965+
bool IsVarLenInst = isa<DagInit>(EncodingDef->getValueInit("Inst"));
19581966
const Record &Def = *Inst->TheDef;
1959-
// If all the bit positions are not specified; do not decode this instruction.
1960-
// We are bound to fail! For proper disassembly, the well-known encoding bits
1961-
// of the instruction must be fully specified.
19621967

19631968
const BitsInit &Bits = getBitsField(*EncodingDef, "Inst");
1964-
if (Bits.allInComplete())
1965-
return 0;
1966-
1967-
std::vector<OperandInfo> Operands;
1969+
assert(!Bits.allInComplete() &&
1970+
"Invalid encodings should have been filtered out");
19681971

19691972
// If the instruction has specified a custom decoding hook, use that instead
19701973
// of trying to auto-generate the decoder.
@@ -1973,7 +1976,6 @@ static unsigned populateInstruction(
19731976
bool HasCompleteInstDecoder =
19741977
EncodingDef->getValueAsBit("hasCompleteDecoder");
19751978
Operands.push_back(OperandInfo(InstDecoder.str(), HasCompleteInstDecoder));
1976-
EncodingOperands[EncodingID] = std::move(Operands);
19771979
return Bits.getNumBits();
19781980
}
19791981

@@ -2014,7 +2016,7 @@ static unsigned populateInstruction(
20142016
}
20152017

20162018
if (IsVarLenInst) {
2017-
parseVarLenInstOperand(EncodingDef, Operands, Inst);
2019+
populateVarLenEncoding();
20182020
} else {
20192021
// For each operand, see if we can figure out where it is encoded.
20202022
for (const auto &Op : InOutOperands) {
@@ -2095,7 +2097,6 @@ static unsigned populateInstruction(
20952097
Operands.push_back(std::move(OpInfo));
20962098
}
20972099
}
2098-
EncodingOperands[EncodingID] = std::move(Operands);
20992100

21002101
#if 0
21012102
LLVM_DEBUG({
@@ -2606,22 +2607,16 @@ namespace {
26062607
emitInsertBits(OS);
26072608
emitCheck(OS);
26082609

2609-
std::map<unsigned, std::vector<OperandInfo>> Operands;
2610+
// Do extra bookkeeping for variable-length encodings.
26102611
std::vector<unsigned> InstrLen;
26112612
bool IsVarLenInst = Target.hasVariableLengthEncodings();
2612-
if (IsVarLenInst)
2613-
InstrLen.resize(Target.getInstructions().size(), 0);
26142613
unsigned MaxInstLen = 0;
2615-
2616-
for (auto [EncodingID, Encoding] : enumerate(Encodings)) {
2617-
const Record *EncodingDef = Encoding.getRecord();
2618-
const CodeGenInstruction *Inst = Encoding.getInstruction();
2619-
unsigned BitWidth = populateInstruction(Target, EncodingDef, Inst,
2620-
EncodingID, Operands, IsVarLenInst);
2621-
assert(BitWidth && "Invalid encodings should have been filtered out");
2622-
if (IsVarLenInst) {
2623-
MaxInstLen = std::max(MaxInstLen, BitWidth);
2624-
InstrLen[Target.getInstrIntValue(Inst->TheDef)] = BitWidth;
2614+
if (IsVarLenInst) {
2615+
InstrLen.resize(Target.getInstructions().size(), 0);
2616+
for (const InstructionEncoding &Encoding : Encodings) {
2617+
MaxInstLen = std::max(MaxInstLen, Encoding.getBitWidth());
2618+
InstrLen[Target.getInstrIntValue(Encoding.getInstruction()->TheDef)] =
2619+
Encoding.getBitWidth();
26252620
}
26262621
}
26272622

@@ -2645,7 +2640,7 @@ namespace {
26452640
auto [DecoderNamespace, HwModeID, Size] = Key;
26462641
const unsigned BitWidth = IsVarLenInst ? MaxInstLen : 8 * Size;
26472642
// Emit the decoder for this (namespace, hwmode, width) combination.
2648-
FilterChooser FC(Encodings, EncodingIDs, Operands, BitWidth, this);
2643+
FilterChooser FC(Encodings, EncodingIDs, BitWidth, this);
26492644

26502645
// The decode table is cleared for each top level decoder function. The
26512646
// predicates and decoders themselves, however, are shared across all

0 commit comments

Comments
 (0)