forked from KhronosGroup/SPIRV-Tools
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Id descriptors are computed as a recursive hash of all instructions used to define an id. Descriptors are invarint of actual id values and the similar code in different files would produce the same descriptors. Multiple ids can have the same descriptor. For example %1 = OpConstant %u32 1 %2 = OpConstant %u32 1 would produce two ids with the same descriptor. But %3 = OpConstant %s32 1 %4 = OpConstant %u32 2 would have descriptors different from %1 and %2. Descriptors will be used as handles of move-to-front sequences in SPIR-V compression.
- Loading branch information
Showing
9 changed files
with
316 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// Copyright (c) 2017 Google Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#include "id_descriptor.h" | ||
|
||
#include <cassert> | ||
#include <iostream> | ||
|
||
#include "opcode.h" | ||
#include "operand.h" | ||
|
||
namespace libspirv { | ||
|
||
namespace { | ||
|
||
// Hashes an array of words. Order of words is important. | ||
uint32_t HashU32Array(const std::vector<uint32_t>& words) { | ||
// The hash function is a sum of hashes of each word seeded by word index. | ||
// Knuth's multiplicative hash is used to hash the words. | ||
const uint32_t kKnuthMulHash = 2654435761; | ||
uint32_t val = 0; | ||
for (uint32_t i = 0; i < words.size(); ++i) { | ||
val += (words[i] + i + 123) * kKnuthMulHash; | ||
} | ||
return val; | ||
} | ||
|
||
} // namespace | ||
|
||
uint32_t IdDescriptorCollection::ProcessInstruction( | ||
const spv_parsed_instruction_t& inst) { | ||
if (!inst.result_id) | ||
return 0; | ||
|
||
assert(words_.empty()); | ||
words_.push_back(inst.words[0]); | ||
|
||
for (size_t operand_index = 0; operand_index < inst.num_operands; | ||
++operand_index) { | ||
const auto &operand = inst.operands[operand_index]; | ||
if (spvIsIdType(operand.type)) { | ||
const uint32_t id = inst.words[operand.offset]; | ||
const auto it = id_to_descriptor_.find(id); | ||
// Forward declared ids are not hashed. | ||
if (it != id_to_descriptor_.end()) { | ||
words_.push_back(it->second); | ||
} | ||
} else { | ||
for (size_t operand_word_index = 0; | ||
operand_word_index < operand.num_words; ++operand_word_index) { | ||
words_.push_back(inst.words[operand.offset + operand_word_index]); | ||
} | ||
} | ||
} | ||
|
||
const uint32_t descriptor = HashU32Array(words_); | ||
assert(descriptor); | ||
|
||
words_.clear(); | ||
|
||
const auto result = id_to_descriptor_.emplace(inst.result_id, descriptor); | ||
assert(result.second); | ||
(void)result; | ||
return descriptor; | ||
} | ||
|
||
} // namespace libspirv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// Copyright (c) 2017 Google Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#ifndef LIBSPIRV_ID_DESCRIPTOR_H_ | ||
#define LIBSPIRV_ID_DESCRIPTOR_H_ | ||
|
||
#include <unordered_map> | ||
#include <vector> | ||
|
||
#include "spirv-tools/libspirv.hpp" | ||
|
||
namespace libspirv { | ||
|
||
// Computes and stores id descriptors. | ||
// | ||
// Descriptors are computed as hash of all words in the instruction where ids | ||
// were substituted with previously computed descriptors. | ||
class IdDescriptorCollection { | ||
public: | ||
IdDescriptorCollection() { | ||
words_.reserve(16); | ||
} | ||
|
||
// Computes descriptor for the result id of the given instruction and | ||
// registers it in id_to_descriptor_. Returns the computed descriptor. | ||
// This function needs to be sequentially called for every instruction in the | ||
// module. | ||
uint32_t ProcessInstruction(const spv_parsed_instruction_t& inst); | ||
|
||
// Returns a previously computed descriptor id. | ||
uint32_t GetDescriptor(uint32_t id) const { | ||
const auto it = id_to_descriptor_.find(id); | ||
if (it == id_to_descriptor_.end()) | ||
return 0; | ||
return it->second; | ||
} | ||
|
||
private: | ||
std::unordered_map<uint32_t, uint32_t> id_to_descriptor_; | ||
|
||
// Scratch buffer used for hashing. Class member to optimize on allocation. | ||
std::vector<uint32_t> words_; | ||
}; | ||
|
||
} // namespace libspirv | ||
|
||
#endif // LIBSPIRV_ID_DESCRIPTOR_H_ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.