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.
std::unordered_map<uint32_t, spv_ext_inst_type_t>
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,
// then converted_words contains the the endian-translated words in the
// 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) {
// 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
// will point to this vector's storage.
std::vector<spv_parsed_operand_t> operands;
// Most instructions have fewer than 25 logical operands.
operands.reserve(25);
_.operands.clear();
_.operands.reserve(25);
assert(_.word_index < _.num_words);
// Decompose and check the first word.
@ -323,8 +328,8 @@ spv_result_t Parser::parseInstruction() {
spv_operand_type_t type = spvTakeFirstMatchableOperand(&expected_operands);
if (auto error =
parseOperand(inst_offset, &inst, type, &endian_converted_words,
&operands, &expected_operands)) {
parseOperand(inst_offset, &inst, type, &_.endian_converted_words,
&_.operands, &expected_operands)) {
return error;
}
}
@ -351,15 +356,15 @@ spv_result_t Parser::parseInstruction() {
// performed, then the vector only contains the initial opcode/word-count
// word.
assert(!_.requires_endian_conversion ||
(inst_word_count == endian_converted_words.size()));
assert(_.requires_endian_conversion || (endian_converted_words.size() == 1));
(inst_word_count == _.endian_converted_words.size()));
assert(_.requires_endian_conversion || (_.endian_converted_words.size() == 1));
recordNumberType(inst_offset, &inst);
if (_.requires_endian_conversion) {
// We must wait until here to set this pointer, because the vector might
// have been be resized while we accumulated its elements.
inst.words = endian_converted_words.data();
inst.words = _.endian_converted_words.data();
} else {
// If no conversion is required, then just point to the underlying binary.
// 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
// have been be resized while we accumulated its elements.
inst.operands = operands.data();
inst.num_operands = uint16_t(operands.size());
inst.operands = _.operands.data();
inst.num_operands = uint16_t(_.operands.size());
// Issue the callback. The callee should know that all the storage in inst
// is transient, and will disappear immediately afterward.