Use std::lower_bound for opcode lookup

Use std::lower_bound for opcode-to-string

Stable sort the generated instruction table.
This commit is contained in:
Jesus Carabano 2017-10-27 15:28:50 +03:00 committed by David Neto
parent 1040a95b3f
commit f063f91d24
2 changed files with 30 additions and 14 deletions

View File

@ -140,13 +140,16 @@ spv_result_t spvOpcodeTableValueLookup(const spv_opcode_table table,
if (!table) return SPV_ERROR_INVALID_TABLE;
if (!pEntry) return SPV_ERROR_INVALID_POINTER;
// TODO: As above this lookup is not optimal.
for (uint64_t opcodeIndex = 0; opcodeIndex < table->count; ++opcodeIndex) {
if (opcode == table->entries[opcodeIndex].opcode) {
// NOTE: Found the Opcode!
*pEntry = &table->entries[opcodeIndex];
return SPV_SUCCESS;
}
const auto beg = table->entries;
const auto end = table->entries + table->count;
spv_opcode_desc_t value{"", opcode, 0, nullptr, 0, {}, 0, 0};
auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) {
return lhs.opcode < rhs.opcode;
};
auto it = std::lower_bound(beg, end, value, comp);
if (it!=end && it->opcode == opcode) {
*pEntry = it;
return SPV_SUCCESS;
}
return SPV_ERROR_INVALID_LOOKUP;
@ -172,9 +175,16 @@ void spvInstructionCopy(const uint32_t* words, const SpvOp opcode,
const char* spvOpcodeString(const SpvOp opcode) {
// Use the latest SPIR-V version, which should be backward-compatible with all
// previous ones.
for (uint32_t i = 0; i < ARRAY_SIZE(kOpcodeTableEntries_1_2); ++i) {
if (kOpcodeTableEntries_1_2[i].opcode == opcode)
return kOpcodeTableEntries_1_2[i].name;
const auto beg = kOpcodeTableEntries_1_2;
const auto end = kOpcodeTableEntries_1_2 + ARRAY_SIZE(kOpcodeTableEntries_1_2);
spv_opcode_desc_t value{"", opcode, 0, nullptr, 0, {}, 0, 0};
auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) {
return lhs.opcode < rhs.opcode;
};
auto it = std::lower_bound(beg, end, value, comp);
if (it!=end && it->opcode == opcode) {
return it->name;
}
assert(0 && "Unreachable!");

View File

@ -327,12 +327,17 @@ def generate_instruction(inst, version, is_ext_inst):
def generate_instruction_table(inst_table, version):
"""Returns the info table containing all SPIR-V instructions,
prefixed by capability arrays.
sorted by opcode, and prefixed by capability arrays.
Note:
- the built-in sorted() function is guaranteed to be stable.
https://docs.python.org/3/library/functions.html#sorted
Arguments:
- inst_table: a dict containing all SPIR-V instructions.
- inst_table: a list containing all SPIR-V instructions.
- vesion: SPIR-V version.
"""
inst_table = sorted(inst_table, key=lambda k: k['opcode'])
caps_arrays = generate_capability_arrays(
[inst.get('capabilities', []) for inst in inst_table], version)
insts = [generate_instruction(inst, version, False) for inst in inst_table]
@ -344,12 +349,13 @@ def generate_instruction_table(inst_table, version):
def generate_extended_instruction_table(inst_table, set_name, version):
"""Returns the info table containing all SPIR-V extended instructions,
prefixed by capability arrays.
sorted by opcode, and prefixed by capability arrays.
Arguments:
- inst_table: a dict containing all SPIR-V instructions.
- inst_table: a list containing all SPIR-V instructions.
- set_name: the name of the extended instruction set.
"""
inst_table = sorted(inst_table, key=lambda k: k['opcode'])
caps = [inst.get('capabilities', []) for inst in inst_table]
caps_arrays = generate_capability_arrays(caps, version)
insts = [generate_instruction(inst, version, True) for inst in inst_table]