Optimize Instruction::Instruction (#4705)

Avoid constructing temporary vector + copying operands multiple times.
Add SmallVector(InputIt first, InputIt last), matching std::vector.
This commit is contained in:
pd-valve 2022-02-10 10:31:07 -08:00 committed by GitHub
parent a383c476e6
commit 44923beb52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 6 deletions

View File

@ -76,10 +76,9 @@ Instruction::Instruction(IRContext* c, const spv_parsed_instruction_t& inst,
dbg_scope_(kNoDebugScope, kNoInlinedAt) {
for (uint32_t i = 0; i < inst.num_operands; ++i) {
const auto& current_payload = inst.operands[i];
std::vector<uint32_t> words(
inst.words + current_payload.offset,
operands_.emplace_back(
current_payload.type, inst.words + current_payload.offset,
inst.words + current_payload.offset + current_payload.num_words);
operands_.emplace_back(current_payload.type, std::move(words));
}
assert((!IsLineInst() || dbg_line.empty()) &&
"Op(No)Line attaching to Op(No)Line found");
@ -96,10 +95,9 @@ Instruction::Instruction(IRContext* c, const spv_parsed_instruction_t& inst,
dbg_scope_(dbg_scope) {
for (uint32_t i = 0; i < inst.num_operands; ++i) {
const auto& current_payload = inst.operands[i];
std::vector<uint32_t> words(
inst.words + current_payload.offset,
operands_.emplace_back(
current_payload.type, inst.words + current_payload.offset,
inst.words + current_payload.offset + current_payload.num_words);
operands_.emplace_back(current_payload.type, std::move(words));
}
}

View File

@ -84,6 +84,11 @@ struct Operand {
Operand(spv_operand_type_t t, const OperandData& w) : type(t), words(w) {}
template <class InputIt>
Operand(spv_operand_type_t t, InputIt firstOperandData,
InputIt lastOperandData)
: type(t), words(firstOperandData, lastOperandData) {}
spv_operand_type_t type; // Type of this logical operand.
OperandData words; // Binary segments of this logical operand.

View File

@ -64,6 +64,11 @@ class SmallVector {
}
}
template <class InputIt>
SmallVector(InputIt first, InputIt last) : SmallVector() {
insert(end(), first, last);
}
SmallVector(std::vector<T>&& vec) : SmallVector() {
if (vec.size() > small_size) {
large_data_ = MakeUnique<std::vector<T>>(std::move(vec));

View File

@ -56,6 +56,18 @@ TEST(SmallVectorTest, Initialize_list2) {
}
}
TEST(SmallVectorTest, Initialize_list3) {
std::vector<uint32_t> result = {0, 1, 2, 3};
SmallVector<uint32_t, 6> vec(result.begin(), result.end());
EXPECT_FALSE(vec.empty());
EXPECT_EQ(vec.size(), 4);
for (uint32_t i = 0; i < vec.size(); ++i) {
EXPECT_EQ(vec[i], result[i]);
}
}
TEST(SmallVectorTest, Initialize_copy1) {
SmallVector<uint32_t, 6> vec1 = {0, 1, 2, 3};
SmallVector<uint32_t, 6> vec2(vec1);