[PATCH] D120958: [TableGen] Add support for variable length instruction in decoder generator
Min-Yih Hsu via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 14 11:20:07 PDT 2022
myhsu added a comment.
Thank you for the patch.
A high level question: It seems like generating a decoder requires two phases -- First, generates a list of `OperandInfo`, which is currently done by `populateInstruction`, then emit the real (C++) code according to these `OperandInfo` instances. My question is, can we use our own way -- possibly putting in a separate file -- to generate these `OperandInfo` before supplying them to the second phase, instead of trying to piggyback everything into the existing FixedLenDecoder framework?
Because, to be honest, I'm not a big fan of overloading the `BitsInit` (to carry operand info). Using a `BitsInit` might fit well for fixed-length instructions but I feel like there are more elegant ways to handle var-length instructions. For instance, using `CGIOperandList::OperandInfo::ParseOperandName` to parse suboperands rather than traversing every single in/out operands in the original instruction definition.
Also, please double check all your modifications and make sure to follow the LLVM coding style, especially the naming convention of local variables.
================
Comment at: llvm/utils/TableGen/FixedLenDecoderEmitter.cpp:228
+ // variable length instruction
+ DagInit *dag = cast<DagInit>(RV->getValue());
+ VarLenInst VLI = VarLenInst(dag, RV);
----------------
https://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly
================
Comment at: llvm/utils/TableGen/FixedLenDecoderEmitter.cpp:265
+ } else {
+ llvm_unreachable("What kind of init it is ?");
+ }
----------------
"unknown Init kind" would probably be better.
================
Comment at: llvm/utils/TableGen/FixedLenDecoderEmitter.cpp:498
+ AllInstructions[Opcode].EncodingDef->getValue("SoftFail");
+ const BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
+ for (unsigned i = 0; i < Bits.getNumBits(); ++i) {
----------------
why do you want to change these three lines? I don't think `RV` is used anywhere else.
================
Comment at: llvm/utils/TableGen/FixedLenDecoderEmitter.cpp:1388
+ const RecordVal *RV = AllInstructions[Opc].EncodingDef->getValue("SoftFail");
+ BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
+
----------------
ditto
================
Comment at: llvm/utils/TableGen/FixedLenDecoderEmitter.cpp:2149
- unsigned Base = ~0U;
- unsigned Width = 0;
- unsigned Offset = 0;
+ auto getOpInfo = [&](OperandInfo OI, StringRef SubOpName) {
+ unsigned Base = ~0U;
----------------
The `OI` argument can be `OperandInfo &` to avoid copy.
================
Comment at: llvm/utils/TableGen/FixedLenDecoderEmitter.cpp:2300
+ << " unsigned numBits,\n"
+ << " std::function<void(InsnType &, uint64_t)> "
+ "makeUp\n"
----------------
please use `llvm::function_ref` here
================
Comment at: llvm/utils/TableGen/FixedLenDecoderEmitter.cpp:2303
+ << " = [](InsnType &insn, uint64_t){}) {\n"
+ << " makeUp(insn, startBit + numBits);\n"
<< " return insn.extractBitsAsZExtValue(numBits, startBit);\n"
----------------
why do we want to enlarge `insn` (on-demand) upon every field extractions? Can we resize `insn` ahead of time and do it only once?
================
Comment at: llvm/utils/TableGen/FixedLenDecoderEmitter.cpp:2342
+ OS << ",\n"
+ << " std::function<void(APInt &,"
+ << " uint64_t)> makeUp";
----------------
ditto
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D120958/new/
https://reviews.llvm.org/D120958
More information about the llvm-commits
mailing list