Move some temp vectors into parser state

We don't need to churn the allocations for these every instruction.
This commit is contained in:
Chris Forbes 2017-06-27 11:00:06 -07:00 committed by David Neto
parent ad1d0351a0
commit fcd991f081

View File

@ -198,6 +198,10 @@ class Parser {
// Maps an ExtInstImport id to the extended instruction type. // Maps an ExtInstImport id to the extended instruction type.
std::unordered_map<uint32_t, spv_ext_inst_type_t> std::unordered_map<uint32_t, spv_ext_inst_type_t>
import_id_to_ext_inst_type; import_id_to_ext_inst_type;
// Used by parseOperand
std::vector<spv_parsed_operand_t> operands;
std::vector<uint32_t> endian_converted_words;
} _; } _;
}; };
@ -269,17 +273,18 @@ spv_result_t Parser::parseInstruction() {
// If the module's endianness is different from the host native endianness, // If the module's endianness is different from the host native endianness,
// then converted_words contains the the endian-translated words in the // then converted_words contains the the endian-translated words in the
// instruction. // instruction.
std::vector<uint32_t> endian_converted_words = {first_word}; _.endian_converted_words.clear();
_.endian_converted_words.push_back(first_word);
if (_.requires_endian_conversion) { if (_.requires_endian_conversion) {
// Most instructions have fewer than 25 words. // Most instructions have fewer than 25 words.
endian_converted_words.reserve(25); _.endian_converted_words.reserve(25);
} }
// After a successful parse of the instruction, the inst.operands member // After a successful parse of the instruction, the inst.operands member
// will point to this vector's storage. // will point to this vector's storage.
std::vector<spv_parsed_operand_t> operands;
// Most instructions have fewer than 25 logical operands. // Most instructions have fewer than 25 logical operands.
operands.reserve(25); _.operands.clear();
_.operands.reserve(25);
assert(_.word_index < _.num_words); assert(_.word_index < _.num_words);
// Decompose and check the first word. // Decompose and check the first word.
@ -323,8 +328,8 @@ spv_result_t Parser::parseInstruction() {
spv_operand_type_t type = spvTakeFirstMatchableOperand(&expected_operands); spv_operand_type_t type = spvTakeFirstMatchableOperand(&expected_operands);
if (auto error = if (auto error =
parseOperand(inst_offset, &inst, type, &endian_converted_words, parseOperand(inst_offset, &inst, type, &_.endian_converted_words,
&operands, &expected_operands)) { &_.operands, &expected_operands)) {
return error; return error;
} }
} }
@ -351,15 +356,15 @@ spv_result_t Parser::parseInstruction() {
// performed, then the vector only contains the initial opcode/word-count // performed, then the vector only contains the initial opcode/word-count
// word. // word.
assert(!_.requires_endian_conversion || assert(!_.requires_endian_conversion ||
(inst_word_count == endian_converted_words.size())); (inst_word_count == _.endian_converted_words.size()));
assert(_.requires_endian_conversion || (endian_converted_words.size() == 1)); assert(_.requires_endian_conversion || (_.endian_converted_words.size() == 1));
recordNumberType(inst_offset, &inst); recordNumberType(inst_offset, &inst);
if (_.requires_endian_conversion) { if (_.requires_endian_conversion) {
// We must wait until here to set this pointer, because the vector might // We must wait until here to set this pointer, because the vector might
// have been be resized while we accumulated its elements. // have been be resized while we accumulated its elements.
inst.words = endian_converted_words.data(); inst.words = _.endian_converted_words.data();
} else { } else {
// If no conversion is required, then just point to the underlying binary. // If no conversion is required, then just point to the underlying binary.
// This saves time and space. // This saves time and space.
@ -369,8 +374,8 @@ spv_result_t Parser::parseInstruction() {
// We must wait until here to set this pointer, because the vector might // We must wait until here to set this pointer, because the vector might
// have been be resized while we accumulated its elements. // have been be resized while we accumulated its elements.
inst.operands = operands.data(); inst.operands = _.operands.data();
inst.num_operands = uint16_t(operands.size()); inst.num_operands = uint16_t(_.operands.size());
// Issue the callback. The callee should know that all the storage in inst // Issue the callback. The callee should know that all the storage in inst
// is transient, and will disappear immediately afterward. // is transient, and will disappear immediately afterward.