diff options
| author | Craig Topper <craig.topper@sifive.com> | 2026-02-03 13:13:13 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-03 13:13:13 -0800 |
| commit | caab98284166784459a2fb76df7bca3f1d35e41e (patch) | |
| tree | edc40217bdc8affd6e1830104461184e31645e62 /llvm/lib/CodeGen/SelectionDAG | |
| parent | 22c8344d986df3d91121b3c27d20eb820d828386 (diff) | |
| download | llvm-caab98284166784459a2fb76df7bca3f1d35e41e.tar.gz llvm-caab98284166784459a2fb76df7bca3f1d35e41e.tar.bz2 llvm-caab98284166784459a2fb76df7bca3f1d35e41e.zip | |
[SelectionDAGISel] Separate the operand numbers in OPC_EmitNode/MorphNodeTo into their own table. (#178722)
The operand lists for these opcode require 1 byte per operand and are
usually small values that fit in 3-4 bits. This makes their storage
inefficient. In addition, many EmitNode/MorphNodeTo in the isel table
will use the same list of operand numbers.
This patch proposes to separate the operand lists into their own table
where they can be de-duplicated. The OPC_EmitNode/MorphNodeTo in the
main table will only store an index into this smaller table.
This is a reduced version of a suggestion from this very old FIXME.
https://github.com/llvm/llvm-project/blob/d8d4096c0be0a6a3248c8deae96608913a85debf/llvm/utils/TableGen/DAGISelMatcherGen.cpp#L1070
For RISC-V this reduces the main table from 1437353 bytes to 1276015
bytes plus a 929 byte operand list table. A savings of about 11%.
For X86 this reduces the main table from 719237 bytes to 623612 bytes
plus a 1042 byte operand list table. A savings of about 11%.
I expect further savings could be had by moving more bytes over.
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index e7cb0a3574b4..7419aac6ba3d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -3350,7 +3350,8 @@ public: void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, const uint8_t *MatcherTable, - unsigned TableSize) { + unsigned TableSize, + const uint8_t *OperandLists) { // FIXME: Should these even be selected? Handle these cases in the caller? switch (NodeToMatch->getOpcode()) { default: @@ -4307,14 +4308,22 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, // Get the operand list. unsigned NumOps = MatcherTable[MatcherIndex++]; - SmallVector<SDValue, 8> Ops; - for (unsigned i = 0; i != NumOps; ++i) { - unsigned RecNo = MatcherTable[MatcherIndex++]; - if (RecNo & 128) - RecNo = GetVBR(RecNo, MatcherTable, MatcherIndex); - assert(RecNo < RecordedNodes.size() && "Invalid EmitNode"); - Ops.push_back(RecordedNodes[RecNo].first); + SmallVector<SDValue, 8> Ops; + if (NumOps != 0) { + // Get the index into the OperandLists. + uint64_t OperandIndex = MatcherTable[MatcherIndex++]; + if (OperandIndex & 128) + OperandIndex = GetVBR(OperandIndex, MatcherTable, MatcherIndex); + + for (unsigned i = 0; i != NumOps; ++i) { + unsigned RecNo = OperandLists[OperandIndex++]; + if (RecNo & 128) + RecNo = GetVBR(RecNo, OperandLists, OperandIndex); + + assert(RecNo < RecordedNodes.size() && "Invalid EmitNode"); + Ops.push_back(RecordedNodes[RecNo].first); + } } // If there are variadic operands to add, handle them now. |
