diff options
120 files changed, 2585 insertions, 2996 deletions
diff --git a/source/binary.cpp b/source/binary.cpp index 2ade2546..24a2b923 100644 --- a/source/binary.cpp +++ b/source/binary.cpp @@ -179,12 +179,11 @@ class Parser { word_index(0), endian(), requires_endian_conversion(false) { - - // Temporary storage for parser state within a single instruction. - // Most instructions require fewer than 25 words or operands. - operands.reserve(25); - endian_converted_words.reserve(25); - expected_operands.reserve(25); + // Temporary storage for parser state within a single instruction. + // Most instructions require fewer than 25 words or operands. + operands.reserve(25); + endian_converted_words.reserve(25); + expected_operands.reserve(25); } State() : State(0, 0, nullptr) {} const uint32_t* words; // Words in the binary SPIR-V module. @@ -310,7 +309,8 @@ spv_result_t Parser::parseInstruction() { // own operands depending on the selected extended instruction. _.expected_operands.clear(); for (auto i = 0; i < opcode_desc->numTypes; i++) - _.expected_operands.push_back(opcode_desc->operandTypes[opcode_desc->numTypes - i - 1]); + _.expected_operands.push_back( + opcode_desc->operandTypes[opcode_desc->numTypes - i - 1]); while (_.word_index < inst_offset + inst_word_count) { const uint16_t inst_word_index = uint16_t(_.word_index - inst_offset); @@ -323,7 +323,8 @@ spv_result_t Parser::parseInstruction() { << inst_word_count << "."; } - spv_operand_type_t type = spvTakeFirstMatchableOperand(&_.expected_operands); + spv_operand_type_t type = + spvTakeFirstMatchableOperand(&_.expected_operands); if (auto error = parseOperand(inst_offset, &inst, type, &_.endian_converted_words, @@ -355,7 +356,8 @@ spv_result_t Parser::parseInstruction() { // word. assert(!_.requires_endian_conversion || (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); @@ -430,8 +432,8 @@ spv_result_t Parser::parseOperand(size_t inst_offset, // Save the result ID to type ID mapping. // In the grammar, type ID always appears before result ID. if (_.id_to_type_id.find(inst->result_id) != _.id_to_type_id.end()) - return diagnostic(SPV_ERROR_INVALID_ID) << "Id " << inst->result_id - << " is defined more than once"; + return diagnostic(SPV_ERROR_INVALID_ID) + << "Id " << inst->result_id << " is defined more than once"; // Record it. // A regular value maps to its type. Some instructions (e.g. OpLabel) // have no type Id, and will map to 0. The result Id for a @@ -477,8 +479,8 @@ spv_result_t Parser::parseOperand(size_t inst_offset, case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: { assert(SpvOpSpecConstantOp == opcode); if (grammar_.lookupSpecConstantOpcode(SpvOp(word))) { - return diagnostic() << "Invalid " << spvOperandTypeStr(type) << ": " - << word; + return diagnostic() + << "Invalid " << spvOperandTypeStr(type) << ": " << word; } spv_opcode_desc opcode_entry = nullptr; if (grammar_.lookupOpcode(SpvOp(word), &opcode_entry)) { @@ -581,8 +583,8 @@ spv_result_t Parser::parseOperand(size_t inst_offset, const spv_ext_inst_type_t ext_inst_type = spvExtInstImportTypeGet(string); if (SPV_EXT_INST_TYPE_NONE == ext_inst_type) { - return diagnostic() << "Invalid extended instruction import '" - << string << "'"; + return diagnostic() + << "Invalid extended instruction import '" << string << "'"; } // We must have parsed a valid result ID. It's a condition // of the grammar, and we only accept non-zero result Ids. @@ -620,9 +622,9 @@ spv_result_t Parser::parseOperand(size_t inst_offset, spv_operand_desc entry; if (grammar_.lookupOperand(type, word, &entry)) { - return diagnostic() << "Invalid " - << spvOperandTypeStr(parsed_operand.type) - << " operand: " << word; + return diagnostic() + << "Invalid " << spvOperandTypeStr(parsed_operand.type) + << " operand: " << word; } // Prepare to accept operands to this operand, if needed. spvPushOperandTypes(entry->operandTypes, expected_operands); diff --git a/source/cfa.h b/source/cfa.h index 6cba06ab..56f8f118 100644 --- a/source/cfa.h +++ b/source/cfa.h @@ -17,9 +17,9 @@ #include <algorithm> #include <cassert> +#include <cstdint> #include <functional> #include <map> -#include <cstdint> #include <unordered_map> #include <unordered_set> #include <utility> @@ -36,12 +36,12 @@ using std::vector; namespace spvtools { // Control Flow Analysis of control flow graphs of basic block nodes |BB|. -template<class BB> class CFA { +template <class BB> +class CFA { using bb_ptr = BB*; using cbb_ptr = const BB*; using bb_iter = typename std::vector<BB*>::const_iterator; - using get_blocks_func = - std::function<const std::vector<BB*>*(const BB*)>; + using get_blocks_func = std::function<const std::vector<BB*>*(const BB*)>; struct block_info { cbb_ptr block; ///< pointer to the block @@ -50,15 +50,16 @@ template<class BB> class CFA { /// Returns true if a block with @p id is found in the @p work_list vector /// - /// @param[in] work_list Set of blocks visited in the the depth first traversal + /// @param[in] work_list Set of blocks visited in the the depth first + /// traversal /// of the CFG /// @param[in] id The ID of the block being checked /// /// @return true if the edge work_list.back().block->id() => id is a back-edge - static bool FindInWorkList( - const std::vector<block_info>& work_list, uint32_t id); + static bool FindInWorkList(const std::vector<block_info>& work_list, + uint32_t id); -public: + public: /// @brief Depth first traversal starting from the \p entry BasicBlock /// /// This function performs a depth first traversal from the \p entry @@ -75,15 +76,16 @@ public: /// CFG following postorder traversal semantics /// @param[in] backedge A function that will be called when a backedge is /// encountered during a traversal - /// NOTE: The @p successor_func and predecessor_func each return a pointer to a + /// NOTE: The @p successor_func and predecessor_func each return a pointer to + /// a /// collection such that iterators to that collection remain valid for the /// lifetime of the algorithm. - static void DepthFirstTraversal(const BB* entry, - get_blocks_func successor_func, - std::function<void(cbb_ptr)> preorder, - std::function<void(cbb_ptr)> postorder, - std::function<void(cbb_ptr, cbb_ptr)> backedge); - + static void DepthFirstTraversal( + const BB* entry, get_blocks_func successor_func, + std::function<void(cbb_ptr)> preorder, + std::function<void(cbb_ptr)> postorder, + std::function<void(cbb_ptr, cbb_ptr)> backedge); + /// @brief Calculates dominator edges for a set of blocks /// /// Computes dominators using the algorithm of Cooper, Harvey, and Kennedy @@ -92,54 +94,58 @@ public: /// The algorithm assumes there is a unique root node (a node without /// predecessors), and it is therefore at the end of the postorder vector. /// - /// This function calculates the dominator edges for a set of blocks in the CFG. + /// This function calculates the dominator edges for a set of blocks in the + /// CFG. /// Uses the dominator algorithm by Cooper et al. /// - /// @param[in] postorder A vector of blocks in post order traversal order + /// @param[in] postorder A vector of blocks in post order traversal + /// order /// in a CFG - /// @param[in] predecessor_func Function used to get the predecessor nodes of a + /// @param[in] predecessor_func Function used to get the predecessor nodes of + /// a /// block /// /// @return the dominator tree of the graph, as a vector of pairs of nodes. /// The first node in the pair is a node in the graph. The second node in the - /// pair is its immediate dominator in the sense of Cooper et.al., where a block - /// without predecessors (such as the root node) is its own immediate dominator. + /// pair is its immediate dominator in the sense of Cooper et.al., where a + /// block + /// without predecessors (such as the root node) is its own immediate + /// dominator. static vector<pair<BB*, BB*>> CalculateDominators( - const vector<cbb_ptr>& postorder, get_blocks_func predecessor_func); + const vector<cbb_ptr>& postorder, get_blocks_func predecessor_func); // Computes a minimal set of root nodes required to traverse, in the forward // direction, the CFG represented by the given vector of blocks, and successor // and predecessor functions. When considering adding two nodes, each having // predecessors, favour using the one that appears earlier on the input blocks // list. - static std::vector<BB*> TraversalRoots( - const std::vector<BB*>& blocks, - get_blocks_func succ_func, - get_blocks_func pred_func); + static std::vector<BB*> TraversalRoots(const std::vector<BB*>& blocks, + get_blocks_func succ_func, + get_blocks_func pred_func); static void ComputeAugmentedCFG( - std::vector<BB*>& ordered_blocks, - BB* pseudo_entry_block, - BB* pseudo_exit_block, - std::unordered_map<const BB*, std::vector<BB*>>* augmented_successors_map, - std::unordered_map<const BB*, std::vector<BB*>>* augmented_predecessors_map, - get_blocks_func succ_func, - get_blocks_func pred_func); + std::vector<BB*>& ordered_blocks, BB* pseudo_entry_block, + BB* pseudo_exit_block, + std::unordered_map<const BB*, std::vector<BB*>>* augmented_successors_map, + std::unordered_map<const BB*, std::vector<BB*>>* + augmented_predecessors_map, + get_blocks_func succ_func, get_blocks_func pred_func); }; -template<class BB> bool CFA<BB>::FindInWorkList(const vector<block_info>& work_list, - uint32_t id) { +template <class BB> +bool CFA<BB>::FindInWorkList(const vector<block_info>& work_list, uint32_t id) { for (const auto b : work_list) { if (b.block->id() == id) return true; } return false; } -template<class BB> void CFA<BB>::DepthFirstTraversal(const BB* entry, - get_blocks_func successor_func, - function<void(cbb_ptr)> preorder, - function<void(cbb_ptr)> postorder, - function<void(cbb_ptr, cbb_ptr)> backedge) { +template <class BB> +void CFA<BB>::DepthFirstTraversal(const BB* entry, + get_blocks_func successor_func, + function<void(cbb_ptr)> preorder, + function<void(cbb_ptr)> postorder, + function<void(cbb_ptr, cbb_ptr)> backedge) { unordered_set<uint32_t> processed; /// NOTE: work_list is the sequence of nodes from the root node to the node @@ -147,7 +153,7 @@ template<class BB> void CFA<BB>::DepthFirstTraversal(const BB* entry, vector<block_info> work_list; work_list.reserve(10); - work_list.push_back({ entry, begin(*successor_func(entry)) }); + work_list.push_back({entry, begin(*successor_func(entry))}); preorder(entry); processed.insert(entry->id()); @@ -156,8 +162,7 @@ template<class BB> void CFA<BB>::DepthFirstTraversal(const BB* entry, if (top.iter == end(*successor_func(top.block))) { postorder(top.block); work_list.pop_back(); - } - else { + } else { BB* child = *top.iter; top.iter++; if (FindInWorkList(work_list, child->id())) { @@ -166,16 +171,16 @@ template<class BB> void CFA<BB>::DepthFirstTraversal(const BB* entry, if (processed.count(child->id()) == 0) { preorder(child); work_list.emplace_back( - block_info{ child, begin(*successor_func(child)) }); + block_info{child, begin(*successor_func(child))}); processed.insert(child->id()); } } } } -template<class BB> +template <class BB> vector<pair<BB*, BB*>> CFA<BB>::CalculateDominators( - const vector<cbb_ptr>& postorder, get_blocks_func predecessor_func) { + const vector<cbb_ptr>& postorder, get_blocks_func predecessor_func) { struct block_detail { size_t dominator; ///< The index of blocks's dominator in post order array size_t postorder_index; ///< The index of the block in the post order array @@ -184,7 +189,7 @@ vector<pair<BB*, BB*>> CFA<BB>::CalculateDominators( unordered_map<cbb_ptr, block_detail> idoms; for (size_t i = 0; i < postorder.size(); i++) { - idoms[postorder[i]] = { undefined_dom, i }; + idoms[postorder[i]] = {undefined_dom, i}; } idoms[postorder.back()].dominator = idoms[postorder.back()].postorder_index; @@ -196,10 +201,10 @@ vector<pair<BB*, BB*>> CFA<BB>::CalculateDominators( // Find the first processed/reachable predecessor that is reachable // in the forward traversal. auto res = find_if(begin(predecessors), end(predecessors), - [&idoms, undefined_dom](BB* pred) { - return idoms.count(pred) && - idoms[pred].dominator != undefined_dom; - }); + [&idoms, undefined_dom](BB* pred) { + return idoms.count(pred) && + idoms[pred].dominator != undefined_dom; + }); if (res == end(predecessors)) continue; const BB* idom = *res; size_t idom_idx = idoms[idom].postorder_index; @@ -236,17 +241,16 @@ vector<pair<BB*, BB*>> CFA<BB>::CalculateDominators( for (auto idom : idoms) { // NOTE: performing a const cast for convenient usage with // UpdateImmediateDominators - out.push_back({ const_cast<BB*>(get<0>(idom)), - const_cast<BB*>(postorder[get<1>(idom).dominator]) }); + out.push_back({const_cast<BB*>(get<0>(idom)), + const_cast<BB*>(postorder[get<1>(idom).dominator])}); } return out; } -template<class BB> -std::vector<BB*> CFA<BB>::TraversalRoots( - const std::vector<BB*>& blocks, - get_blocks_func succ_func, - get_blocks_func pred_func) { +template <class BB> +std::vector<BB*> CFA<BB>::TraversalRoots(const std::vector<BB*>& blocks, + get_blocks_func succ_func, + get_blocks_func pred_func) { // The set of nodes which have been visited from any of the roots so far. std::unordered_set<const BB*> visited; @@ -254,11 +258,10 @@ std::vector<BB*> CFA<BB>::TraversalRoots( auto ignore_block = [](const BB*) {}; auto ignore_blocks = [](const BB*, const BB*) {}; - auto traverse_from_root = [&mark_visited, &succ_func, &ignore_block, - &ignore_blocks](const BB* entry) { - DepthFirstTraversal( - entry, succ_func, mark_visited, ignore_block, ignore_blocks); + &ignore_blocks](const BB* entry) { + DepthFirstTraversal(entry, succ_func, mark_visited, ignore_block, + ignore_blocks); }; std::vector<BB*> result; @@ -283,15 +286,13 @@ std::vector<BB*> CFA<BB>::TraversalRoots( return result; } -template<class BB> +template <class BB> void CFA<BB>::ComputeAugmentedCFG( - std::vector<BB*>& ordered_blocks, - BB* pseudo_entry_block, BB* pseudo_exit_block, + std::vector<BB*>& ordered_blocks, BB* pseudo_entry_block, + BB* pseudo_exit_block, std::unordered_map<const BB*, std::vector<BB*>>* augmented_successors_map, std::unordered_map<const BB*, std::vector<BB*>>* augmented_predecessors_map, - get_blocks_func succ_func, - get_blocks_func pred_func) { - + get_blocks_func succ_func, get_blocks_func pred_func) { // Compute the successors of the pseudo-entry block, and // the predecessors of the pseudo exit block. auto sources = TraversalRoots(ordered_blocks, succ_func, pred_func); @@ -308,7 +309,7 @@ void CFA<BB>::ComputeAugmentedCFG( // constraint when A is a loop header that points to itself as its // own continue target, and B is the latch block for the loop. std::vector<BB*> reversed_blocks(ordered_blocks.rbegin(), - ordered_blocks.rend()); + ordered_blocks.rend()); auto sinks = TraversalRoots(reversed_blocks, pred_func, succ_func); // Wire up the pseudo entry block. @@ -332,6 +333,6 @@ void CFA<BB>::ComputeAugmentedCFG( } }; -} // namespace spvtools +} // namespace spvtools #endif // SPVTOOLS_CFA_H_ diff --git a/source/comp/markv.h b/source/comp/markv.h index b3e27bbd..288e6808 100644 --- a/source/comp/markv.h +++ b/source/comp/markv.h @@ -38,9 +38,9 @@ struct MarkvCodecOptions { // |bits| is a textual representation of the MARK-V bit sequence used to encode // the instruction (char '0' for 0, char '1' for 1). // |comment| contains all logs generated while processing the instruction. -using MarkvDebugConsumer = std::function<bool( - const std::vector<uint32_t>& words, const std::string& bits, - const std::string& comment)>; +using MarkvDebugConsumer = + std::function<bool(const std::vector<uint32_t>& words, + const std::string& bits, const std::string& comment)>; // Logging callback. Called often (if decoder reads a single bit, the log // consumer will receive 1 character string with that bit). @@ -54,26 +54,20 @@ using MarkvLogConsumer = std::function<void(const std::string& snippet)>; // Encodes the given SPIR-V binary to MARK-V binary. // |log_consumer| is optional (pass MarkvLogConsumer() to disable). // |debug_consumer| is optional (pass MarkvDebugConsumer() to disable). -spv_result_t SpirvToMarkv(spv_const_context context, - const std::vector<uint32_t>& spirv, - const MarkvCodecOptions& options, - const MarkvModel& markv_model, - MessageConsumer message_consumer, - MarkvLogConsumer log_consumer, - MarkvDebugConsumer debug_consumer, - std::vector<uint8_t>* markv); +spv_result_t SpirvToMarkv( + spv_const_context context, const std::vector<uint32_t>& spirv, + const MarkvCodecOptions& options, const MarkvModel& markv_model, + MessageConsumer message_consumer, MarkvLogConsumer log_consumer, + MarkvDebugConsumer debug_consumer, std::vector<uint8_t>* markv); // Decodes a SPIR-V binary from the given MARK-V binary. // |log_consumer| is optional (pass MarkvLogConsumer() to disable). // |debug_consumer| is optional (pass MarkvDebugConsumer() to disable). -spv_result_t MarkvToSpirv(spv_const_context context, - const std::vector<uint8_t>& markv, - const MarkvCodecOptions& options, - const MarkvModel& markv_model, - MessageConsumer message_consumer, - MarkvLogConsumer log_consumer, - MarkvDebugConsumer debug_consumer, - std::vector<uint32_t>* spirv); +spv_result_t MarkvToSpirv( + spv_const_context context, const std::vector<uint8_t>& markv, + const MarkvCodecOptions& options, const MarkvModel& markv_model, + MessageConsumer message_consumer, MarkvLogConsumer log_consumer, + MarkvDebugConsumer debug_consumer, std::vector<uint32_t>* spirv); } // namespace spvtools diff --git a/source/comp/markv_codec.cpp b/source/comp/markv_codec.cpp index b5df2b06..ae89cccb 100644 --- a/source/comp/markv_codec.cpp +++ b/source/comp/markv_codec.cpp @@ -30,9 +30,9 @@ #include <memory> #include <numeric> #include <string> -#include <vector> #include <unordered_map> #include <unordered_set> +#include <vector> #include "spirv/1.2/GLSL.std.450.h" #include "spirv/1.2/OpenCL.std.h" @@ -41,8 +41,8 @@ #include "binary.h" #include "diagnostic.h" #include "enum_string_mapping.h" -#include "extensions.h" #include "ext_inst.h" +#include "extensions.h" #include "id_descriptor.h" #include "instruction.h" #include "markv.h" @@ -56,9 +56,9 @@ #include "util/huffman_codec.h" #include "util/move_to_front.h" #include "util/parse_number.h" -#include "validate.h" #include "val/instruction.h" #include "val/validation_state.h" +#include "validate.h" using libspirv::IdDescriptorCollection; using libspirv::Instruction; @@ -161,31 +161,31 @@ GetMtfHuffmanCodecs() { std::unique_ptr<HuffmanCodec<uint32_t>> codec; codec.reset(new HuffmanCodec<uint32_t>(std::map<uint32_t, uint32_t>({ - { 0, 5 }, - { 1, 40 }, - { 2, 10 }, - { 3, 5 }, - { 4, 5 }, - { 5, 5 }, - { 6, 3 }, - { 7, 3 }, - { 8, 3 }, - { 9, 3 }, - { kMtfRankEncodedByValueSignal, 10 }, + {0, 5}, + {1, 40}, + {2, 10}, + {3, 5}, + {4, 5}, + {5, 5}, + {6, 3}, + {7, 3}, + {8, 3}, + {9, 3}, + {kMtfRankEncodedByValueSignal, 10}, }))); codecs.emplace(kMtfAll, std::move(codec)); codec.reset(new HuffmanCodec<uint32_t>(std::map<uint32_t, uint32_t>({ - { 1, 50 }, - { 2, 20 }, - { 3, 5 }, - { 4, 5 }, - { 5, 2 }, - { 6, 1 }, - { 7, 1 }, - { 8, 1 }, - { 9, 1 }, - { kMtfRankEncodedByValueSignal, 10 }, + {1, 50}, + {2, 20}, + {3, 5}, + {4, 5}, + {5, 2}, + {6, 1}, + {7, 1}, + {8, 1}, + {9, 1}, + {kMtfRankEncodedByValueSignal, 10}, }))); codecs.emplace(kMtfGenericNonZeroRank, std::move(codec)); @@ -258,9 +258,7 @@ bool OpcodeHasFixedNumberOfOperands(SpvOp opcode) { return false; } -size_t GetNumBitsToNextByte(size_t bit_pos) { - return (8 - (bit_pos % 8)) % 8; -} +size_t GetNumBitsToNextByte(size_t bit_pos) { return (8 - (bit_pos % 8)) % 8; } // Defines and returns current MARK-V version. uint32_t GetMarkvVersion() { @@ -286,10 +284,8 @@ class MarkvLogger { } void AppendBitSequence(const std::string& str) { - if (debug_consumer_) - instruction_bits_ << str; - if (use_delimiter_) - Append("-"); + if (debug_consumer_) instruction_bits_ << str; + if (use_delimiter_) Append("-"); Append(str); use_delimiter_ = true; } @@ -323,10 +319,8 @@ class MarkvLogger { MarkvLogger& operator=(MarkvLogger&&) = delete; void Append(const std::string& str) { - if (log_consumer_) - log_consumer_(str); - if (debug_consumer_) - instruction_comment_ << str; + if (log_consumer_) log_consumer_(str); + if (debug_consumer_) instruction_comment_ << str; } MarkvLogConsumer log_consumer_; @@ -346,9 +340,7 @@ class MarkvLogger { // - SPIR-V grammar and helper functions. class MarkvCodecBase { public: - virtual ~MarkvCodecBase() { - spvValidatorOptionsDestroy(validator_options_); - } + virtual ~MarkvCodecBase() { spvValidatorOptionsDestroy(validator_options_); } MarkvCodecBase() = delete; @@ -377,17 +369,19 @@ class MarkvCodecBase { explicit MarkvCodecBase(spv_const_context context, spv_validator_options validator_options, const MarkvModel* model) - : validator_options_(validator_options), grammar_(context), - model_(model), mtf_huffman_codecs_(GetMtfHuffmanCodecs()), + : validator_options_(validator_options), + grammar_(context), + model_(model), + mtf_huffman_codecs_(GetMtfHuffmanCodecs()), context_(context), - vstate_(validator_options ? - new ValidationState_t(context, validator_options_) : nullptr) {} + vstate_(validator_options + ? new ValidationState_t(context, validator_options_) + : nullptr) {} // Validates a single instruction and updates validation state of the module. // Does nothing and returns SPV_SUCCESS if validator was not created. spv_result_t UpdateValidationState(const spv_parsed_instruction_t& inst) { - if (!vstate_) - return SPV_SUCCESS; + if (!vstate_) return SPV_SUCCESS; return ValidateInstructionAndUpdateValidationState(vstate_.get(), &inst); } @@ -396,8 +390,7 @@ class MarkvCodecBase { // not registered. const Instruction* FindDef(uint32_t id) const { const auto it = id_to_def_instruction_.find(id); - if (it == id_to_def_instruction_.end()) - return nullptr; + if (it == id_to_def_instruction_.end()) return nullptr; return it->second; } @@ -473,44 +466,38 @@ class MarkvCodecBase { // Returns words of the current instruction. Decoder has a different // implementation and the array is valid only until the previously decoded // word. - virtual const uint32_t* GetInstWords() const { - return inst_.words; - } + virtual const uint32_t* GetInstWords() const { return inst_.words; } // Returns the opcode of the previous instruction. SpvOp GetPrevOpcode() const { - if (instructions_.empty()) - return SpvOpNop; + if (instructions_.empty()) return SpvOpNop; return instructions_.back()->opcode(); } // Returns diagnostic stream, position index is set to instruction number. DiagnosticStream Diag(spv_result_t error_code) const { - return DiagnosticStream({0, 0, instructions_.size()}, - context_->consumer, error_code); + return DiagnosticStream({0, 0, instructions_.size()}, context_->consumer, + error_code); } // Returns current id bound. - uint32_t GetIdBound() const { - return id_bound_; - } + uint32_t GetIdBound() const { return id_bound_; } // Sets current id bound, expected to be no lower than the previous one. void SetIdBound(uint32_t id_bound) { assert(id_bound >= id_bound_); id_bound_ = id_bound; - if (vstate_) - vstate_->setIdBound(id_bound); + if (vstate_) vstate_->setIdBound(id_bound); } // Returns Huffman codec for ranks of the mtf with given |handle|. // Different mtfs can use different rank distributions. // May return nullptr if the codec doesn't exist. - const spvutils::HuffmanCodec<uint32_t>* GetMtfHuffmanCodec(uint64_t handle) const { + const spvutils::HuffmanCodec<uint32_t>* GetMtfHuffmanCodec( + uint64_t handle) const { const auto it = mtf_huffman_codecs_.find(handle); - if (it == mtf_huffman_codecs_.end()) - return nullptr; + if (it == mtf_huffman_codecs_.end()) return nullptr; return it->second.get(); } @@ -586,19 +573,17 @@ class MarkvEncoder : public MarkvCodecBase { public: // |model| is owned by the caller, must be not null and valid during the // lifetime of MarkvEncoder. - MarkvEncoder(spv_const_context context, - const MarkvCodecOptions& options, + MarkvEncoder(spv_const_context context, const MarkvCodecOptions& options, const MarkvModel* model) : MarkvCodecBase(context, GetValidatorOptions(options), model), options_(options) { - (void) options_; + (void)options_; } // Writes data from SPIR-V header to MARK-V header. - spv_result_t EncodeHeader( - spv_endianness_t /* endian */, uint32_t /* magic */, - uint32_t version, uint32_t generator, uint32_t id_bound, - uint32_t /* schema */) { + spv_result_t EncodeHeader(spv_endianness_t /* endian */, uint32_t /* magic */, + uint32_t version, uint32_t generator, + uint32_t id_bound, uint32_t /* schema */) { SetIdBound(id_bound); header_.spirv_version = version; header_.spirv_generator = generator; @@ -609,9 +594,8 @@ class MarkvEncoder : public MarkvCodecBase { void CreateLogger(MarkvLogConsumer log_consumer, MarkvDebugConsumer debug_consumer) { logger_.reset(new MarkvLogger(log_consumer, debug_consumer)); - writer_.SetCallback([this](const std::string& str){ - logger_->AppendBitSequence(str); - }); + writer_.SetCallback( + [this](const std::string& str) { logger_->AppendBitSequence(str); }); } // Encodes SPIR-V instruction to MARK-V and writes to bit stream. @@ -634,8 +618,8 @@ class MarkvEncoder : public MarkvCodecBase { assert(writer_.GetData()); std::memcpy(markv.data(), &header_, sizeof(header_)); - std::memcpy(markv.data() + sizeof(header_), - writer_.GetData(), writer_.GetDataSizeBytes()); + std::memcpy(markv.data() + sizeof(header_), writer_.GetData(), + writer_.GetDataSizeBytes()); return markv; } @@ -659,8 +643,8 @@ class MarkvEncoder : public MarkvCodecBase { // Creates and returns validator options. Returned value owned by the caller. static spv_validator_options GetValidatorOptions( const MarkvCodecOptions& options) { - return options.validate_spirv_binary ? - spvValidatorOptionsCreate() : nullptr; + return options.validate_spirv_binary ? spvValidatorOptionsCreate() + : nullptr; } // Writes a single word to bit stream. operand_.type determines if the word is @@ -669,7 +653,8 @@ class MarkvEncoder : public MarkvCodecBase { // Writes both opcode and num_operands as a single code. // Returns SPV_UNSUPPORTED iff no suitable codec was found. - spv_result_t EncodeOpcodeAndNumOperands(uint32_t opcode, uint32_t num_operands); + spv_result_t EncodeOpcodeAndNumOperands(uint32_t opcode, + uint32_t num_operands); // Writes mtf rank to bit stream. |mtf| is used to determine the codec // scheme. |fallback_method| is used if no codec defined for |mtf|. @@ -715,13 +700,12 @@ class MarkvDecoder : public MarkvCodecBase { public: // |model| is owned by the caller, must be not null and valid during the // lifetime of MarkvEncoder. - MarkvDecoder(spv_const_context context, - const std::vector<uint8_t>& markv, - const MarkvCodecOptions& options, - const MarkvModel* model) + MarkvDecoder(spv_const_context context, const std::vector<uint8_t>& markv, + const MarkvCodecOptions& options, const MarkvModel* model) : MarkvCodecBase(context, GetValidatorOptions(options), model), - options_(options), reader_(markv) { - (void) options_; + options_(options), + reader_(markv) { + (void)options_; SetIdBound(1); parsed_operands_.reserve(25); inst_words_.reserve(25); @@ -748,8 +732,8 @@ class MarkvDecoder : public MarkvCodecBase { // Creates and returns validator options. Returned value owned by the caller. static spv_validator_options GetValidatorOptions( const MarkvCodecOptions& options) { - return options.validate_spirv_binary ? - spvValidatorOptionsCreate() : nullptr; + return options.validate_spirv_binary ? spvValidatorOptionsCreate() + : nullptr; } // Reads a single bit from reader_. The read bit is stored in |bit|. @@ -757,8 +741,7 @@ class MarkvDecoder : public MarkvCodecBase { bool ReadBit(bool* bit) { uint64_t bits = 0; const bool result = reader_.ReadBits(&bits, 1); - if (result) - *bit = bits ? true : false; + if (result) *bit = bits ? true : false; return result; }; @@ -803,9 +786,7 @@ class MarkvDecoder : public MarkvCodecBase { bool ReadToByteBreak(size_t byte_break_if_less_than); // Returns instruction words decoded up to this point. - const uint32_t* GetInstWords() const override { - return inst_words_.data(); - } + const uint32_t* GetInstWords() const override { return inst_words_.data(); } // Reads a literal number as it is described in |operand| from the bit stream, // decodes and writes it to spirv_. @@ -866,7 +847,7 @@ void MarkvCodecBase::ProcessCurInstruction() { id_to_def_instruction_.emplace(inst_.result_id, instructions_.back().get()); // Collect ids local to the current function. - if (cur_function_id_){ + if (cur_function_id_) { ids_local_to_cur_function_.push_back(inst_.result_id); } @@ -891,14 +872,12 @@ void MarkvCodecBase::ProcessCurInstruction() { // Remove local ids from MTFs if function end. if (opcode == SpvOpFunctionEnd) { cur_function_id_ = 0; - for (uint32_t id : ids_local_to_cur_function_) - multi_mtf_.RemoveFromAll(id); + for (uint32_t id : ids_local_to_cur_function_) multi_mtf_.RemoveFromAll(id); ids_local_to_cur_function_.clear(); assert(remaining_function_parameter_types_.empty()); } - if (!inst_.result_id) - return; + if (!inst_.result_id) return; { // Save the result ID to type ID mapping. @@ -908,8 +887,8 @@ void MarkvCodecBase::ProcessCurInstruction() { // type-generating instruction (e.g. OpTypeInt) maps to itself. auto insertion_result = id_to_type_id_.emplace( inst_.result_id, - spvOpcodeGeneratesType(SpvOp(inst_.opcode)) ? - inst_.result_id : inst_.type_id); + spvOpcodeGeneratesType(SpvOp(inst_.opcode)) ? inst_.result_id + : inst_.type_id); (void)insertion_result; assert(insertion_result.second); } @@ -962,10 +941,10 @@ void MarkvCodecBase::ProcessCurInstruction() { component_type_id)) { multi_mtf_.Insert(kMtfTypeFloatScalarOrVector, inst_.result_id); } else if (multi_mtf_.HasValue(GetMtfIdGeneratedByOpcode(SpvOpTypeInt), - component_type_id)) { + component_type_id)) { multi_mtf_.Insert(kMtfTypeIntScalarOrVector, inst_.result_id); } else if (multi_mtf_.HasValue(GetMtfIdGeneratedByOpcode(SpvOpTypeBool), - component_type_id)) { + component_type_id)) { multi_mtf_.Insert(kMtfTypeBoolScalarOrVector, inst_.result_id); } multi_mtf_.Insert(GetMtfTypeVectorOfSize(size), inst_.result_id); @@ -1007,8 +986,9 @@ void MarkvCodecBase::ProcessCurInstruction() { case SpvOpTypeImage: case SpvOpTypeSampledImage: case SpvOpTypeSampler: - multi_mtf_.Insert(GetMtfIdWithTypeGeneratedByOpcode( - type_inst->opcode()), inst_.result_id); + multi_mtf_.Insert( + GetMtfIdWithTypeGeneratedByOpcode(type_inst->opcode()), + inst_.result_id); break; default: break; @@ -1056,7 +1036,7 @@ uint64_t MarkvCodecBase::GetRuleBasedMtf() { (inst_.opcode == SpvOpSelectionMerge && operand_index_ == 0) || (inst_.opcode == SpvOpBranch && operand_index_ == 0) || (inst_.opcode == SpvOpBranchConditional && - (operand_index_ == 1 || operand_index_ == 2 )) || + (operand_index_ == 1 || operand_index_ == 2)) || (inst_.opcode == SpvOpPhi && operand_index_ >= 3 && operand_index_ % 2 == 1) || (inst_.opcode == SpvOpSwitch && operand_index_ > 0)) { @@ -1071,8 +1051,7 @@ uint64_t MarkvCodecBase::GetRuleBasedMtf() { case SpvOpFRem: case SpvOpFMod: case SpvOpFNegate: { - if (operand_index_ == 0) - return kMtfTypeFloatScalarOrVector; + if (operand_index_ == 0) return kMtfTypeFloatScalarOrVector; return GetMtfIdOfType(inst_.type_id); } @@ -1086,8 +1065,7 @@ uint64_t MarkvCodecBase::GetRuleBasedMtf() { case SpvOpUMod: case SpvOpSRem: case SpvOpSNegate: { - if (operand_index_ == 0) - return kMtfTypeIntScalarOrVector; + if (operand_index_ == 0) return kMtfTypeIntScalarOrVector; return kMtfIntScalarOrVector; } @@ -1106,14 +1084,11 @@ uint64_t MarkvCodecBase::GetRuleBasedMtf() { case SpvOpFUnordLessThanEqual: case SpvOpFOrdGreaterThanEqual: case SpvOpFUnordGreaterThanEqual: { - if (operand_index_ == 0) - return kMtfTypeBoolScalarOrVector; - if (operand_index_ == 2) - return kMtfFloatScalarOrVector; + if (operand_index_ == 0) return kMtfTypeBoolScalarOrVector; + if (operand_index_ == 2) return kMtfFloatScalarOrVector; if (operand_index_ == 3) { const uint32_t first_operand_id = GetInstWords()[3]; - const uint32_t first_operand_type = - id_to_type_id_.at(first_operand_id); + const uint32_t first_operand_type = id_to_type_id_.at(first_operand_id); return GetMtfIdOfType(first_operand_type); } break; @@ -1139,16 +1114,14 @@ uint64_t MarkvCodecBase::GetRuleBasedMtf() { } assert(inst_.type_id); - if (operand_index_ == 2) - return GetMtfIdOfType(inst_.type_id); + if (operand_index_ == 2) return GetMtfIdOfType(inst_.type_id); if (operand_index_ == 3) return GetMtfIdOfType(GetVectorComponentType(inst_.type_id)); break; } case SpvOpDot: { - if (operand_index_ == 0) - return GetMtfIdGeneratedByOpcode(SpvOpTypeFloat); + if (operand_index_ == 0) return GetMtfIdGeneratedByOpcode(SpvOpTypeFloat); assert(inst_.type_id); if (operand_index_ == 2) @@ -1201,8 +1174,7 @@ uint64_t MarkvCodecBase::GetRuleBasedMtf() { } case SpvOpLoad: { - if (operand_index_ == 0) - return kMtfTypeNonFunction; + if (operand_index_ == 0) return kMtfTypeNonFunction; if (operand_index_ == 2) { assert(inst_.type_id); @@ -1236,16 +1208,14 @@ uint64_t MarkvCodecBase::GetRuleBasedMtf() { case SpvOpAccessChain: { if (operand_index_ == 0) return GetMtfIdGeneratedByOpcode(SpvOpTypePointer); - if (operand_index_ == 2) - return kMtfTypePointerToComposite; + if (operand_index_ == 2) return kMtfTypePointerToComposite; if (operand_index_ >= 3) return GetMtfIdWithTypeGeneratedByOpcode(SpvOpTypeInt); break; } case SpvOpCompositeConstruct: { - if (operand_index_ == 0) - return kMtfTypeComposite; + if (operand_index_ == 0) return kMtfTypeComposite; if (operand_index_ >= 2) { const uint32_t composite_type = GetInstWords()[1]; if (multi_mtf_.HasValue(kMtfTypeFloatScalarOrVector, composite_type)) @@ -1259,14 +1229,12 @@ uint64_t MarkvCodecBase::GetRuleBasedMtf() { } case SpvOpCompositeExtract: { - if (operand_index_ == 2) - return kMtfComposite; + if (operand_index_ == 2) return kMtfComposite; break; } case SpvOpConstantComposite: { - if (operand_index_ == 0) - return kMtfTypeComposite; + if (operand_index_ == 0) return kMtfTypeComposite; if (operand_index_ >= 2) { const Instruction* composite_type_inst = FindDef(inst_.type_id); assert(composite_type_inst); @@ -1383,8 +1351,7 @@ uint64_t MarkvCodecBase::GetRuleBasedMtf() { } case SpvOpFunction: { - if (operand_index_ == 0) - return kMtfTypeReturnedByFunction; + if (operand_index_ == 0) return kMtfTypeReturnedByFunction; if (operand_index_ == 3) { const uint32_t return_type = GetInstWords()[1]; @@ -1394,8 +1361,7 @@ uint64_t MarkvCodecBase::GetRuleBasedMtf() { } case SpvOpFunctionCall: { - if (operand_index_ == 0) - return kMtfTypeReturnedByFunction; + if (operand_index_ == 0) return kMtfTypeReturnedByFunction; if (operand_index_ == 2) { const uint32_t return_type = GetInstWords()[1]; @@ -1405,8 +1371,7 @@ uint64_t MarkvCodecBase::GetRuleBasedMtf() { if (operand_index_ >= 3) { const uint32_t function_id = GetInstWords()[3]; const Instruction* function_inst = FindDef(function_id); - if (!function_inst) - return kMtfObject; + if (!function_inst) return kMtfObject; assert(function_inst->opcode() == SpvOpFunction); @@ -1415,16 +1380,14 @@ uint64_t MarkvCodecBase::GetRuleBasedMtf() { assert(function_type_inst); assert(function_type_inst->opcode() == SpvOpTypeFunction); - const uint32_t argument_type = - function_type_inst->word(operand_index_); + const uint32_t argument_type = function_type_inst->word(operand_index_); return GetMtfIdOfType(argument_type); } break; } case SpvOpReturnValue: { - if (operand_index_ == 0) - return GetMtfIdOfType(cur_function_return_type_); + if (operand_index_ == 0) return GetMtfIdOfType(cur_function_return_type_); break; } @@ -1475,10 +1438,9 @@ spv_result_t MarkvEncoder::EncodeNonIdWord(uint32_t word) { // Encoding failed, write kMarkvNoneOfTheAbove flag. if (!codec->Encode(kMarkvNoneOfTheAbove, &bits, &num_bits)) return Diag(SPV_ERROR_INTERNAL) - << "Non-id word Huffman table for " - << spvOpcodeString(SpvOp(inst_.opcode)) - << " operand index " << operand_index_ - << " is missing kMarkvNoneOfTheAbove"; + << "Non-id word Huffman table for " + << spvOpcodeString(SpvOp(inst_.opcode)) << " operand index " + << operand_index_ << " is missing kMarkvNoneOfTheAbove"; writer_.WriteBits(bits, num_bits); } } @@ -1501,7 +1463,7 @@ spv_result_t MarkvDecoder::DecodeNonIdWord(uint32_t* word) { uint64_t decoded_value = 0; if (!codec->DecodeFromStream(GetReadBitCallback(), &decoded_value)) return Diag(SPV_ERROR_INVALID_BINARY) - << "Failed to decode non-id word with Huffman"; + << "Failed to decode non-id word with Huffman"; if (decoded_value != kMarkvNoneOfTheAbove) { // The word decoded successfully. @@ -1518,24 +1480,25 @@ spv_result_t MarkvDecoder::DecodeNonIdWord(uint32_t* word) { if (chunk_length) { if (!reader_.ReadVariableWidthU32(word, chunk_length)) return Diag(SPV_ERROR_INVALID_BINARY) - << "Failed to decode non-id word with varint"; + << "Failed to decode non-id word with varint"; } else { if (!reader_.ReadUnencoded(word)) return Diag(SPV_ERROR_INVALID_BINARY) - << "Failed to read unencoded non-id word"; + << "Failed to read unencoded non-id word"; } return SPV_SUCCESS; } -spv_result_t MarkvEncoder::EncodeOpcodeAndNumOperands( - uint32_t opcode, uint32_t num_operands) { +spv_result_t MarkvEncoder::EncodeOpcodeAndNumOperands(uint32_t opcode, + uint32_t num_operands) { uint64_t bits = 0; size_t num_bits = 0; const uint32_t word = opcode | (num_operands << 16); // First try to use the Markov chain codec. - auto* codec = model_->GetOpcodeAndNumOperandsMarkovHuffmanCodec(GetPrevOpcode()); + auto* codec = + model_->GetOpcodeAndNumOperandsMarkovHuffmanCodec(GetPrevOpcode()); if (codec) { if (codec->Encode(word, &bits, &num_bits)) { // The word was successfully encoded into bits/num_bits. @@ -1546,9 +1509,9 @@ spv_result_t MarkvEncoder::EncodeOpcodeAndNumOperands( // and use fallback encoding. if (!codec->Encode(kMarkvNoneOfTheAbove, &bits, &num_bits)) return Diag(SPV_ERROR_INTERNAL) - << "opcode_and_num_operands Huffman table for " - << spvOpcodeString(GetPrevOpcode()) - << "is missing kMarkvNoneOfTheAbove"; + << "opcode_and_num_operands Huffman table for " + << spvOpcodeString(GetPrevOpcode()) + << "is missing kMarkvNoneOfTheAbove"; writer_.WriteBits(bits, num_bits); } } @@ -1565,8 +1528,8 @@ spv_result_t MarkvEncoder::EncodeOpcodeAndNumOperands( // and return false. if (!codec->Encode(kMarkvNoneOfTheAbove, &bits, &num_bits)) return Diag(SPV_ERROR_INTERNAL) - << "Global opcode_and_num_operands Huffman table is missing " - << "kMarkvNoneOfTheAbove"; + << "Global opcode_and_num_operands Huffman table is missing " + << "kMarkvNoneOfTheAbove"; writer_.WriteBits(bits, num_bits); return SPV_UNSUPPORTED; } @@ -1575,13 +1538,14 @@ spv_result_t MarkvEncoder::EncodeOpcodeAndNumOperands( spv_result_t MarkvDecoder::DecodeOpcodeAndNumberOfOperands( uint32_t* opcode, uint32_t* num_operands) { // First try to use the Markov chain codec. - auto* codec = model_->GetOpcodeAndNumOperandsMarkovHuffmanCodec(GetPrevOpcode()); + auto* codec = + model_->GetOpcodeAndNumOperandsMarkovHuffmanCodec(GetPrevOpcode()); if (codec) { uint64_t decoded_value = 0; if (!codec->DecodeFromStream(GetReadBitCallback(), &decoded_value)) return Diag(SPV_ERROR_INTERNAL) - << "Failed to decode opcode_and_num_operands, previous opcode is " - << spvOpcodeString(GetPrevOpcode()); + << "Failed to decode opcode_and_num_operands, previous opcode is " + << spvOpcodeString(GetPrevOpcode()); if (decoded_value != kMarkvNoneOfTheAbove) { // The word was successfully decoded. @@ -1599,7 +1563,7 @@ spv_result_t MarkvDecoder::DecodeOpcodeAndNumberOfOperands( uint64_t decoded_value = 0; if (!codec->DecodeFromStream(GetReadBitCallback(), &decoded_value)) return Diag(SPV_ERROR_INTERNAL) - << "Failed to decode opcode_and_num_operands with global codec"; + << "Failed to decode opcode_and_num_operands with global codec"; if (decoded_value == kMarkvNoneOfTheAbove) { // Received kMarkvNoneOfTheAbove signal, fallback further. @@ -1619,8 +1583,7 @@ spv_result_t MarkvEncoder::EncodeMtfRankHuffman(uint32_t rank, uint64_t mtf, codec = GetMtfHuffmanCodec(fallback_method); } - if (!codec) - return Diag(SPV_ERROR_INTERNAL) << "No codec to encode MTF rank"; + if (!codec) return Diag(SPV_ERROR_INTERNAL) << "No codec to encode MTF rank"; uint64_t bits = 0; size_t num_bits = 0; @@ -1628,14 +1591,14 @@ spv_result_t MarkvEncoder::EncodeMtfRankHuffman(uint32_t rank, uint64_t mtf, // Encode using Huffman coding. if (!codec->Encode(rank, &bits, &num_bits)) return Diag(SPV_ERROR_INTERNAL) - << "Failed to encode MTF rank with Huffman"; + << "Failed to encode MTF rank with Huffman"; writer_.WriteBits(bits, num_bits); } else { // Encode by value. if (!codec->Encode(kMtfRankEncodedByValueSignal, &bits, &num_bits)) return Diag(SPV_ERROR_INTERNAL) - << "Failed to encode kMtfRankEncodedByValueSignal"; + << "Failed to encode kMtfRankEncodedByValueSignal"; writer_.WriteBits(bits, num_bits); writer_.WriteVariableWidthU32(rank - kMtfSmallestRankEncodedByValue, @@ -1644,27 +1607,26 @@ spv_result_t MarkvEncoder::EncodeMtfRankHuffman(uint32_t rank, uint64_t mtf, return SPV_SUCCESS; } -spv_result_t MarkvDecoder::DecodeMtfRankHuffman( - uint64_t mtf, uint32_t fallback_method, uint32_t* rank) { +spv_result_t MarkvDecoder::DecodeMtfRankHuffman(uint64_t mtf, + uint32_t fallback_method, + uint32_t* rank) { const auto* codec = GetMtfHuffmanCodec(mtf); if (!codec) { assert(fallback_method != kMtfNone); codec = GetMtfHuffmanCodec(fallback_method); } - if (!codec) - return Diag(SPV_ERROR_INTERNAL) << "No codec to decode MTF rank"; + if (!codec) return Diag(SPV_ERROR_INTERNAL) << "No codec to decode MTF rank"; uint32_t decoded_value = 0; if (!codec->DecodeFromStream(GetReadBitCallback(), &decoded_value)) - return Diag(SPV_ERROR_INTERNAL) - << "Failed to decode MTF rank with Huffman"; + return Diag(SPV_ERROR_INTERNAL) << "Failed to decode MTF rank with Huffman"; if (decoded_value == kMtfRankEncodedByValueSignal) { // Decode by value. if (!reader_.ReadVariableWidthU32(rank, model_->mtf_rank_chunk_length())) return Diag(SPV_ERROR_INTERNAL) - << "Failed to decode MTF rank with varint"; + << "Failed to decode MTF rank with varint"; *rank += kMtfSmallestRankEncodedByValue; } else { // Decode using Huffman coding. @@ -1675,10 +1637,9 @@ spv_result_t MarkvDecoder::DecodeMtfRankHuffman( } spv_result_t MarkvEncoder::EncodeIdWithDescriptor(uint32_t id) { - auto* codec = model_->GetIdDescriptorHuffmanCodec(inst_.opcode, - operand_index_); - if (!codec) - return SPV_UNSUPPORTED; + auto* codec = + model_->GetIdDescriptorHuffmanCodec(inst_.opcode, operand_index_); + if (!codec) return SPV_UNSUPPORTED; uint64_t bits = 0; size_t num_bits = 0; @@ -1695,10 +1656,9 @@ spv_result_t MarkvEncoder::EncodeIdWithDescriptor(uint32_t id) { // kMarkvNoneOfTheAbove and go to fallback method. if (!codec->Encode(kMarkvNoneOfTheAbove, &bits, &num_bits)) return Diag(SPV_ERROR_INTERNAL) - << "Descriptor Huffman table for " - << spvOpcodeString(SpvOp(inst_.opcode)) - << " operand index " << operand_index_ - << " is missing kMarkvNoneOfTheAbove"; + << "Descriptor Huffman table for " + << spvOpcodeString(SpvOp(inst_.opcode)) << " operand index " + << operand_index_ << " is missing kMarkvNoneOfTheAbove"; writer_.WriteBits(bits, num_bits); return SPV_UNSUPPORTED; @@ -1711,18 +1671,16 @@ spv_result_t MarkvEncoder::EncodeIdWithDescriptor(uint32_t id) { } spv_result_t MarkvDecoder::DecodeIdWithDescriptor(uint32_t* id) { - auto* codec = model_->GetIdDescriptorHuffmanCodec(inst_.opcode, - operand_index_); - if (!codec) - return SPV_UNSUPPORTED; + auto* codec = + model_->GetIdDescriptorHuffmanCodec(inst_.opcode, operand_index_); + if (!codec) return SPV_UNSUPPORTED; uint64_t decoded_value = 0; if (!codec->DecodeFromStream(GetReadBitCallback(), &decoded_value)) return Diag(SPV_ERROR_INTERNAL) - << "Failed to decode descriptor with Huffman"; + << "Failed to decode descriptor with Huffman"; - if (decoded_value == kMarkvNoneOfTheAbove) - return SPV_UNSUPPORTED; + if (decoded_value == kMarkvNoneOfTheAbove) return SPV_UNSUPPORTED; // If descriptor exists then the id was encoded through descriptor mtf. const uint32_t descriptor = uint32_t(decoded_value); @@ -1743,8 +1701,7 @@ spv_result_t MarkvEncoder::EncodeExistingId(uint64_t mtf, uint32_t id) { uint32_t rank = 0; if (!multi_mtf_.RankFromValue(mtf, id, &rank)) - return Diag(SPV_ERROR_INTERNAL) - << "Id is not in the MTF sequence"; + return Diag(SPV_ERROR_INTERNAL) << "Id is not in the MTF sequence"; return EncodeMtfRankHuffman(rank, mtf, kMtfGenericNonZeroRank); } @@ -1760,14 +1717,12 @@ spv_result_t MarkvDecoder::DecodeExistingId(uint64_t mtf, uint32_t* id) { } else { const spv_result_t result = DecodeMtfRankHuffman(mtf, kMtfGenericNonZeroRank, &rank); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; } assert(rank); if (!multi_mtf_.ValueFromRank(mtf, rank, id)) - return Diag(SPV_ERROR_INTERNAL) - << "MTF rank is out of bounds"; + return Diag(SPV_ERROR_INTERNAL) << "MTF rank is out of bounds"; return SPV_SUCCESS; } @@ -1776,24 +1731,21 @@ spv_result_t MarkvEncoder::EncodeRefId(uint32_t id) { { // Try to encode using id descriptor mtfs. const spv_result_t result = EncodeIdWithDescriptor(id); - if (result != SPV_UNSUPPORTED) - return result; + if (result != SPV_UNSUPPORTED) return result; // If can't be done continue with other methods. } // Encode using rule-based mtf. uint64_t mtf = GetRuleBasedMtf(); - const bool can_forward_declare = - spvOperandCanBeForwardDeclaredFunction( - SpvOp(inst_.opcode))(operand_index_); + const bool can_forward_declare = spvOperandCanBeForwardDeclaredFunction( + SpvOp(inst_.opcode))(operand_index_); if (mtf != kMtfNone && !can_forward_declare) { assert(multi_mtf_.HasValue(kMtfAll, id)); return EncodeExistingId(mtf, id); } - if (mtf == kMtfNone) - mtf = kMtfAll; + if (mtf == kMtfNone) mtf = kMtfAll; uint32_t rank = 0; @@ -1801,8 +1753,7 @@ spv_result_t MarkvEncoder::EncodeRefId(uint32_t id) { // This is the first occurrence of a forward declared id. multi_mtf_.Insert(kMtfAll, id); multi_mtf_.Insert(kMtfForwardDeclared, id); - if (mtf != kMtfAll) - multi_mtf_.Insert(mtf, id); + if (mtf != kMtfAll) multi_mtf_.Insert(mtf, id); rank = 0; } @@ -1812,21 +1763,18 @@ spv_result_t MarkvEncoder::EncodeRefId(uint32_t id) { spv_result_t MarkvDecoder::DecodeRefId(uint32_t* id) { { const spv_result_t result = DecodeIdWithDescriptor(id); - if (result != SPV_UNSUPPORTED) - return result; + if (result != SPV_UNSUPPORTED) return result; } uint64_t mtf = GetRuleBasedMtf(); - const bool can_forward_declare = - spvOperandCanBeForwardDeclaredFunction( - SpvOp(inst_.opcode))(operand_index_); + const bool can_forward_declare = spvOperandCanBeForwardDeclaredFunction( + SpvOp(inst_.opcode))(operand_index_); if (mtf != kMtfNone && !can_forward_declare) { return DecodeExistingId(mtf, id); } - if (mtf == kMtfNone) - mtf = kMtfAll; + if (mtf == kMtfNone) mtf = kMtfAll; *id = 0; @@ -1834,8 +1782,7 @@ spv_result_t MarkvDecoder::DecodeRefId(uint32_t* id) { { const spv_result_t result = DecodeMtfRankHuffman(mtf, kMtfAll, &rank); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; } if (rank == 0) { @@ -1844,8 +1791,7 @@ spv_result_t MarkvDecoder::DecodeRefId(uint32_t* id) { SetIdBound(*id + 1); multi_mtf_.Insert(kMtfAll, *id); multi_mtf_.Insert(kMtfForwardDeclared, *id); - if (mtf != kMtfAll) - multi_mtf_.Insert(mtf, *id); + if (mtf != kMtfAll) multi_mtf_.Insert(mtf, *id); } else { if (!multi_mtf_.ValueFromRank(mtf, rank, id)) return Diag(SPV_ERROR_INTERNAL) << "MTF rank out of bounds"; @@ -1866,14 +1812,13 @@ spv_result_t MarkvEncoder::EncodeTypeId() { { // Try to encode using id descriptor mtfs. const spv_result_t result = EncodeIdWithDescriptor(inst_.type_id); - if (result != SPV_UNSUPPORTED) - return result; + if (result != SPV_UNSUPPORTED) return result; // If can't be done continue with other methods. } uint64_t mtf = GetRuleBasedMtf(); - assert(!spvOperandCanBeForwardDeclaredFunction( - SpvOp(inst_.opcode))(operand_index_)); + assert(!spvOperandCanBeForwardDeclaredFunction(SpvOp(inst_.opcode))( + operand_index_)); if (mtf == kMtfNone) { mtf = kMtfTypeNonFunction; @@ -1894,13 +1839,12 @@ spv_result_t MarkvDecoder::DecodeTypeId() { { const spv_result_t result = DecodeIdWithDescriptor(&inst_.type_id); - if (result != SPV_UNSUPPORTED) - return result; + if (result != SPV_UNSUPPORTED) return result; } uint64_t mtf = GetRuleBasedMtf(); - assert(!spvOperandCanBeForwardDeclaredFunction( - SpvOp(inst_.opcode))(operand_index_)); + assert(!spvOperandCanBeForwardDeclaredFunction(SpvOp(inst_.opcode))( + operand_index_)); if (mtf == kMtfNone) { mtf = kMtfTypeNonFunction; @@ -1920,16 +1864,14 @@ spv_result_t MarkvEncoder::EncodeResultId() { if (num_still_forward_declared) { // We write the rank only if kMtfForwardDeclared is not empty. If it is // empty the decoder knows that there are no forward declared ids to expect. - if (multi_mtf_.RankFromValue(kMtfForwardDeclared, - inst_.result_id, &rank)) { + if (multi_mtf_.RankFromValue(kMtfForwardDeclared, inst_.result_id, &rank)) { // This is a definition of a forward declared id. We can remove the id // from kMtfForwardDeclared. if (!multi_mtf_.Remove(kMtfForwardDeclared, inst_.result_id)) return Diag(SPV_ERROR_INTERNAL) - << "Failed to remove id from kMtfForwardDeclared"; + << "Failed to remove id from kMtfForwardDeclared"; writer_.WriteBits(1, 1); - writer_.WriteVariableWidthU32( - rank, model_->mtf_rank_chunk_length()); + writer_.WriteVariableWidthU32(rank, model_->mtf_rank_chunk_length()); } else { rank = 0; writer_.WriteBits(0, 1); @@ -1954,25 +1896,24 @@ spv_result_t MarkvDecoder::DecodeResultId() { uint64_t id_was_forward_declared; if (!reader_.ReadBits(&id_was_forward_declared, 1)) return Diag(SPV_ERROR_INVALID_BINARY) - << "Failed to read id_was_forward_declared flag"; + << "Failed to read id_was_forward_declared flag"; if (id_was_forward_declared) { - if (!reader_.ReadVariableWidthU32( - &rank, model_->mtf_rank_chunk_length())) + if (!reader_.ReadVariableWidthU32(&rank, model_->mtf_rank_chunk_length())) return Diag(SPV_ERROR_INVALID_BINARY) - << "Failed to read MTF rank of forward declared id"; + << "Failed to read MTF rank of forward declared id"; if (rank) { // The id was forward declared, recover it from kMtfForwardDeclared. - if (!multi_mtf_.ValueFromRank(kMtfForwardDeclared, - rank, &inst_.result_id)) + if (!multi_mtf_.ValueFromRank(kMtfForwardDeclared, rank, + &inst_.result_id)) return Diag(SPV_ERROR_INTERNAL) - << "Forward declared MTF rank is out of bounds"; + << "Forward declared MTF rank is out of bounds"; // We can now remove the id from kMtfForwardDeclared. if (!multi_mtf_.Remove(kMtfForwardDeclared, inst_.result_id)) return Diag(SPV_ERROR_INTERNAL) - << "Failed to remove id from kMtfForwardDeclared"; + << "Failed to remove id from kMtfForwardDeclared"; } } } @@ -1997,9 +1938,8 @@ spv_result_t MarkvEncoder::EncodeLiteralNumber( return EncodeNonIdWord(word); } else { assert(operand.number_bit_width <= 64); - const uint64_t word = - uint64_t(inst_.words[operand.offset]) | - (uint64_t(inst_.words[operand.offset + 1]) << 32); + const uint64_t word = uint64_t(inst_.words[operand.offset]) | + (uint64_t(inst_.words[operand.offset + 1]) << 32); if (operand.number_kind == SPV_NUMBER_UNSIGNED_INT) { writer_.WriteVariableWidthU64(word, model_->u64_chunk_length()); } else if (operand.number_kind == SPV_NUMBER_SIGNED_INT) { @@ -2021,27 +1961,23 @@ spv_result_t MarkvDecoder::DecodeLiteralNumber( if (operand.number_bit_width <= 32) { uint32_t word = 0; const spv_result_t result = DecodeNonIdWord(&word); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; inst_words_.push_back(word); } else { assert(operand.number_bit_width <= 64); uint64_t word = 0; if (operand.number_kind == SPV_NUMBER_UNSIGNED_INT) { if (!reader_.ReadVariableWidthU64(&word, model_->u64_chunk_length())) - return Diag(SPV_ERROR_INVALID_BINARY) - << "Failed to read literal U64"; + return Diag(SPV_ERROR_INVALID_BINARY) << "Failed to read literal U64"; } else if (operand.number_kind == SPV_NUMBER_SIGNED_INT) { int64_t val = 0; if (!reader_.ReadVariableWidthS64(&val, model_->s64_chunk_length(), model_->s64_block_exponent())) - return Diag(SPV_ERROR_INVALID_BINARY) - << "Failed to read literal S64"; + return Diag(SPV_ERROR_INVALID_BINARY) << "Failed to read literal S64"; std::memcpy(&word, &val, 8); } else if (operand.number_kind == SPV_NUMBER_FLOATING) { if (!reader_.ReadUnencoded(&word)) - return Diag(SPV_ERROR_INVALID_BINARY) - << "Failed to read literal F64"; + return Diag(SPV_ERROR_INVALID_BINARY) << "Failed to read literal F64"; } else { return Diag(SPV_ERROR_INTERNAL) << "Unsupported bit length"; } @@ -2073,14 +2009,11 @@ bool MarkvDecoder::ReadToByteBreak(size_t byte_break_if_less_than) { num_bits_to_next_byte > byte_break_if_less_than) return true; - uint64_t bits = 0; - if (!reader_.ReadBits(&bits, num_bits_to_next_byte)) - return false; + if (!reader_.ReadBits(&bits, num_bits_to_next_byte)) return false; assert(bits == 0); - if (bits != 0) - return false; + if (bits != 0) return false; return true; } @@ -2091,15 +2024,13 @@ spv_result_t MarkvEncoder::EncodeInstruction( inst_ = inst; const spv_result_t validation_result = UpdateValidationState(inst); - if (validation_result != SPV_SUCCESS) - return validation_result; + if (validation_result != SPV_SUCCESS) return validation_result; LogDisassemblyInstruction(); const spv_result_t opcode_encodig_result = EncodeOpcodeAndNumOperands(opcode, inst.num_operands); - if (opcode_encodig_result < 0) - return opcode_encodig_result; + if (opcode_encodig_result < 0) return opcode_encodig_result; if (opcode_encodig_result != SPV_SUCCESS) { // Fallback encoding for opcode and num_operands. @@ -2109,8 +2040,7 @@ spv_result_t MarkvEncoder::EncodeInstruction( // If the opcode has a variable number of operands, encode the number of // operands with the instruction. - if (logger_) - logger_->AppendWhitespaces(kCommentNumWhitespaces); + if (logger_) logger_->AppendWhitespaces(kCommentNumWhitespaces); writer_.WriteVariableWidthU16(inst.num_operands, model_->num_operands_chunk_length()); @@ -2139,16 +2069,13 @@ spv_result_t MarkvEncoder::EncodeInstruction( const uint32_t id = inst_.words[operand_.offset]; if (operand_.type == SPV_OPERAND_TYPE_TYPE_ID) { const spv_result_t result = EncodeTypeId(); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; } else if (operand_.type == SPV_OPERAND_TYPE_RESULT_ID) { const spv_result_t result = EncodeResultId(); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; } else { const spv_result_t result = EncodeRefId(id); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; } multi_mtf_.Promote(id); @@ -2158,21 +2085,19 @@ spv_result_t MarkvEncoder::EncodeInstruction( case SPV_OPERAND_TYPE_LITERAL_INTEGER: { const spv_result_t result = EncodeNonIdWord(inst_.words[operand_.offset]); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; break; } case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: { const spv_result_t result = EncodeLiteralNumber(operand_); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; break; } case SPV_OPERAND_TYPE_LITERAL_STRING: { - const char* src = reinterpret_cast<const char*>( - &inst_.words[operand_.offset]); + const char* src = + reinterpret_cast<const char*>(&inst_.words[operand_.offset]); auto* codec = model_->GetLiteralStringHuffmanCodec(opcode); if (codec) { @@ -2183,8 +2108,8 @@ spv_result_t MarkvEncoder::EncodeInstruction( writer_.WriteBits(bits, num_bits); break; } else { - bool result = codec->Encode("kMarkvNoneOfTheAbove", - &bits, &num_bits); + bool result = + codec->Encode("kMarkvNoneOfTheAbove", &bits, &num_bits); (void)result; assert(result); writer_.WriteBits(bits, num_bits); @@ -2194,9 +2119,8 @@ spv_result_t MarkvEncoder::EncodeInstruction( const size_t length = spv_strnlen_s(src, operand_.num_words * 4); if (length == operand_.num_words * 4) return Diag(SPV_ERROR_INVALID_BINARY) - << "Failed to find terminal character of literal string"; - for (size_t i = 0; i < length + 1; ++i) - writer_.WriteUnencoded(src[i]); + << "Failed to find terminal character of literal string"; + for (size_t i = 0; i < length + 1; ++i) writer_.WriteUnencoded(src[i]); break; } @@ -2204,8 +2128,7 @@ spv_result_t MarkvEncoder::EncodeInstruction( for (int i = 0; i < operand_.num_words; ++i) { const uint32_t word = inst_.words[operand_.offset + i]; const spv_result_t result = EncodeNonIdWord(word); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; } break; } @@ -2217,8 +2140,7 @@ spv_result_t MarkvEncoder::EncodeInstruction( if (logger_) { logger_->NewLine(); logger_->NewLine(); - if (!logger_->DebugInstruction(inst_)) - return SPV_REQUESTED_TERMINATION; + if (!logger_->DebugInstruction(inst_)) return SPV_REQUESTED_TERMINATION; } ProcessCurInstruction(); @@ -2236,62 +2158,57 @@ spv_result_t MarkvDecoder::DecodeModule(std::vector<uint32_t>* spirv_binary) { reader_.ReadUnencoded(&header_.spirv_generator); if (!header_read_success) - return Diag(SPV_ERROR_INVALID_BINARY) - << "Unable to read MARK-V header"; + return Diag(SPV_ERROR_INVALID_BINARY) << "Unable to read MARK-V header"; if (header_.markv_length_in_bits == 0) return Diag(SPV_ERROR_INVALID_BINARY) - << "Header markv_length_in_bits field is zero"; + << "Header markv_length_in_bits field is zero"; if (header_.magic_number != kMarkvMagicNumber) return Diag(SPV_ERROR_INVALID_BINARY) - << "MARK-V binary has incorrect magic number"; + << "MARK-V binary has incorrect magic number"; // TODO(atgoo@github.com): Print version strings. if (header_.markv_version != GetMarkvVersion()) return Diag(SPV_ERROR_INVALID_BINARY) - << "MARK-V binary and the codec have different versions"; + << "MARK-V binary and the codec have different versions"; const uint32_t model_type = header_.markv_model >> 16; const uint32_t model_version = header_.markv_model & 0xFFFF; if (model_type != model_->model_type()) return Diag(SPV_ERROR_INVALID_BINARY) - << "MARK-V binary and the codec use different MARK-V models"; + << "MARK-V binary and the codec use different MARK-V models"; if (model_version != model_->model_version()) return Diag(SPV_ERROR_INVALID_BINARY) - << "MARK-V binary and the codec use different versions if the same " - << "MARK-V model"; + << "MARK-V binary and the codec use different versions if the same " + << "MARK-V model"; - spirv_.reserve(header_.markv_length_in_bits / 2); // Heuristic. + spirv_.reserve(header_.markv_length_in_bits / 2); // Heuristic. spirv_.resize(5, 0); spirv_[0] = kSpirvMagicNumber; spirv_[1] = header_.spirv_version; spirv_[2] = header_.spirv_generator; if (logger_) { - reader_.SetCallback([this](const std::string& str){ - logger_->AppendBitSequence(str); - }); + reader_.SetCallback( + [this](const std::string& str) { logger_->AppendBitSequence(str); }); } while (reader_.GetNumReadBits() < header_.markv_length_in_bits) { inst_ = {}; const spv_result_t decode_result = DecodeInstruction(); - if (decode_result != SPV_SUCCESS) - return decode_result; + if (decode_result != SPV_SUCCESS) return decode_result; const spv_result_t validation_result = UpdateValidationState(inst_); - if (validation_result != SPV_SUCCESS) - return validation_result; + if (validation_result != SPV_SUCCESS) return validation_result; } - if (reader_.GetNumReadBits() != header_.markv_length_in_bits || !reader_.OnlyZeroesLeft()) { return Diag(SPV_ERROR_INVALID_BINARY) - << "MARK-V binary has wrong stated bit length " - << reader_.GetNumReadBits() << " " << header_.markv_length_in_bits; + << "MARK-V binary has wrong stated bit length " + << reader_.GetNumReadBits() << " " << header_.markv_length_in_bits; } // Decoding of the module is finished, validation state should have correct @@ -2308,8 +2225,7 @@ spv_result_t MarkvDecoder::DecodeModule(std::vector<uint32_t>* spirv_binary) { // For now it's better to keep the code independent for experimentation // purposes. spv_result_t MarkvDecoder::DecodeOperand( - size_t operand_offset, - const spv_operand_type_t type, + size_t operand_offset, const spv_operand_type_t type, spv_operand_pattern_t* expected_operands) { const SpvOp opcode = static_cast<SpvOp>(inst_.opcode); @@ -2328,8 +2244,7 @@ spv_result_t MarkvDecoder::DecodeOperand( switch (type) { case SPV_OPERAND_TYPE_RESULT_ID: { const spv_result_t result = DecodeResultId(); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; inst_words_.push_back(inst_.result_id); SetIdBound(std::max(GetIdBound(), inst_.result_id + 1)); @@ -2339,8 +2254,7 @@ spv_result_t MarkvDecoder::DecodeOperand( case SPV_OPERAND_TYPE_TYPE_ID: { const spv_result_t result = DecodeTypeId(); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; inst_words_.push_back(inst_.type_id); SetIdBound(std::max(GetIdBound(), inst_.type_id + 1)); @@ -2354,15 +2268,11 @@ spv_result_t MarkvDecoder::DecodeOperand( case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID: { uint32_t id = 0; const spv_result_t result = DecodeRefId(&id); - if (result != SPV_SUCCESS) - return result; - - if (id == 0) - return Diag(SPV_ERROR_INVALID_BINARY) << "Decoded id is 0"; + if (result != SPV_SUCCESS) return result; - if (type == SPV_OPERAND_TYPE_ID || - type == SPV_OPERAND_TYPE_OPTIONAL_ID) { + if (id == 0) return Diag(SPV_ERROR_INVALID_BINARY) << "Decoded id is 0"; + if (type == SPV_OPERAND_TYPE_ID || type == SPV_OPERAND_TYPE_OPTIONAL_ID) { operand_.type = SPV_OPERAND_TYPE_ID; if (opcode == SpvOpExtInst && operand_.offset == 3) { @@ -2372,8 +2282,8 @@ spv_result_t MarkvDecoder::DecodeOperand( auto ext_inst_type_iter = import_id_to_ext_inst_type_.find(id); if (ext_inst_type_iter == import_id_to_ext_inst_type_.end()) { return Diag(SPV_ERROR_INVALID_ID) - << "OpExtInst set id " << id - << " does not reference an OpExtInstImport result Id"; + << "OpExtInst set id " << id + << " does not reference an OpExtInstImport result Id"; } inst_.ext_inst_type = ext_inst_type_iter->second; } @@ -2388,8 +2298,7 @@ spv_result_t MarkvDecoder::DecodeOperand( case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: { uint32_t word = 0; const spv_result_t result = DecodeNonIdWord(&word); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; inst_words_.push_back(word); @@ -2398,7 +2307,7 @@ spv_result_t MarkvDecoder::DecodeOperand( spv_ext_inst_desc ext_inst; if (grammar_.lookupExtInst(inst_.ext_inst_type, word, &ext_inst)) return Diag(SPV_ERROR_INVALID_BINARY) - << "Invalid extended instruction number: " << word; + << "Invalid extended instruction number: " << word; spvPushOperandTypes(ext_inst->operandTypes, expected_operands); break; } @@ -2414,8 +2323,7 @@ spv_result_t MarkvDecoder::DecodeOperand( uint32_t word = 0; const spv_result_t result = DecodeNonIdWord(&word); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; inst_words_.push_back(word); break; @@ -2429,11 +2337,10 @@ spv_result_t MarkvDecoder::DecodeOperand( // referenced by the selector Id. const uint32_t selector_id = inst_words_.at(1); const auto type_id_iter = id_to_type_id_.find(selector_id); - if (type_id_iter == id_to_type_id_.end() || - type_id_iter->second == 0) { + if (type_id_iter == id_to_type_id_.end() || type_id_iter->second == 0) { return Diag(SPV_ERROR_INVALID_BINARY) - << "Invalid OpSwitch: selector id " << selector_id - << " has no type"; + << "Invalid OpSwitch: selector id " << selector_id + << " has no type"; } uint32_t type_id = type_id_iter->second; @@ -2441,16 +2348,16 @@ spv_result_t MarkvDecoder::DecodeOperand( // Recall that by convention, a result ID that is a type definition // maps to itself. return Diag(SPV_ERROR_INVALID_BINARY) - << "Invalid OpSwitch: selector id " << selector_id - << " is a type, not a value"; + << "Invalid OpSwitch: selector id " << selector_id + << " is a type, not a value"; } if (auto error = SetNumericTypeInfoForType(&operand_, type_id)) return error; if (operand_.number_kind != SPV_NUMBER_UNSIGNED_INT && operand_.number_kind != SPV_NUMBER_SIGNED_INT) { return Diag(SPV_ERROR_INVALID_BINARY) - << "Invalid OpSwitch: selector id " << selector_id - << " is not a scalar integer"; + << "Invalid OpSwitch: selector id " << selector_id + << " is not a scalar integer"; } } else { assert(opcode == SpvOpConstant || opcode == SpvOpSpecConstant); @@ -2461,8 +2368,7 @@ spv_result_t MarkvDecoder::DecodeOperand( return error; } - if (auto error = DecodeLiteralNumber(operand_)) - return error; + if (auto error = DecodeLiteralNumber(operand_)) return error; break; } @@ -2480,7 +2386,7 @@ spv_result_t MarkvDecoder::DecodeOperand( assert(huffman_result); if (!huffman_result) return Diag(SPV_ERROR_INVALID_BINARY) - << "Failed to read literal string"; + << "Failed to read literal string"; if (decoded_string != "kMarkvNoneOfTheAbove") { std::copy(decoded_string.begin(), decoded_string.end(), @@ -2496,17 +2402,15 @@ spv_result_t MarkvDecoder::DecodeOperand( char ch = 0; if (!reader_.ReadUnencoded(&ch)) return Diag(SPV_ERROR_INVALID_BINARY) - << "Failed to read literal string"; + << "Failed to read literal string"; str.push_back(ch); - if (ch == '\0') - break; + if (ch == '\0') break; } } - while (str.size() % 4 != 0) - str.push_back('\0'); + while (str.size() % 4 != 0) str.push_back('\0'); inst_words_.resize(inst_words_.size() + str.size() / 4); std::memcpy(&inst_words_[first_word_index], str.data(), str.size()); @@ -2519,13 +2423,15 @@ spv_result_t MarkvDecoder::DecodeOperand( spvExtInstImportTypeGet(str.data()); if (SPV_EXT_INST_TYPE_NONE == ext_inst_type) { return Diag(SPV_ERROR_INVALID_BINARY) - << "Invalid extended instruction import '" << str.data() << "'"; + << "Invalid extended instruction import '" << str.data() + << "'"; } // We must have parsed a valid result ID. It's a condition // of the grammar, and we only accept non-zero result Ids. assert(inst_.result_id); - const bool inserted = import_id_to_ext_inst_type_.emplace( - inst_.result_id, ext_inst_type).second; + const bool inserted = + import_id_to_ext_inst_type_.emplace(inst_.result_id, ext_inst_type) + .second; (void)inserted; assert(inserted); } @@ -2556,8 +2462,7 @@ spv_result_t MarkvDecoder::DecodeOperand( // A single word that is a plain enum value. uint32_t word = 0; const spv_result_t result = DecodeNonIdWord(&word); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; inst_words_.push_back(word); @@ -2568,9 +2473,8 @@ spv_result_t MarkvDecoder::DecodeOperand( spv_operand_desc entry; if (grammar_.lookupOperand(type, word, &entry)) { return Diag(SPV_ERROR_INVALID_BINARY) - << "Invalid " - << spvOperandTypeStr(operand_.type) - << " operand: " << word; + << "Invalid " << spvOperandTypeStr(operand_.type) + << " operand: " << word; } // Prepare to accept operands to this operand, if needed. @@ -2588,8 +2492,7 @@ spv_result_t MarkvDecoder::DecodeOperand( // This operand is a mask. uint32_t word = 0; const spv_result_t result = DecodeNonIdWord(&word); - if (result != SPV_SUCCESS) - return result; + if (result != SPV_SUCCESS) return result; inst_words_.push_back(word); @@ -2631,7 +2534,7 @@ spv_result_t MarkvDecoder::DecodeOperand( } default: return Diag(SPV_ERROR_INVALID_BINARY) - << "Internal error: Unhandled operand type: " << type; + << "Internal error: Unhandled operand type: " << type; } operand_.num_words = uint16_t(inst_words_.size() - first_word_index); @@ -2658,17 +2561,16 @@ spv_result_t MarkvDecoder::DecodeInstruction() { const spv_result_t opcode_decoding_result = DecodeOpcodeAndNumberOfOperands(&opcode, &num_operands); - if (opcode_decoding_result < 0) - return opcode_decoding_result; + if (opcode_decoding_result < 0) return opcode_decoding_result; if (opcode_decoding_result == SPV_SUCCESS) { inst_.num_operands = static_cast<uint16_t>(num_operands); num_operands_still_unknown = false; } else { - if (!reader_.ReadVariableWidthU32( - &opcode, model_->opcode_chunk_length())) { + if (!reader_.ReadVariableWidthU32(&opcode, + model_->opcode_chunk_length())) { return Diag(SPV_ERROR_INVALID_BINARY) - << "Failed to read opcode of instruction"; + << "Failed to read opcode of instruction"; } } @@ -2694,7 +2596,7 @@ spv_result_t MarkvDecoder::DecodeInstruction() { if (!reader_.ReadVariableWidthU16(&inst_.num_operands, model_->num_operands_chunk_length())) return Diag(SPV_ERROR_INVALID_BINARY) - << "Failed to read num_operands of instruction"; + << "Failed to read num_operands of instruction"; } else { inst_.num_operands = static_cast<uint16_t>(expected_operands.size()); } @@ -2709,14 +2611,12 @@ spv_result_t MarkvDecoder::DecodeInstruction() { const size_t operand_offset = inst_words_.size(); - const spv_result_t decode_result = DecodeOperand( - operand_offset, type, &expected_operands); + const spv_result_t decode_result = + DecodeOperand(operand_offset, type, &expected_operands); - if (decode_result != SPV_SUCCESS) - return decode_result; + if (decode_result != SPV_SUCCESS) return decode_result; } - assert(inst_.num_operands == parsed_operands_.size()); // Only valid while inst_words_ and parsed_operands_ remain unchanged (until @@ -2728,19 +2628,20 @@ spv_result_t MarkvDecoder::DecodeInstruction() { std::copy(inst_words_.begin(), inst_words_.end(), std::back_inserter(spirv_)); - assert(inst_.num_words == std::accumulate( - parsed_operands_.begin(), parsed_operands_.end(), 1, - [](int num_words, const spv_parsed_operand_t& operand) { - return num_words += operand.num_words; - }) && "num_words in instruction doesn't correspond to the sum of num_words" - "in the operands"); + assert(inst_.num_words == + std::accumulate( + parsed_operands_.begin(), parsed_operands_.end(), 1, + [](int num_words, const spv_parsed_operand_t& operand) { + return num_words += operand.num_words; + }) && + "num_words in instruction doesn't correspond to the sum of num_words" + "in the operands"); RecordNumberType(); ProcessCurInstruction(); if (!ReadToByteBreak(kByteBreakAfterInstIfLessThanUntilNextByte)) - return Diag(SPV_ERROR_INVALID_BINARY) - << "Failed to read to byte break"; + return Diag(SPV_ERROR_INVALID_BINARY) << "Failed to read to byte break"; if (logger_) { logger_->NewLine(); @@ -2751,8 +2652,7 @@ spv_result_t MarkvDecoder::DecodeInstruction() { logger_->AppendText(ss.str()); logger_->NewLine(); logger_->NewLine(); - if (!logger_->DebugInstruction(inst_)) - return SPV_REQUESTED_TERMINATION; + if (!logger_->DebugInstruction(inst_)) return SPV_REQUESTED_TERMINATION; } return SPV_SUCCESS; @@ -2764,14 +2664,14 @@ spv_result_t MarkvDecoder::SetNumericTypeInfoForType( auto type_info_iter = type_id_to_number_type_info_.find(type_id); if (type_info_iter == type_id_to_number_type_info_.end()) { return Diag(SPV_ERROR_INVALID_BINARY) - << "Type Id " << type_id << " is not a type"; + << "Type Id " << type_id << " is not a type"; } const NumberType& info = type_info_iter->second; if (info.type == SPV_NUMBER_NONE) { // This is a valid type, but for something other than a scalar number. return Diag(SPV_ERROR_INVALID_BINARY) - << "Type Id " << type_id << " is not a scalar numeric type"; + << "Type Id " << type_id << " is not a scalar numeric type"; } parsed_operand->number_kind = info.type; @@ -2787,8 +2687,9 @@ void MarkvDecoder::RecordNumberType() { NumberType info = {SPV_NUMBER_NONE, 0}; if (SpvOpTypeInt == opcode) { info.bit_width = inst_.words[inst_.operands[1].offset]; - info.type = inst_.words[inst_.operands[2].offset] ? - SPV_NUMBER_SIGNED_INT : SPV_NUMBER_UNSIGNED_INT; + info.type = inst_.words[inst_.operands[2].offset] + ? SPV_NUMBER_SIGNED_INT + : SPV_NUMBER_UNSIGNED_INT; } else if (SpvOpTypeFloat == opcode) { info.bit_width = inst_.words[inst_.operands[1].offset]; info.type = SPV_NUMBER_FLOATING; @@ -2798,31 +2699,27 @@ void MarkvDecoder::RecordNumberType() { } } -spv_result_t EncodeHeader( - void* user_data, spv_endianness_t endian, uint32_t magic, - uint32_t version, uint32_t generator, uint32_t id_bound, - uint32_t schema) { +spv_result_t EncodeHeader(void* user_data, spv_endianness_t endian, + uint32_t magic, uint32_t version, uint32_t generator, + uint32_t id_bound, uint32_t schema) { MarkvEncoder* encoder = reinterpret_cast<MarkvEncoder*>(user_data); - return encoder->EncodeHeader( - endian, magic, version, generator, id_bound, schema); + return encoder->EncodeHeader(endian, magic, version, generator, id_bound, + schema); } -spv_result_t EncodeInstruction( - void* user_data, const spv_parsed_instruction_t* inst) { +spv_result_t EncodeInstruction(void* user_data, + const spv_parsed_instruction_t* inst) { MarkvEncoder* encoder = reinterpret_cast<MarkvEncoder*>(user_data); return encoder->EncodeInstruction(*inst); } } // namespace -spv_result_t SpirvToMarkv(spv_const_context context, - const std::vector<uint32_t>& spirv, - const MarkvCodecOptions& options, - const MarkvModel& markv_model, - MessageConsumer message_consumer, - MarkvLogConsumer log_consumer, - MarkvDebugConsumer debug_consumer, - std::vector<uint8_t>* markv) { +spv_result_t SpirvToMarkv( + spv_const_context context, const std::vector<uint32_t>& spirv, + const MarkvCodecOptions& options, const MarkvModel& markv_model, + MessageConsumer message_consumer, MarkvLogConsumer log_consumer, + MarkvDebugConsumer debug_consumer, std::vector<uint8_t>* markv) { spv_context_t hijack_context = *context; SetContextMessageConsumer(&hijack_context, message_consumer); @@ -2832,15 +2729,15 @@ spv_result_t SpirvToMarkv(spv_const_context context, spv_position_t position = {}; if (spvBinaryEndianness(&spirv_binary, &endian)) { return DiagnosticStream(position, hijack_context.consumer, - SPV_ERROR_INVALID_BINARY) - << "Invalid SPIR-V magic number."; + SPV_ERROR_INVALID_BINARY) + << "Invalid SPIR-V magic number."; } spv_header_t header; if (spvBinaryHeaderGet(&spirv_binary, endian, &header)) { return DiagnosticStream(position, hijack_context.consumer, SPV_ERROR_INVALID_BINARY) - << "Invalid SPIR-V header."; + << "Invalid SPIR-V header."; } MarkvEncoder encoder(&hijack_context, options, &markv_model); @@ -2850,37 +2747,33 @@ spv_result_t SpirvToMarkv(spv_const_context context, spv_text text = nullptr; if (spvBinaryToText(&hijack_context, spirv.data(), spirv.size(), - SPV_BINARY_TO_TEXT_OPTION_NO_HEADER, &text, nullptr) - != SPV_SUCCESS) { + SPV_BINARY_TO_TEXT_OPTION_NO_HEADER, &text, + nullptr) != SPV_SUCCESS) { return DiagnosticStream(position, hijack_context.consumer, SPV_ERROR_INVALID_BINARY) - << "Failed to disassemble SPIR-V binary."; + << "Failed to disassemble SPIR-V binary."; } assert(text); encoder.SetDisassembly(std::string(text->str, text->length)); spvTextDestroy(text); } - if (spvBinaryParse( - &hijack_context, &encoder, spirv.data(), spirv.size(), EncodeHeader, - EncodeInstruction, nullptr) != SPV_SUCCESS) { + if (spvBinaryParse(&hijack_context, &encoder, spirv.data(), spirv.size(), + EncodeHeader, EncodeInstruction, nullptr) != SPV_SUCCESS) { return DiagnosticStream(position, hijack_context.consumer, SPV_ERROR_INVALID_BINARY) - << "Unable to encode to MARK-V."; + << "Unable to encode to MARK-V."; } *markv = encoder.GetMarkvBinary(); return SPV_SUCCESS; } -spv_result_t MarkvToSpirv(spv_const_context context, - const std::vector<uint8_t>& markv, - const MarkvCodecOptions& options, - const MarkvModel& markv_model, - MessageConsumer message_consumer, - MarkvLogConsumer log_consumer, - MarkvDebugConsumer debug_consumer, - std::vector<uint32_t>* spirv) { +spv_result_t MarkvToSpirv( + spv_const_context context, const std::vector<uint8_t>& markv, + const MarkvCodecOptions& options, const MarkvModel& markv_model, + MessageConsumer message_consumer, MarkvLogConsumer log_consumer, + MarkvDebugConsumer debug_consumer, std::vector<uint32_t>* spirv) { spv_position_t position = {}; spv_context_t hijack_context = *context; SetContextMessageConsumer(&hijack_context, message_consumer); @@ -2893,7 +2786,7 @@ spv_result_t MarkvToSpirv(spv_const_context context, if (decoder.DecodeModule(spirv) != SPV_SUCCESS) { return DiagnosticStream(position, hijack_context.consumer, SPV_ERROR_INVALID_BINARY) - << "Unable to decode MARK-V."; + << "Unable to decode MARK-V."; } assert(!spirv->empty()); diff --git a/source/comp/markv_model.h b/source/comp/markv_model.h index f656df45..cfdf95c9 100644 --- a/source/comp/markv_model.h +++ b/source/comp/markv_model.h @@ -19,8 +19,8 @@ #include <unordered_set> #include <vector> -#include "spirv/1.2/spirv.h" #include "spirv-tools/libspirv.h" +#include "spirv/1.2/spirv.h" #include "util/huffman_codec.h" namespace spvtools { @@ -30,14 +30,17 @@ namespace spvtools { // codecs used by the compression algorithm. class MarkvModel { public: - MarkvModel() : operand_chunk_lengths_( - static_cast<size_t>(SPV_OPERAND_TYPE_NUM_OPERAND_TYPES), 0) {} + MarkvModel() + : operand_chunk_lengths_( + static_cast<size_t>(SPV_OPERAND_TYPE_NUM_OPERAND_TYPES), 0) {} uint32_t model_type() const { return model_type_; } uint32_t model_version() const { return model_version_; } uint32_t opcode_chunk_length() const { return opcode_chunk_length_; } - uint32_t num_operands_chunk_length() const { return num_operands_chunk_length_; } + uint32_t num_operands_chunk_length() const { + return num_operands_chunk_length_; + } uint32_t mtf_rank_chunk_length() const { return mtf_rank_chunk_length_; } uint32_t u64_chunk_length() const { return u64_chunk_length_; } @@ -46,8 +49,8 @@ class MarkvModel { // Returns a codec for common opcode_and_num_operands words for the given // previous opcode. May return nullptr if the codec doesn't exist. - const spvutils::HuffmanCodec<uint64_t>* GetOpcodeAndNumOperandsMarkovHuffmanCodec( - uint32_t prev_opcode) const { + const spvutils::HuffmanCodec<uint64_t>* + GetOpcodeAndNumOperandsMarkovHuffmanCodec(uint32_t prev_opcode) const { if (prev_opcode == SpvOpNop) return opcode_and_num_operands_huffman_codec_.get(); @@ -65,8 +68,7 @@ class MarkvModel { uint32_t opcode, uint32_t operand_index) const { const auto it = non_id_word_huffman_codecs_.find( std::pair<uint32_t, uint32_t>(opcode, operand_index)); - if (it == non_id_word_huffman_codecs_.end()) - return nullptr; + if (it == non_id_word_huffman_codecs_.end()) return nullptr; return it->second.get(); } @@ -77,8 +79,7 @@ class MarkvModel { uint32_t opcode, uint32_t operand_index) const { const auto it = id_descriptor_huffman_codecs_.find( std::pair<uint32_t, uint32_t>(opcode, operand_index)); - if (it == id_descriptor_huffman_codecs_.end()) - return nullptr; + if (it == id_descriptor_huffman_codecs_.end()) return nullptr; return it->second.get(); } @@ -88,8 +89,7 @@ class MarkvModel { const spvutils::HuffmanCodec<std::string>* GetLiteralStringHuffmanCodec( uint32_t opcode) const { const auto it = literal_string_huffman_codecs_.find(opcode); - if (it == literal_string_huffman_codecs_.end()) - return nullptr; + if (it == literal_string_huffman_codecs_.end()) return nullptr; return it->second.get(); } @@ -106,9 +106,7 @@ class MarkvModel { } // Sets model type. - void SetModelType(uint32_t in_model_type) { - model_type_ = in_model_type; - } + void SetModelType(uint32_t in_model_type) { model_type_ = in_model_type; } // Sets model version. void SetModelVersion(uint32_t in_model_version) { @@ -137,12 +135,14 @@ class MarkvModel { // Huffman codecs for non-id single-word operand values. // The map key is pair <opcode, operand_index>. std::map<std::pair<uint32_t, uint32_t>, - std::unique_ptr<spvutils::HuffmanCodec<uint64_t>>> non_id_word_huffman_codecs_; + std::unique_ptr<spvutils::HuffmanCodec<uint64_t>>> + non_id_word_huffman_codecs_; // Huffman codecs for id descriptors. The map key is pair // <opcode, operand_index>. std::map<std::pair<uint32_t, uint32_t>, - std::unique_ptr<spvutils::HuffmanCodec<uint64_t>>> id_descriptor_huffman_codecs_; + std::unique_ptr<spvutils::HuffmanCodec<uint64_t>>> + id_descriptor_huffman_codecs_; // Set of all descriptors which have a coding scheme in any of // id_descriptor_huffman_codecs_. @@ -160,7 +160,7 @@ class MarkvModel { std::vector<uint32_t> operand_chunk_lengths_; uint32_t opcode_chunk_length_ = 7; - uint32_t num_operands_chunk_length_ = 3; + uint32_t num_operands_chunk_length_ = 3; uint32_t mtf_rank_chunk_length_ = 5; uint32_t u64_chunk_length_ = 8; diff --git a/source/extensions.cpp b/source/extensions.cpp index 260a15b6..065543c1 100644 --- a/source/extensions.cpp +++ b/source/extensions.cpp @@ -23,8 +23,7 @@ namespace libspirv { std::string GetExtensionString(const spv_parsed_instruction_t* inst) { - if (inst->opcode != SpvOpExtension) - return "ERROR_not_op_extension"; + if (inst->opcode != SpvOpExtension) return "ERROR_not_op_extension"; assert(inst->num_operands == 1); @@ -37,9 +36,8 @@ std::string GetExtensionString(const spv_parsed_instruction_t* inst) { std::string ExtensionSetToString(const ExtensionSet& extensions) { std::stringstream ss; - extensions.ForEach([&ss](Extension ext) { - ss << ExtensionToString(ext) << " "; - }); + extensions.ForEach( + [&ss](Extension ext) { ss << ExtensionToString(ext) << " "; }); return ss.str(); } diff --git a/source/id_descriptor.cpp b/source/id_descriptor.cpp index d2c6220b..2384c634 100644 --- a/source/id_descriptor.cpp +++ b/source/id_descriptor.cpp @@ -40,15 +40,14 @@ uint32_t HashU32Array(const std::vector<uint32_t>& words) { uint32_t IdDescriptorCollection::ProcessInstruction( const spv_parsed_instruction_t& inst) { - if (!inst.result_id) - return 0; + 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]; + 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); diff --git a/source/id_descriptor.h b/source/id_descriptor.h index b4947a78..d177eb98 100644 --- a/source/id_descriptor.h +++ b/source/id_descriptor.h @@ -28,9 +28,7 @@ namespace libspirv { // were substituted with previously computed descriptors. class IdDescriptorCollection { public: - IdDescriptorCollection() { - words_.reserve(16); - } + 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. @@ -41,8 +39,7 @@ class IdDescriptorCollection { // 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; + if (it == id_to_descriptor_.end()) return 0; return it->second; } @@ -56,4 +53,3 @@ class IdDescriptorCollection { } // namespace libspirv #endif // LIBSPIRV_ID_DESCRIPTOR_H_ - diff --git a/source/link/linker.cpp b/source/link/linker.cpp index 79d48727..35cba981 100644 --- a/source/link/linker.cpp +++ b/source/link/linker.cpp @@ -497,7 +497,7 @@ static spv_result_t GetImportExportPairs( // Ignore if the targeted symbol is a built-in bool is_built_in = false; for (const auto& id_decoration : - decoration_manager.GetDecorationsFor(id, false)) { + decoration_manager.GetDecorationsFor(id, false)) { if (id_decoration->GetSingleWordInOperand(1u) == SpvDecorationBuiltIn) { is_built_in = true; break; diff --git a/source/name_mapper.cpp b/source/name_mapper.cpp index 1accc943..a169621f 100644 --- a/source/name_mapper.cpp +++ b/source/name_mapper.cpp @@ -14,8 +14,8 @@ #include "name_mapper.h" -#include <cassert> #include <algorithm> +#include <cassert> #include <iterator> #include <sstream> #include <string> @@ -234,26 +234,30 @@ spv_result_t FriendlyNameMapper::ParseInstruction( } } break; case SpvOpTypeVector: - SaveName(result_id, std::string("v") + to_string(inst.words[3]) + - NameForId(inst.words[2])); + SaveName(result_id, + std::string("v") + to_string(inst.words[3]) + + NameForId(inst.words[2])); break; case SpvOpTypeMatrix: - SaveName(result_id, std::string("mat") + to_string(inst.words[3]) + - NameForId(inst.words[2])); + SaveName(result_id, + std::string("mat") + to_string(inst.words[3]) + + NameForId(inst.words[2])); break; case SpvOpTypeArray: - SaveName(result_id, std::string("_arr_") + NameForId(inst.words[2]) + - "_" + NameForId(inst.words[3])); + SaveName(result_id, + std::string("_arr_") + NameForId(inst.words[2]) + "_" + + NameForId(inst.words[3])); break; case SpvOpTypeRuntimeArray: SaveName(result_id, std::string("_runtimearr_") + NameForId(inst.words[2])); break; case SpvOpTypePointer: - SaveName(result_id, std::string("_ptr_") + - NameForEnumOperand(SPV_OPERAND_TYPE_STORAGE_CLASS, - inst.words[2]) + - "_" + NameForId(inst.words[3])); + SaveName(result_id, + std::string("_ptr_") + + NameForEnumOperand(SPV_OPERAND_TYPE_STORAGE_CLASS, + inst.words[2]) + + "_" + NameForId(inst.words[3])); break; case SpvOpTypePipe: SaveName(result_id, diff --git a/source/name_mapper.h b/source/name_mapper.h index 12078b66..8afac424 100644 --- a/source/name_mapper.h +++ b/source/name_mapper.h @@ -20,8 +20,8 @@ #include <unordered_map> #include <unordered_set> -#include "spirv-tools/libspirv.h" #include "assembly_grammar.h" +#include "spirv-tools/libspirv.h" namespace libspirv { @@ -41,7 +41,8 @@ NameMapper GetTrivialNameMapper(); // - If an Id has a debug name (via OpName), then that will be used when // possible. // - Well known scalar types map to friendly names. For example, -// OpTypeVoid should be %void. Scalar types map to their names in OpenCL when +// OpTypeVoid should be %void. Scalar types map to their names in OpenCL +// when // there is a correspondence, and otherwise as follows: // - unsigned integer type of n bits map to "u" followed by n // - signed integer type of n bits map to "i" followed by n diff --git a/source/opcode.cpp b/source/opcode.cpp index 62ea1d17..1d229e08 100644 --- a/source/opcode.cpp +++ b/source/opcode.cpp @@ -147,7 +147,7 @@ spv_result_t spvOpcodeTableValueLookup(const spv_opcode_table table, return lhs.opcode < rhs.opcode; }; auto it = std::lower_bound(beg, end, value, comp); - if (it!=end && it->opcode == opcode) { + if (it != end && it->opcode == opcode) { *pEntry = it; return SPV_SUCCESS; } @@ -177,13 +177,14 @@ const char* spvOpcodeString(const SpvOp opcode) { // previous ones. const auto beg = kOpcodeTableEntries_1_2; - const auto end = kOpcodeTableEntries_1_2 + ARRAY_SIZE(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) { + if (it != end && it->opcode == opcode) { return it->name; } diff --git a/source/opt/aggressive_dead_code_elim_pass.cpp b/source/opt/aggressive_dead_code_elim_pass.cpp index 54e930aa..fb11f13a 100644 --- a/source/opt/aggressive_dead_code_elim_pass.cpp +++ b/source/opt/aggressive_dead_code_elim_pass.cpp @@ -36,29 +36,25 @@ const uint32_t kLoopMergeMergeBlockIdInIdx = 0; } // namespace anonymous -bool AggressiveDCEPass::IsVarOfStorage(uint32_t varId, - uint32_t storageClass) { +bool AggressiveDCEPass::IsVarOfStorage(uint32_t varId, uint32_t storageClass) { const ir::Instruction* varInst = get_def_use_mgr()->GetDef(varId); const SpvOp op = varInst->opcode(); - if (op != SpvOpVariable) - return false; + if (op != SpvOpVariable) return false; const uint32_t varTypeId = varInst->type_id(); const ir::Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId); - if (varTypeInst->opcode() != SpvOpTypePointer) - return false; + if (varTypeInst->opcode() != SpvOpTypePointer) return false; return varTypeInst->GetSingleWordInOperand(kTypePointerStorageClassInIdx) == - storageClass; + storageClass; } bool AggressiveDCEPass::IsLocalVar(uint32_t varId) { - return IsVarOfStorage(varId, SpvStorageClassFunction) || - (IsVarOfStorage(varId, SpvStorageClassPrivate) && private_like_local_); + return IsVarOfStorage(varId, SpvStorageClassFunction) || + (IsVarOfStorage(varId, SpvStorageClassPrivate) && private_like_local_); } void AggressiveDCEPass::AddStores(uint32_t ptrId) { const analysis::UseList* uses = get_def_use_mgr()->GetUses(ptrId); - if (uses == nullptr) - return; + if (uses == nullptr) return; for (const auto u : *uses) { const SpvOp op = u.inst->opcode(); switch (op) { @@ -72,8 +68,7 @@ void AggressiveDCEPass::AddStores(uint32_t ptrId) { // If default, assume it stores eg frexp, modf, function call case SpvOpStore: default: { - if (!IsLive(u.inst)) - AddToWorklist(u.inst); + if (!IsLive(u.inst)) AddToWorklist(u.inst); } break; } } @@ -88,17 +83,16 @@ bool AggressiveDCEPass::IsCombinatorExt(ir::Instruction* inst) const { if (inst->GetSingleWordInOperand(kExtInstSetIdInIndx) == glsl_std_450_id_) { uint32_t op = inst->GetSingleWordInOperand(kExtInstInstructionInIndx); return combinator_ops_glsl_std_450_.find(op) != - combinator_ops_glsl_std_450_.end(); - } - else + combinator_ops_glsl_std_450_.end(); + } else return false; } bool AggressiveDCEPass::AllExtensionsSupported() const { // If any extension not in whitelist, return false for (auto& ei : get_module()->extensions()) { - const char* extName = reinterpret_cast<const char*>( - &ei.GetInOperand(0).words[0]); + const char* extName = + reinterpret_cast<const char*>(&ei.GetInOperand(0).words[0]); if (extensions_whitelist_.find(extName) == extensions_whitelist_.end()) return false; } @@ -117,11 +111,9 @@ bool AggressiveDCEPass::KillInstIfTargetDead(ir::Instruction* inst) { void AggressiveDCEPass::ProcessLoad(uint32_t varId) { // Only process locals - if (!IsLocalVar(varId)) - return; + if (!IsLocalVar(varId)) return; // Return if already processed - if (live_local_vars_.find(varId) != live_local_vars_.end()) - return; + if (live_local_vars_.find(varId) != live_local_vars_.end()) return; // Mark all stores to varId as live AddStores(varId); // Cache varId as processed @@ -129,20 +121,17 @@ void AggressiveDCEPass::ProcessLoad(uint32_t varId) { } bool AggressiveDCEPass::IsStructuredIfHeader(ir::BasicBlock* bp, - ir::Instruction** mergeInst, ir::Instruction** branchInst, - uint32_t* mergeBlockId) { + ir::Instruction** mergeInst, + ir::Instruction** branchInst, + uint32_t* mergeBlockId) { auto ii = bp->end(); --ii; - if (ii->opcode() != SpvOpBranchConditional) - return false; - if (ii == bp->begin()) - return false; + if (ii->opcode() != SpvOpBranchConditional) return false; + if (ii == bp->begin()) return false; if (branchInst != nullptr) *branchInst = &*ii; --ii; - if (ii->opcode() != SpvOpSelectionMerge) - return false; - if (mergeInst != nullptr) - *mergeInst = &*ii; + if (ii->opcode() != SpvOpSelectionMerge) return false; + if (mergeInst != nullptr) *mergeInst = &*ii; if (mergeBlockId != nullptr) *mergeBlockId = ii->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx); @@ -150,7 +139,7 @@ bool AggressiveDCEPass::IsStructuredIfHeader(ir::BasicBlock* bp, } void AggressiveDCEPass::ComputeBlock2HeaderMaps( - std::list<ir::BasicBlock*>& structuredOrder) { + std::list<ir::BasicBlock*>& structuredOrder) { block2headerMerge_.clear(); block2headerBranch_.clear(); std::stack<ir::Instruction*> currentMergeInst; @@ -180,16 +169,15 @@ void AggressiveDCEPass::ComputeBlock2HeaderMaps( void AggressiveDCEPass::ComputeInst2BlockMap(ir::Function* func) { for (auto& blk : *func) { - blk.ForEachInst([&blk,this](ir::Instruction* ip) { - inst2block_[ip] = &blk; - }); + blk.ForEachInst( + [&blk, this](ir::Instruction* ip) { inst2block_[ip] = &blk; }); } } void AggressiveDCEPass::AddBranch(uint32_t labelId, ir::BasicBlock* bp) { - std::unique_ptr<ir::Instruction> newBranch( - new ir::Instruction(SpvOpBranch, 0, 0, - {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}})); + std::unique_ptr<ir::Instruction> newBranch(new ir::Instruction( + SpvOpBranch, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}})); get_def_use_mgr()->AnalyzeInstDefUse(&*newBranch); bp->AddInstruction(std::move(newBranch)); } @@ -209,7 +197,7 @@ bool AggressiveDCEPass::AggressiveDCE(ir::Function* func) { func_is_entry_point_ = false; private_stores_.clear(); // Stacks to keep track of when we are inside an if-construct. When not - // immediately inside an in-construct, we must assume all branches are live. + // immediately inside an in-construct, we must assume all branches are live. std::stack<bool> assume_branches_live; std::stack<uint32_t> currentMergeBlockId; // Push sentinel values on stack for when outside of any control flow. @@ -225,7 +213,7 @@ bool AggressiveDCEPass::AggressiveDCE(ir::Function* func) { switch (op) { case SpvOpStore: { uint32_t varId; - (void) GetPtr(&*ii, &varId); + (void)GetPtr(&*ii, &varId); // Mark stores as live if their variable is not function scope // and is not private scope. Remember private stores for possible // later inclusion @@ -236,8 +224,7 @@ bool AggressiveDCEPass::AggressiveDCE(ir::Function* func) { } break; case SpvOpExtInst: { // eg. GLSL frexp, modf - if (!IsCombinatorExt(&*ii)) - AddToWorklist(&*ii); + if (!IsCombinatorExt(&*ii)) AddToWorklist(&*ii); } break; case SpvOpLoopMerge: { // Assume loops live (for now) @@ -254,22 +241,18 @@ bool AggressiveDCEPass::AggressiveDCE(ir::Function* func) { assume_branches_live.push(!is_structured_if); currentMergeBlockId.push( ii->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx)); - if (!is_structured_if) - AddToWorklist(&*ii); + if (!is_structured_if) AddToWorklist(&*ii); } break; case SpvOpBranch: case SpvOpBranchConditional: { - if (assume_branches_live.top()) - AddToWorklist(&*ii); + if (assume_branches_live.top()) AddToWorklist(&*ii); } break; default: { // Function calls, atomics, function params, function returns, etc. // TODO(greg-lunarg): function calls live only if write to non-local - if (!IsCombinator(op)) - AddToWorklist(&*ii); + if (!IsCombinator(op)) AddToWorklist(&*ii); // Remember function calls - if (op == SpvOpFunctionCall) - call_in_func_ = true; + if (op == SpvOpFunctionCall) call_in_func_ = true; } break; } } @@ -287,23 +270,20 @@ bool AggressiveDCEPass::AggressiveDCE(ir::Function* func) { private_like_local_ = func_is_entry_point_ && !call_in_func_; // If privates are not like local, add their stores to worklist if (!private_like_local_) - for (auto& ps : private_stores_) - AddToWorklist(ps); + for (auto& ps : private_stores_) AddToWorklist(ps); // Add OpGroupDecorates to worklist because they are a pain to remove // ids from. // TODO(greg-lunarg): Handle dead ids in OpGroupDecorate for (auto& ai : get_module()->annotations()) { - if (ai.opcode() == SpvOpGroupDecorate) - AddToWorklist(&ai); + if (ai.opcode() == SpvOpGroupDecorate) AddToWorklist(&ai); } - // Perform closure on live instruction set. + // Perform closure on live instruction set. while (!worklist_.empty()) { ir::Instruction* liveInst = worklist_.front(); // Add all operand instructions if not already live liveInst->ForEachInId([this](const uint32_t* iid) { ir::Instruction* inInst = get_def_use_mgr()->GetDef(*iid); - if (!IsLive(inInst)) - AddToWorklist(inInst); + if (!IsLive(inInst)) AddToWorklist(inInst); }); // If in a structured if construct, add the controlling conditional branch // and its merge. Any containing if construct is marked live when the @@ -317,7 +297,7 @@ bool AggressiveDCEPass::AggressiveDCE(ir::Function* func) { // If local load, add all variable's stores if variable not already live if (liveInst->opcode() == SpvOpLoad) { uint32_t varId; - (void) GetPtr(liveInst, &varId); + (void)GetPtr(liveInst, &varId); ProcessLoad(varId); } // If function call, treat as if it loads from all pointer arguments @@ -326,7 +306,7 @@ bool AggressiveDCEPass::AggressiveDCE(ir::Function* func) { // Skip non-ptr args if (!IsPtr(*iid)) return; uint32_t varId; - (void) GetPtr(*iid, &varId); + (void)GetPtr(*iid, &varId); ProcessLoad(varId); }); } @@ -340,8 +320,7 @@ bool AggressiveDCEPass::AggressiveDCE(ir::Function* func) { // at the end of an if-header, which indicate a dead if. for (auto bi = structuredOrder.begin(); bi != structuredOrder.end(); ++bi) { for (auto ii = (*bi)->begin(); ii != (*bi)->end(); ++ii) { - if (IsLive(&*ii)) - continue; + if (IsLive(&*ii)) continue; if (IsBranch(ii->opcode()) && !IsStructuredIfHeader(*bi, nullptr, nullptr, nullptr)) continue; @@ -352,27 +331,23 @@ bool AggressiveDCEPass::AggressiveDCE(ir::Function* func) { // This must be done before killing the instructions, otherwise there are // dead objects in the def/use database. for (auto& di : get_module()->debugs2()) { - if (di.opcode() != SpvOpName) - continue; - if (KillInstIfTargetDead(&di)) - modified = true; + if (di.opcode() != SpvOpName) continue; + if (KillInstIfTargetDead(&di)) modified = true; } for (auto& ai : get_module()->annotations()) { if (ai.opcode() != SpvOpDecorate && ai.opcode() != SpvOpDecorateId) continue; - if (KillInstIfTargetDead(&ai)) - modified = true; + if (KillInstIfTargetDead(&ai)) modified = true; } // Kill dead instructions and remember dead blocks for (auto bi = structuredOrder.begin(); bi != structuredOrder.end();) { uint32_t mergeBlockId = 0; for (auto ii = (*bi)->begin(); ii != (*bi)->end(); ++ii) { - if (dead_insts_.find(&*ii) == dead_insts_.end()) - continue; + if (dead_insts_.find(&*ii) == dead_insts_.end()) continue; // If dead instruction is selection merge, remember merge block // for new branch at end of block if (ii->opcode() == SpvOpSelectionMerge) - mergeBlockId = + mergeBlockId = ii->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx); context()->KillInst(&*ii); modified = true; @@ -384,8 +359,7 @@ bool AggressiveDCEPass::AggressiveDCE(ir::Function* func) { AddBranch(mergeBlockId, *bi); for (++bi; (*bi)->id() != mergeBlockId; ++bi) { } - } - else { + } else { ++bi; } } @@ -412,7 +386,7 @@ void AggressiveDCEPass::Initialize(ir::IRContext* c) { } Pass::Status AggressiveDCEPass::ProcessImpl() { - // Current functionality assumes shader capability + // Current functionality assumes shader capability // TODO(greg-lunarg): Handle additional capabilities if (!get_module()->HasCapability(SpvCapabilityShader)) return Status::SuccessWithoutChange; @@ -421,15 +395,12 @@ Pass::Status AggressiveDCEPass::ProcessImpl() { if (get_module()->HasCapability(SpvCapabilityAddresses)) return Status::SuccessWithoutChange; // If any extensions in the module are not explicitly supported, - // return unmodified. - if (!AllExtensionsSupported()) - return Status::SuccessWithoutChange; + // return unmodified. + if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; // Initialize combinator whitelists InitCombinatorSets(); // Process all entry point functions - ProcessFunction pfn = [this](ir::Function* fp) { - return AggressiveDCE(fp); - }; + ProcessFunction pfn = [this](ir::Function* fp) { return AggressiveDCE(fp); }; bool modified = ProcessEntryPointCallTree(pfn, get_module()); return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; } @@ -443,258 +414,246 @@ Pass::Status AggressiveDCEPass::Process(ir::IRContext* c) { void AggressiveDCEPass::InitCombinatorSets() { combinator_ops_shader_ = { - SpvOpNop, - SpvOpUndef, - SpvOpVariable, - SpvOpImageTexelPointer, - SpvOpLoad, - SpvOpAccessChain, - SpvOpInBoundsAccessChain, - SpvOpArrayLength, - SpvOpVectorExtractDynamic, - SpvOpVectorInsertDynamic, - SpvOpVectorShuffle, - SpvOpCompositeConstruct, - SpvOpCompositeExtract, - SpvOpCompositeInsert, - SpvOpCopyObject, - SpvOpTranspose, - SpvOpSampledImage, - SpvOpImageSampleImplicitLod, - SpvOpImageSampleExplicitLod, - SpvOpImageSampleDrefImplicitLod, - SpvOpImageSampleDrefExplicitLod, - SpvOpImageSampleProjImplicitLod, - SpvOpImageSampleProjExplicitLod, - SpvOpImageSampleProjDrefImplicitLod, - SpvOpImageSampleProjDrefExplicitLod, - SpvOpImageFetch, - SpvOpImageGather, - SpvOpImageDrefGather, - SpvOpImageRead, - SpvOpImage, - SpvOpConvertFToU, - SpvOpConvertFToS, - SpvOpConvertSToF, - SpvOpConvertUToF, - SpvOpUConvert, - SpvOpSConvert, - SpvOpFConvert, - SpvOpQuantizeToF16, - SpvOpBitcast, - SpvOpSNegate, - SpvOpFNegate, - SpvOpIAdd, - SpvOpFAdd, - SpvOpISub, - SpvOpFSub, - SpvOpIMul, - SpvOpFMul, - SpvOpUDiv, - SpvOpSDiv, - SpvOpFDiv, - SpvOpUMod, - SpvOpSRem, - SpvOpSMod, - SpvOpFRem, - SpvOpFMod, - SpvOpVectorTimesScalar, - SpvOpMatrixTimesScalar, - SpvOpVectorTimesMatrix, - SpvOpMatrixTimesVector, - SpvOpMatrixTimesMatrix, - SpvOpOuterProduct, - SpvOpDot, - SpvOpIAddCarry, - SpvOpISubBorrow, - SpvOpUMulExtended, - SpvOpSMulExtended, - SpvOpAny, - SpvOpAll, - SpvOpIsNan, - SpvOpIsInf, - SpvOpLogicalEqual, - SpvOpLogicalNotEqual, - SpvOpLogicalOr, - SpvOpLogicalAnd, - SpvOpLogicalNot, - SpvOpSelect, - SpvOpIEqual, - SpvOpINotEqual, - SpvOpUGreaterThan, - SpvOpSGreaterThan, - SpvOpUGreaterThanEqual, - SpvOpSGreaterThanEqual, - SpvOpULessThan, - SpvOpSLessThan, - SpvOpULessThanEqual, - SpvOpSLessThanEqual, - SpvOpFOrdEqual, - SpvOpFUnordEqual, - SpvOpFOrdNotEqual, - SpvOpFUnordNotEqual, - SpvOpFOrdLessThan, - SpvOpFUnordLessThan, - SpvOpFOrdGreaterThan, - SpvOpFUnordGreaterThan, - SpvOpFOrdLessThanEqual, - SpvOpFUnordLessThanEqual, - SpvOpFOrdGreaterThanEqual, - SpvOpFUnordGreaterThanEqual, - SpvOpShiftRightLogical, - SpvOpShiftRightArithmetic, - SpvOpShiftLeftLogical, - SpvOpBitwiseOr, - SpvOpBitwiseXor, - SpvOpBitwiseAnd, - SpvOpNot, - SpvOpBitFieldInsert, - SpvOpBitFieldSExtract, - SpvOpBitFieldUExtract, - SpvOpBitReverse, - SpvOpBitCount, - SpvOpDPdx, - SpvOpDPdy, - SpvOpFwidth, - SpvOpDPdxFine, - SpvOpDPdyFine, - SpvOpFwidthFine, - SpvOpDPdxCoarse, - SpvOpDPdyCoarse, - SpvOpFwidthCoarse, - SpvOpPhi, - SpvOpImageSparseSampleImplicitLod, - SpvOpImageSparseSampleExplicitLod, - SpvOpImageSparseSampleDrefImplicitLod, - SpvOpImageSparseSampleDrefExplicitLod, - SpvOpImageSparseSampleProjImplicitLod, - SpvOpImageSparseSampleProjExplicitLod, - SpvOpImageSparseSampleProjDrefImplicitLod, - SpvOpImageSparseSampleProjDrefExplicitLod, - SpvOpImageSparseFetch, - SpvOpImageSparseGather, - SpvOpImageSparseDrefGather, - SpvOpImageSparseTexelsResident, - SpvOpImageSparseRead, - SpvOpSizeOf - // TODO(dneto): Add instructions enabled by ImageQuery + SpvOpNop, + SpvOpUndef, + SpvOpVariable, + SpvOpImageTexelPointer, + SpvOpLoad, + SpvOpAccessChain, + SpvOpInBoundsAccessChain, + SpvOpArrayLength, + SpvOpVectorExtractDynamic, + SpvOpVectorInsertDynamic, + SpvOpVectorShuffle, + SpvOpCompositeConstruct, + SpvOpCompositeExtract, + SpvOpCompositeInsert, + SpvOpCopyObject, + SpvOpTranspose, + SpvOpSampledImage, + SpvOpImageSampleImplicitLod, + SpvOpImageSampleExplicitLod, + SpvOpImageSampleDrefImplicitLod, + SpvOpImageSampleDrefExplicitLod, + SpvOpImageSampleProjImplicitLod, + SpvOpImageSampleProjExplicitLod, + SpvOpImageSampleProjDrefImplicitLod, + SpvOpImageSampleProjDrefExplicitLod, + SpvOpImageFetch, + SpvOpImageGather, + SpvOpImageDrefGather, + SpvOpImageRead, + SpvOpImage, + SpvOpConvertFToU, + SpvOpConvertFToS, + SpvOpConvertSToF, + SpvOpConvertUToF, + SpvOpUConvert, + SpvOpSConvert, + SpvOpFConvert, + SpvOpQuantizeToF16, + SpvOpBitcast, + SpvOpSNegate, + SpvOpFNegate, + SpvOpIAdd, + SpvOpFAdd, + SpvOpISub, + SpvOpFSub, + SpvOpIMul, + SpvOpFMul, + SpvOpUDiv, + SpvOpSDiv, + SpvOpFDiv, + SpvOpUMod, + SpvOpSRem, + SpvOpSMod, + SpvOpFRem, + SpvOpFMod, + SpvOpVectorTimesScalar, + SpvOpMatrixTimesScalar, + SpvOpVectorTimesMatrix, + SpvOpMatrixTimesVector, + SpvOpMatrixTimesMatrix, + SpvOpOuterProduct, + SpvOpDot, + SpvOpIAddCarry, + SpvOpISubBorrow, + SpvOpUMulExtended, + SpvOpSMulExtended, + SpvOpAny, + SpvOpAll, + SpvOpIsNan, + SpvOpIsInf, + SpvOpLogicalEqual, + SpvOpLogicalNotEqual, + SpvOpLogicalOr, + SpvOpLogicalAnd, + SpvOpLogicalNot, + SpvOpSelect, + SpvOpIEqual, + SpvOpINotEqual, + SpvOpUGreaterThan, + SpvOpSGreaterThan, + SpvOpUGreaterThanEqual, + SpvOpSGreaterThanEqual, + SpvOpULessThan, + SpvOpSLessThan, + SpvOpULessThanEqual, + SpvOpSLessThanEqual, + SpvOpFOrdEqual, + SpvOpFUnordEqual, + SpvOpFOrdNotEqual, + SpvOpFUnordNotEqual, + SpvOpFOrdLessThan, + SpvOpFUnordLessThan, + SpvOpFOrdGreaterThan, + SpvOpFUnordGreaterThan, + SpvOpFOrdLessThanEqual, + SpvOpFUnordLessThanEqual, + SpvOpFOrdGreaterThanEqual, + SpvOpFUnordGreaterThanEqual, + SpvOpShiftRightLogical, + SpvOpShiftRightArithmetic, + SpvOpShiftLeftLogical, + SpvOpBitwiseOr, + SpvOpBitwiseXor, + SpvOpBitwiseAnd, + SpvOpNot, + SpvOpBitFieldInsert, + SpvOpBitFieldSExtract, + SpvOpBitFieldUExtract, + SpvOpBitReverse, + SpvOpBitCount, + SpvOpDPdx, + SpvOpDPdy, + SpvOpFwidth, + SpvOpDPdxFine, + SpvOpDPdyFine, + SpvOpFwidthFine, + SpvOpDPdxCoarse, + SpvOpDPdyCoarse, + SpvOpFwidthCoarse, + SpvOpPhi, + SpvOpImageSparseSampleImplicitLod, + SpvOpImageSparseSampleExplicitLod, + SpvOpImageSparseSampleDrefImplicitLod, + SpvOpImageSparseSampleDrefExplicitLod, + SpvOpImageSparseSampleProjImplicitLod, + SpvOpImageSparseSampleProjExplicitLod, + SpvOpImageSparseSampleProjDrefImplicitLod, + SpvOpImageSparseSampleProjDrefExplicitLod, + SpvOpImageSparseFetch, + SpvOpImageSparseGather, + SpvOpImageSparseDrefGather, + SpvOpImageSparseTexelsResident, + SpvOpImageSparseRead, + SpvOpSizeOf + // TODO(dneto): Add instructions enabled by ImageQuery }; // Find supported extension instruction set ids glsl_std_450_id_ = get_module()->GetExtInstImportId("GLSL.std.450"); - combinator_ops_glsl_std_450_ = { - GLSLstd450Round, - GLSLstd450RoundEven, - GLSLstd450Trunc, - GLSLstd450FAbs, - GLSLstd450SAbs, - GLSLstd450FSign, - GLSLstd450SSign, - GLSLstd450Floor, - GLSLstd450Ceil, - GLSLstd450Fract, - GLSLstd450Radians, - GLSLstd450Degrees, - GLSLstd450Sin, - GLSLstd450Cos, - GLSLstd450Tan, - GLSLstd450Asin, - GLSLstd450Acos, - GLSLstd450Atan, - GLSLstd450Sinh, - GLSLstd450Cosh, - GLSLstd450Tanh, - GLSLstd450Asinh, - GLSLstd450Acosh, - GLSLstd450Atanh, - GLSLstd450Atan2, - GLSLstd450Pow, - GLSLstd450Exp, - GLSLstd450Log, - GLSLstd450Exp2, - GLSLstd450Log2, - GLSLstd450Sqrt, - GLSLstd450InverseSqrt, - GLSLstd450Determinant, - GLSLstd450MatrixInverse, - GLSLstd450ModfStruct, - GLSLstd450FMin, - GLSLstd450UMin, - GLSLstd450SMin, - GLSLstd450FMax, - GLSLstd450UMax, - GLSLstd450SMax, - GLSLstd450FClamp, - GLSLstd450UClamp, - GLSLstd450SClamp, - GLSLstd450FMix, - GLSLstd450IMix, - GLSLstd450Step, - GLSLstd450SmoothStep, - GLSLstd450Fma, - GLSLstd450FrexpStruct, - GLSLstd450Ldexp, - GLSLstd450PackSnorm4x8, - GLSLstd450PackUnorm4x8, - GLSLstd450PackSnorm2x16, - GLSLstd450PackUnorm2x16, - GLSLstd450PackHalf2x16, - GLSLstd450PackDouble2x32, - GLSLstd450UnpackSnorm2x16, - GLSLstd450UnpackUnorm2x16, - GLSLstd450UnpackHalf2x16, - GLSLstd450UnpackSnorm4x8, - GLSLstd450UnpackUnorm4x8, - GLSLstd450UnpackDouble2x32, - GLSLstd450Length, - GLSLstd450Distance, - GLSLstd450Cross, - GLSLstd450Normalize, - GLSLstd450FaceForward, - GLSLstd450Reflect, - GLSLstd450Refract, - GLSLstd450FindILsb, - GLSLstd450FindSMsb, - GLSLstd450FindUMsb, - GLSLstd450InterpolateAtCentroid, - GLSLstd450InterpolateAtSample, - GLSLstd450InterpolateAtOffset, - GLSLstd450NMin, - GLSLstd450NMax, - GLSLstd450NClamp - }; + combinator_ops_glsl_std_450_ = {GLSLstd450Round, + GLSLstd450RoundEven, + GLSLstd450Trunc, + GLSLstd450FAbs, + GLSLstd450SAbs, + GLSLstd450FSign, + GLSLstd450SSign, + GLSLstd450Floor, + GLSLstd450Ceil, + GLSLstd450Fract, + GLSLstd450Radians, + GLSLstd450Degrees, + GLSLstd450Sin, + GLSLstd450Cos, + GLSLstd450Tan, + GLSLstd450Asin, + GLSLstd450Acos, + GLSLstd450Atan, + GLSLstd450Sinh, + GLSLstd450Cosh, + GLSLstd450Tanh, + GLSLstd450Asinh, + GLSLstd450Acosh, + GLSLstd450Atanh, + GLSLstd450Atan2, + GLSLstd450Pow, + GLSLstd450Exp, + GLSLstd450Log, + GLSLstd450Exp2, + GLSLstd450Log2, + GLSLstd450Sqrt, + GLSLstd450InverseSqrt, + GLSLstd450Determinant, + GLSLstd450MatrixInverse, + GLSLstd450ModfStruct, + GLSLstd450FMin, + GLSLstd450UMin, + GLSLstd450SMin, + GLSLstd450FMax, + GLSLstd450UMax, + GLSLstd450SMax, + GLSLstd450FClamp, + GLSLstd450UClamp, + GLSLstd450SClamp, + GLSLstd450FMix, + GLSLstd450IMix, + GLSLstd450Step, + GLSLstd450SmoothStep, + GLSLstd450Fma, + GLSLstd450FrexpStruct, + GLSLstd450Ldexp, + GLSLstd450PackSnorm4x8, + GLSLstd450PackUnorm4x8, + GLSLstd450PackSnorm2x16, + GLSLstd450PackUnorm2x16, + GLSLstd450PackHalf2x16, + GLSLstd450PackDouble2x32, + GLSLstd450UnpackSnorm2x16, + GLSLstd450UnpackUnorm2x16, + GLSLstd450UnpackHalf2x16, + GLSLstd450UnpackSnorm4x8, + GLSLstd450UnpackUnorm4x8, + GLSLstd450UnpackDouble2x32, + GLSLstd450Length, + GLSLstd450Distance, + GLSLstd450Cross, + GLSLstd450Normalize, + GLSLstd450FaceForward, + GLSLstd450Reflect, + GLSLstd450Refract, + GLSLstd450FindILsb, + GLSLstd450FindSMsb, + GLSLstd450FindUMsb, + GLSLstd450InterpolateAtCentroid, + GLSLstd450InterpolateAtSample, + GLSLstd450InterpolateAtOffset, + GLSLstd450NMin, + GLSLstd450NMax, + GLSLstd450NClamp}; } void AggressiveDCEPass::InitExtensions() { extensions_whitelist_.clear(); extensions_whitelist_.insert({ - "SPV_AMD_shader_explicit_vertex_parameter", - "SPV_AMD_shader_trinary_minmax", - "SPV_AMD_gcn_shader", - "SPV_KHR_shader_ballot", - "SPV_AMD_shader_ballot", - "SPV_AMD_gpu_shader_half_float", - "SPV_KHR_shader_draw_parameters", - "SPV_KHR_subgroup_vote", - "SPV_KHR_16bit_storage", - "SPV_KHR_device_group", - "SPV_KHR_multiview", - "SPV_NVX_multiview_per_view_attributes", - "SPV_NV_viewport_array2", - "SPV_NV_stereo_view_rendering", - "SPV_NV_sample_mask_override_coverage", - "SPV_NV_geometry_shader_passthrough", - "SPV_AMD_texture_gather_bias_lod", - "SPV_KHR_storage_buffer_storage_class", - // SPV_KHR_variable_pointers - // Currently do not support extended pointer expressions - "SPV_AMD_gpu_shader_int16", - "SPV_KHR_post_depth_coverage", - "SPV_KHR_shader_atomic_counter_ops", + "SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", "SPV_KHR_16bit_storage", "SPV_KHR_device_group", + "SPV_KHR_multiview", "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", "SPV_NV_stereo_view_rendering", + "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + // SPV_KHR_variable_pointers + // Currently do not support extended pointer expressions + "SPV_AMD_gpu_shader_int16", "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", }); } } // namespace opt } // namespace spvtools - diff --git a/source/opt/aggressive_dead_code_elim_pass.h b/source/opt/aggressive_dead_code_elim_pass.h index 7e0bf378..b19e3755 100644 --- a/source/opt/aggressive_dead_code_elim_pass.h +++ b/source/opt/aggressive_dead_code_elim_pass.h @@ -26,20 +26,19 @@ #include "basic_block.h" #include "def_use_manager.h" -#include "module.h" #include "mem_pass.h" +#include "module.h" namespace spvtools { namespace opt { // See optimizer.hpp for documentation. class AggressiveDCEPass : public MemPass { - using cbb_ptr = const ir::BasicBlock*; public: - using GetBlocksFunction = - std::function<std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>; + using GetBlocksFunction = + std::function<std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>; AggressiveDCEPass(); const char* name() const override { return "eliminate-dead-code-aggressive"; } @@ -102,9 +101,9 @@ class AggressiveDCEPass : public MemPass { // If |bp| is structured if header block, return true and set |branchInst| // to the conditional branch and |mergeBlockId| to the merge block. - bool IsStructuredIfHeader(ir::BasicBlock* bp, - ir::Instruction** mergeInst, ir::Instruction** branchInst, - uint32_t* mergeBlockId); + bool IsStructuredIfHeader(ir::BasicBlock* bp, ir::Instruction** mergeInst, + ir::Instruction** branchInst, + uint32_t* mergeBlockId); // Initialize block2branch_ and block2merge_ using |structuredOrder| to // order blocks. @@ -120,7 +119,7 @@ class AggressiveDCEPass : public MemPass { // and block terminating instructions as live. Recursively mark the values // they use. When complete, delete any non-live instructions. Return true // if the function has been modified. - // + // // Note: This function does not delete useless control structures. All // existing control structures will remain. This can leave not-insignificant // sequences of ultimately useless code. @@ -160,7 +159,7 @@ class AggressiveDCEPass : public MemPass { // Map from block's label id to block. std::unordered_map<uint32_t, ir::BasicBlock*> id2block_; - // Map from block to its structured successor blocks. See + // Map from block to its structured successor blocks. See // ComputeStructuredSuccessors() for definition. std::unordered_map<const ir::BasicBlock*, std::vector<ir::BasicBlock*>> block2structured_succs_; @@ -200,4 +199,3 @@ class AggressiveDCEPass : public MemPass { } // namespace spvtools #endif // LIBSPIRV_OPT_AGGRESSIVE_DCE_PASS_H_ - diff --git a/source/opt/block_merge_pass.cpp b/source/opt/block_merge_pass.cpp index 4b06a2eb..c0da5d70 100644 --- a/source/opt/block_merge_pass.cpp +++ b/source/opt/block_merge_pass.cpp @@ -16,8 +16,8 @@ #include "block_merge_pass.h" -#include "iterator.h" #include "ir_context.h" +#include "iterator.h" namespace spvtools { namespace opt { @@ -27,10 +27,8 @@ bool BlockMergePass::HasMultipleRefs(uint32_t labId) { int rcnt = 0; for (const auto u : *uses) { // Don't count OpName - if (u.inst->opcode() == SpvOpName) - continue; - if (rcnt == 1) - return true; + if (u.inst->opcode() == SpvOpName) continue; + if (rcnt == 1) return true; ++rcnt; } return false; @@ -52,7 +50,7 @@ void BlockMergePass::KillInstAndName(ir::Instruction* inst) { bool BlockMergePass::MergeBlocks(ir::Function* func) { bool modified = false; - for (auto bi = func->begin(); bi != func->end(); ) { + for (auto bi = func->begin(); bi != func->end();) { // Do not merge loop header blocks, at least for now. if (bi->IsLoopHeader()) { ++bi; @@ -81,14 +79,13 @@ bool BlockMergePass::MergeBlocks(ir::Function* func) { context()->KillInst(br); auto sbi = bi; for (; sbi != func->end(); ++sbi) - if (sbi->id() == labId) - break; + if (sbi->id() == labId) break; // If bi is sbi's only predecessor, it dominates sbi and thus // sbi must follow bi in func's ordering. assert(sbi != func->end()); bi->AddInstructions(&*sbi); KillInstAndName(sbi->GetLabelInst()); - (void) sbi.Erase(); + (void)sbi.Erase(); // reprocess block modified = true; } @@ -105,8 +102,8 @@ void BlockMergePass::Initialize(ir::IRContext* c) { bool BlockMergePass::AllExtensionsSupported() const { // If any extension not in whitelist, return false for (auto& ei : get_module()->extensions()) { - const char* extName = reinterpret_cast<const char*>( - &ei.GetInOperand(0).words[0]); + const char* extName = + reinterpret_cast<const char*>(&ei.GetInOperand(0).words[0]); if (extensions_whitelist_.find(extName) == extensions_whitelist_.end()) return false; } @@ -115,12 +112,9 @@ bool BlockMergePass::AllExtensionsSupported() const { Pass::Status BlockMergePass::ProcessImpl() { // Do not process if any disallowed extensions are enabled - if (!AllExtensionsSupported()) - return Status::SuccessWithoutChange; + if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; // Process all entry point functions. - ProcessFunction pfn = [this](ir::Function* fp) { - return MergeBlocks(fp); - }; + ProcessFunction pfn = [this](ir::Function* fp) { return MergeBlocks(fp); }; bool modified = ProcessEntryPointCallTree(pfn, get_module()); return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; } @@ -135,31 +129,30 @@ Pass::Status BlockMergePass::Process(ir::IRContext* c) { void BlockMergePass::InitExtensions() { extensions_whitelist_.clear(); extensions_whitelist_.insert({ - "SPV_AMD_shader_explicit_vertex_parameter", - "SPV_AMD_shader_trinary_minmax", - "SPV_AMD_gcn_shader", - "SPV_KHR_shader_ballot", - "SPV_AMD_shader_ballot", - "SPV_AMD_gpu_shader_half_float", - "SPV_KHR_shader_draw_parameters", - "SPV_KHR_subgroup_vote", - "SPV_KHR_16bit_storage", - "SPV_KHR_device_group", - "SPV_KHR_multiview", - "SPV_NVX_multiview_per_view_attributes", - "SPV_NV_viewport_array2", - "SPV_NV_stereo_view_rendering", - "SPV_NV_sample_mask_override_coverage", - "SPV_NV_geometry_shader_passthrough", - "SPV_AMD_texture_gather_bias_lod", - "SPV_KHR_storage_buffer_storage_class", - "SPV_KHR_variable_pointers", - "SPV_AMD_gpu_shader_int16", - "SPV_KHR_post_depth_coverage", - "SPV_KHR_shader_atomic_counter_ops", + "SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", + "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", + "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", + "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", + "SPV_KHR_16bit_storage", + "SPV_KHR_device_group", + "SPV_KHR_multiview", + "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", + "SPV_NV_stereo_view_rendering", + "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", + "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers", + "SPV_AMD_gpu_shader_int16", + "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", }); } } // namespace opt } // namespace spvtools - diff --git a/source/opt/block_merge_pass.h b/source/opt/block_merge_pass.h index 3ebd358c..92921a5b 100644 --- a/source/opt/block_merge_pass.h +++ b/source/opt/block_merge_pass.h @@ -26,9 +26,9 @@ #include "basic_block.h" #include "def_use_manager.h" +#include "ir_context.h" #include "module.h" #include "pass.h" -#include "ir_context.h" namespace spvtools { namespace opt { @@ -68,4 +68,3 @@ class BlockMergePass : public Pass { } // namespace spvtools #endif // LIBSPIRV_OPT_BLOCK_MERGE_PASS_H_ - diff --git a/source/opt/build_module.cpp b/source/opt/build_module.cpp index 766dbb52..e3439f3d 100644 --- a/source/opt/build_module.cpp +++ b/source/opt/build_module.cpp @@ -27,8 +27,8 @@ namespace { spv_result_t SetSpvHeader(void* builder, spv_endianness_t, uint32_t magic, uint32_t version, uint32_t generator, uint32_t id_bound, uint32_t reserved) { - reinterpret_cast<ir::IrLoader*>(builder) - ->SetModuleHeader(magic, version, generator, id_bound, reserved); + reinterpret_cast<ir::IrLoader*>(builder)->SetModuleHeader( + magic, version, generator, id_bound, reserved); return SPV_SUCCESS; }; diff --git a/source/opt/build_module.h b/source/opt/build_module.h index c27b1aeb..36ea74f2 100644 --- a/source/opt/build_module.h +++ b/source/opt/build_module.h @@ -27,9 +27,9 @@ namespace spvtools { // specifies number of words in |binary|. The |binary| will be decoded // according to the given target |env|. Returns nullptr if erors occur and // sends the errors to |consumer|. -std::unique_ptr<ir::Module> BuildModule( - spv_target_env env, MessageConsumer consumer, const uint32_t* binary, - size_t size); +std::unique_ptr<ir::Module> BuildModule(spv_target_env env, + MessageConsumer consumer, + const uint32_t* binary, size_t size); // Builds and returns an ir::Module from the given SPIR-V assembly |text|. // The |text| will be encoded according to the given target |env|. Returns diff --git a/source/opt/common_uniform_elim_pass.cpp b/source/opt/common_uniform_elim_pass.cpp index aafc5f1a..5c3d8725 100644 --- a/source/opt/common_uniform_elim_pass.cpp +++ b/source/opt/common_uniform_elim_pass.cpp @@ -574,31 +574,21 @@ void CommonUniformElimPass::InitExtensions() { extensions_whitelist_.clear(); extensions_whitelist_.insert({ "SPV_AMD_shader_explicit_vertex_parameter", - "SPV_AMD_shader_trinary_minmax", - "SPV_AMD_gcn_shader", - "SPV_KHR_shader_ballot", - "SPV_AMD_shader_ballot", - "SPV_AMD_gpu_shader_half_float", - "SPV_KHR_shader_draw_parameters", - "SPV_KHR_subgroup_vote", - "SPV_KHR_16bit_storage", - "SPV_KHR_device_group", - "SPV_KHR_multiview", - "SPV_NVX_multiview_per_view_attributes", - "SPV_NV_viewport_array2", - "SPV_NV_stereo_view_rendering", + "SPV_AMD_shader_trinary_minmax", "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", "SPV_KHR_16bit_storage", "SPV_KHR_device_group", + "SPV_KHR_multiview", "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", "SPV_NV_stereo_view_rendering", "SPV_NV_sample_mask_override_coverage", - "SPV_NV_geometry_shader_passthrough", - "SPV_AMD_texture_gather_bias_lod", + "SPV_NV_geometry_shader_passthrough", "SPV_AMD_texture_gather_bias_lod", "SPV_KHR_storage_buffer_storage_class", // SPV_KHR_variable_pointers // Currently do not support extended pointer expressions - "SPV_AMD_gpu_shader_int16", - "SPV_KHR_post_depth_coverage", + "SPV_AMD_gpu_shader_int16", "SPV_KHR_post_depth_coverage", "SPV_KHR_shader_atomic_counter_ops", }); } } // namespace opt } // namespace spvtools - diff --git a/source/opt/common_uniform_elim_pass.h b/source/opt/common_uniform_elim_pass.h index ccafd313..0e626600 100644 --- a/source/opt/common_uniform_elim_pass.h +++ b/source/opt/common_uniform_elim_pass.h @@ -24,23 +24,23 @@ #include <unordered_set> #include <utility> -#include "def_use_manager.h" +#include "basic_block.h" #include "decoration_manager.h" +#include "def_use_manager.h" +#include "ir_context.h" #include "module.h" -#include "basic_block.h" #include "pass.h" -#include "ir_context.h" namespace spvtools { namespace opt { // See optimizer.hpp for documentation. class CommonUniformElimPass : public Pass { - using cbb_ptr = const ir::BasicBlock*; + using cbb_ptr = const ir::BasicBlock*; public: - using GetBlocksFunction = - std::function<std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>; + using GetBlocksFunction = + std::function<std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>; CommonUniformElimPass(); const char* name() const override { return "eliminate-common-uniform"; } @@ -72,7 +72,8 @@ class CommonUniformElimPass : public Pass { // Given an OpAccessChain instruction, return true // if the accessed variable belongs to a volatile // decorated object or member of a struct type - bool IsAccessChainToVolatileStructType(const ir::Instruction &AccessChainInst); + bool IsAccessChainToVolatileStructType( + const ir::Instruction& AccessChainInst); // Given an OpLoad instruction, return true if // OpLoad has a Volatile Memory Access flag or if @@ -96,15 +97,14 @@ class CommonUniformElimPass : public Pass { // Replace all instances of load's id with replId and delete load // and its access chain, if any - void ReplaceAndDeleteLoad(ir::Instruction* loadInst, - uint32_t replId, - ir::Instruction* ptrInst); + void ReplaceAndDeleteLoad(ir::Instruction* loadInst, uint32_t replId, + ir::Instruction* ptrInst); // For the (constant index) access chain ptrInst, create an // equivalent load and extract void GenACLoadRepl(const ir::Instruction* ptrInst, - std::vector<std::unique_ptr<ir::Instruction>>* newInsts, - uint32_t* resultId); + std::vector<std::unique_ptr<ir::Instruction>>* newInsts, + uint32_t* resultId); // Return true if all indices are constant bool IsConstantIndexAccessChain(ir::Instruction* acp); @@ -132,14 +132,15 @@ class CommonUniformElimPass : public Pass { // TODO(dnovillo): This pass computes structured order slightly different // than the implementation in class Pass. Can this be re-factored? void ComputeStructuredOrder(ir::Function* func, - std::list<ir::BasicBlock*>* order); + std::list<ir::BasicBlock*>* order); // Eliminate loads of uniform variables which have previously been loaded. // If first load is in control flow, move it to first block of function. // Most effective if preceded by UniformAccessChainRemoval(). bool CommonUniformLoadElimination(ir::Function* func); - // Eliminate loads of uniform sampler and image variables which have previously + // Eliminate loads of uniform sampler and image variables which have + // previously // been loaded in the same block for types whose loads cannot cross blocks. bool CommonUniformLoadElimBlock(ir::Function* func); @@ -150,11 +151,11 @@ class CommonUniformElimPass : public Pass { bool CommonExtractElimination(ir::Function* func); // For function |func|, first change all uniform constant index - // access chain loads into equivalent composite extracts. Then consolidate + // access chain loads into equivalent composite extracts. Then consolidate // identical uniform loads into one uniform load. Finally, consolidate // identical uniform extracts into one uniform extract. This may require // moving a load or extract to a point which dominates all uses. - // Return true if func is modified. + // Return true if func is modified. // // This pass requires the function to have structured control flow ie shader // capability. It also requires logical addressing ie Addresses capability @@ -185,8 +186,9 @@ class CommonUniformElimPass : public Pass { // Map of extract composite ids to map of indices to insts // TODO(greg-lunarg): Consider std::vector. - std::unordered_map<uint32_t, std::unordered_map<uint32_t, - std::list<ir::Instruction*>>> comp2idx2inst_; + std::unordered_map<uint32_t, + std::unordered_map<uint32_t, std::list<ir::Instruction*>>> + comp2idx2inst_; // Extensions supported by this pass. std::unordered_set<std::string> extensions_whitelist_; @@ -201,4 +203,3 @@ class CommonUniformElimPass : public Pass { } // namespace spvtools #endif // LIBSPIRV_OPT_SSAMEM_PASS_H_ - diff --git a/source/opt/compact_ids_pass.cpp b/source/opt/compact_ids_pass.cpp index 5a7c4855..380b75cc 100644 --- a/source/opt/compact_ids_pass.cpp +++ b/source/opt/compact_ids_pass.cpp @@ -30,35 +30,38 @@ Pass::Status CompactIdsPass::Process(ir::IRContext* c) { bool modified = false; std::unordered_map<uint32_t, uint32_t> result_id_mapping; - c->module()->ForEachInst([&result_id_mapping, &modified] (Instruction* inst) { - auto operand = inst->begin(); - while (operand != inst->end()) { - const auto type = operand->type; - if (spvIsIdType(type)) { - assert(operand->words.size() == 1); - uint32_t& id = operand->words[0]; - auto it = result_id_mapping.find(id); - if (it == result_id_mapping.end()) { - const uint32_t new_id = - static_cast<uint32_t>(result_id_mapping.size()) + 1; - const auto insertion_result = result_id_mapping.emplace(id, new_id); - it = insertion_result.first; - assert(insertion_result.second); - } - if (id != it->second) { - modified = true; - id = it->second; - // Update data cached in the instruction object. - if (type == SPV_OPERAND_TYPE_RESULT_ID) { - inst->SetResultId(id); - } else if (type == SPV_OPERAND_TYPE_TYPE_ID) { - inst->SetResultType(id); + c->module()->ForEachInst( + [&result_id_mapping, &modified](Instruction* inst) { + auto operand = inst->begin(); + while (operand != inst->end()) { + const auto type = operand->type; + if (spvIsIdType(type)) { + assert(operand->words.size() == 1); + uint32_t& id = operand->words[0]; + auto it = result_id_mapping.find(id); + if (it == result_id_mapping.end()) { + const uint32_t new_id = + static_cast<uint32_t>(result_id_mapping.size()) + 1; + const auto insertion_result = + result_id_mapping.emplace(id, new_id); + it = insertion_result.first; + assert(insertion_result.second); + } + if (id != it->second) { + modified = true; + id = it->second; + // Update data cached in the instruction object. + if (type == SPV_OPERAND_TYPE_RESULT_ID) { + inst->SetResultId(id); + } else if (type == SPV_OPERAND_TYPE_TYPE_ID) { + inst->SetResultType(id); + } + } } + ++operand; } - } - ++operand; - } - }, true); + }, + true); if (modified) c->SetIdBound(static_cast<uint32_t>(result_id_mapping.size() + 1)); diff --git a/source/opt/compact_ids_pass.h b/source/opt/compact_ids_pass.h index 702620ea..cf7c3fb7 100644 --- a/source/opt/compact_ids_pass.h +++ b/source/opt/compact_ids_pass.h @@ -15,9 +15,9 @@ #ifndef LIBSPIRV_OPT_COMPACT_IDS_PASS_H_ #define LIBSPIRV_OPT_COMPACT_IDS_PASS_H_ +#include "ir_context.h" #include "module.h" #include "pass.h" -#include "ir_context.h" namespace spvtools { namespace opt { diff --git a/source/opt/dead_branch_elim_pass.cpp b/source/opt/dead_branch_elim_pass.cpp index ebca89e5..7d543f98 100644 --- a/source/opt/dead_branch_elim_pass.cpp +++ b/source/opt/dead_branch_elim_pass.cpp @@ -29,7 +29,7 @@ const uint32_t kBranchCondTrueLabIdInIdx = 1; const uint32_t kBranchCondFalseLabIdInIdx = 2; const uint32_t kSelectionMergeMergeBlockIdInIdx = 0; -} // anonymous namespace +} // anonymous namespace bool DeadBranchElimPass::GetConstCondition(uint32_t condId, bool* condVal) { bool condIsConst; @@ -45,14 +45,11 @@ bool DeadBranchElimPass::GetConstCondition(uint32_t condId, bool* condVal) { } break; case SpvOpLogicalNot: { bool negVal; - condIsConst = GetConstCondition(cInst->GetSingleWordInOperand(0), - &negVal); - if (condIsConst) - *condVal = !negVal; - } break; - default: { - condIsConst = false; + condIsConst = + GetConstCondition(cInst->GetSingleWordInOperand(0), &negVal); + if (condIsConst) *condVal = !negVal; } break; + default: { condIsConst = false; } break; } return condIsConst; } @@ -63,13 +60,11 @@ bool DeadBranchElimPass::GetConstInteger(uint32_t selId, uint32_t* selVal) { ir::Instruction* typeInst = get_def_use_mgr()->GetDef(typeId); if (!typeInst || (typeInst->opcode() != SpvOpTypeInt)) return false; // TODO(greg-lunarg): Support non-32 bit ints - if (typeInst->GetSingleWordInOperand(0) != 32) - return false; + if (typeInst->GetSingleWordInOperand(0) != 32) return false; if (sInst->opcode() == SpvOpConstant) { *selVal = sInst->GetSingleWordInOperand(0); return true; - } - else if (sInst->opcode() == SpvOpConstantNull) { + } else if (sInst->opcode() == SpvOpConstantNull) { *selVal = 0; return true; } @@ -77,46 +72,47 @@ bool DeadBranchElimPass::GetConstInteger(uint32_t selId, uint32_t* selVal) { } void DeadBranchElimPass::AddBranch(uint32_t labelId, ir::BasicBlock* bp) { - std::unique_ptr<ir::Instruction> newBranch( - new ir::Instruction(SpvOpBranch, 0, 0, - {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}})); + std::unique_ptr<ir::Instruction> newBranch(new ir::Instruction( + SpvOpBranch, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}})); get_def_use_mgr()->AnalyzeInstDefUse(&*newBranch); bp->AddInstruction(std::move(newBranch)); } void DeadBranchElimPass::AddSelectionMerge(uint32_t labelId, - ir::BasicBlock* bp) { - std::unique_ptr<ir::Instruction> newMerge( - new ir::Instruction(SpvOpSelectionMerge, 0, 0, - {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {0}}})); + ir::BasicBlock* bp) { + std::unique_ptr<ir::Instruction> newMerge(new ir::Instruction( + SpvOpSelectionMerge, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {0}}})); get_def_use_mgr()->AnalyzeInstDefUse(&*newMerge); bp->AddInstruction(std::move(newMerge)); } void DeadBranchElimPass::AddBranchConditional(uint32_t condId, - uint32_t trueLabId, uint32_t falseLabId, ir::BasicBlock* bp) { - std::unique_ptr<ir::Instruction> newBranchCond( - new ir::Instruction(SpvOpBranchConditional, 0, 0, - {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {condId}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {trueLabId}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {falseLabId}}})); + uint32_t trueLabId, + uint32_t falseLabId, + ir::BasicBlock* bp) { + std::unique_ptr<ir::Instruction> newBranchCond(new ir::Instruction( + SpvOpBranchConditional, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {condId}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {trueLabId}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {falseLabId}}})); get_def_use_mgr()->AnalyzeInstDefUse(&*newBranchCond); bp->AddInstruction(std::move(newBranchCond)); } bool DeadBranchElimPass::GetSelectionBranch(ir::BasicBlock* bp, - ir::Instruction** branchInst, ir::Instruction** mergeInst, - uint32_t *condId) { + ir::Instruction** branchInst, + ir::Instruction** mergeInst, + uint32_t* condId) { auto ii = bp->end(); --ii; *branchInst = &*ii; - if (ii == bp->begin()) - return false; + if (ii == bp->begin()) return false; --ii; *mergeInst = &*ii; - if ((*mergeInst)->opcode() != SpvOpSelectionMerge) - return false; + if ((*mergeInst)->opcode() != SpvOpSelectionMerge) return false; // SPIR-V says the terminator for an OpSelectionMerge must be // either a conditional branch or a switch. assert((*branchInst)->opcode() == SpvOpBranchConditional || @@ -128,8 +124,7 @@ bool DeadBranchElimPass::GetSelectionBranch(ir::BasicBlock* bp, bool DeadBranchElimPass::HasNonPhiNonBackedgeRef(uint32_t labelId) { analysis::UseList* uses = get_def_use_mgr()->GetUses(labelId); - if (uses == nullptr) - return false; + if (uses == nullptr) return false; for (auto u : *uses) { if (u.inst->opcode() != SpvOpPhi && backedges_.find(u.inst) == backedges_.end()) @@ -147,24 +142,22 @@ void DeadBranchElimPass::ComputeBackEdges( visited.insert((*bi)->id()); auto ii = (*bi)->end(); --ii; - switch(ii->opcode()) { + switch (ii->opcode()) { case SpvOpBranch: { - const uint32_t labId = ii->GetSingleWordInOperand( - kBranchTargetLabIdInIdx); - if (visited.find(labId) != visited.end()) - backedges_.insert(&*ii); + const uint32_t labId = + ii->GetSingleWordInOperand(kBranchTargetLabIdInIdx); + if (visited.find(labId) != visited.end()) backedges_.insert(&*ii); } break; case SpvOpBranchConditional: { - const uint32_t tLabId = ii->GetSingleWordInOperand( - kBranchCondTrueLabIdInIdx); + const uint32_t tLabId = + ii->GetSingleWordInOperand(kBranchCondTrueLabIdInIdx); if (visited.find(tLabId) != visited.end()) { backedges_.insert(&*ii); break; } - const uint32_t fLabId = ii->GetSingleWordInOperand( - kBranchCondFalseLabIdInIdx); - if (visited.find(fLabId) != visited.end()) - backedges_.insert(&*ii); + const uint32_t fLabId = + ii->GetSingleWordInOperand(kBranchCondFalseLabIdInIdx); + if (visited.find(fLabId) != visited.end()) backedges_.insert(&*ii); } break; default: break; @@ -181,53 +174,45 @@ bool DeadBranchElimPass::EliminateDeadBranches(ir::Function* func) { bool modified = false; for (auto bi = structuredOrder.begin(); bi != structuredOrder.end(); ++bi) { // Skip blocks that are already in the elimination set - if (elimBlocks.find(*bi) != elimBlocks.end()) - continue; + if (elimBlocks.find(*bi) != elimBlocks.end()) continue; // Skip blocks that don't have conditional branch preceded // by OpSelectionMerge ir::Instruction* br; ir::Instruction* mergeInst; uint32_t condId; - if (!GetSelectionBranch(*bi, &br, &mergeInst, &condId)) - continue; + if (!GetSelectionBranch(*bi, &br, &mergeInst, &condId)) continue; // If constant condition/selector, replace conditional branch/switch // with unconditional branch and delete merge uint32_t liveLabId; if (br->opcode() == SpvOpBranchConditional) { bool condVal; - if (!GetConstCondition(condId, &condVal)) - continue; - liveLabId = (condVal == true) ? - br->GetSingleWordInOperand(kBranchCondTrueLabIdInIdx) : - br->GetSingleWordInOperand(kBranchCondFalseLabIdInIdx); - } - else { + if (!GetConstCondition(condId, &condVal)) continue; + liveLabId = (condVal == true) + ? br->GetSingleWordInOperand(kBranchCondTrueLabIdInIdx) + : br->GetSingleWordInOperand(kBranchCondFalseLabIdInIdx); + } else { assert(br->opcode() == SpvOpSwitch); // Search switch operands for selector value, set liveLabId to // corresponding label, use default if not found uint32_t selVal; - if (!GetConstInteger(condId, &selVal)) - continue; + if (!GetConstInteger(condId, &selVal)) continue; uint32_t icnt = 0; uint32_t caseVal; br->ForEachInOperand( - [&icnt,&caseVal,&selVal,&liveLabId](const uint32_t* idp) { - if (icnt == 1) { - // Start with default label - liveLabId = *idp; - } - else if (icnt > 1) { - if (icnt % 2 == 0) { - caseVal = *idp; - } - else { - if (caseVal == selVal) + [&icnt, &caseVal, &selVal, &liveLabId](const uint32_t* idp) { + if (icnt == 1) { + // Start with default label liveLabId = *idp; - } - } - ++icnt; - }); + } else if (icnt > 1) { + if (icnt % 2 == 0) { + caseVal = *idp; + } else { + if (caseVal == selVal) liveLabId = *idp; + } + } + ++icnt; + }); } const uint32_t mergeLabId = @@ -258,36 +243,30 @@ bool DeadBranchElimPass::EliminateDeadBranches(ir::Function* func) { KillAllInsts(*dbi); elimBlocks.insert(*dbi); ++dbi; - if (dbi == structuredOrder.end()) - break; + if (dbi == structuredOrder.end()) break; dLabId = (*dbi)->id(); } // If last block reached, look for next dead branch - if (dbi == structuredOrder.end()) - continue; + if (dbi == structuredOrder.end()) continue; // Create set of dead predecessors in preparation for phi update. // Add the header block if the live branch is not the merge block. std::unordered_set<ir::BasicBlock*> deadPreds(elimBlocks); - if (liveLabId != dLabId) - deadPreds.insert(*bi); + if (liveLabId != dLabId) deadPreds.insert(*bi); // Update phi instructions in terminating block. - for (auto pii = (*dbi)->begin(); ; ++pii) { + for (auto pii = (*dbi)->begin();; ++pii) { // Skip NoOps, break at end of phis SpvOp op = pii->opcode(); - if (op == SpvOpNop) - continue; - if (op != SpvOpPhi) - break; + if (op == SpvOpNop) continue; + if (op != SpvOpPhi) break; // Count phi's live predecessors with lcnt and remember last one // with lidx. uint32_t lcnt = 0; uint32_t lidx = 0; uint32_t icnt = 0; - pii->ForEachInId( - [&deadPreds,&icnt,&lcnt,&lidx,this](uint32_t* idp) { + pii->ForEachInId([&deadPreds, &icnt, &lcnt, &lidx, this](uint32_t* idp) { if (icnt % 2 == 1) { if (deadPreds.find(cfg()->block(*idp)) == deadPreds.end()) { ++lcnt; @@ -300,8 +279,7 @@ bool DeadBranchElimPass::EliminateDeadBranches(ir::Function* func) { uint32_t replId; if (lcnt == 1) { replId = pii->GetSingleWordInOperand(lidx); - } - else { + } else { // Otherwise create new phi eliminating dead predecessor entries assert(lcnt > 1); replId = TakeNextId(); @@ -309,20 +287,19 @@ bool DeadBranchElimPass::EliminateDeadBranches(ir::Function* func) { icnt = 0; uint32_t lastId; pii->ForEachInId( - [&deadPreds,&icnt,&phi_in_opnds,&lastId,this](uint32_t* idp) { - if (icnt % 2 == 1) { - if (deadPreds.find(cfg()->block(*idp)) == deadPreds.end()) { - phi_in_opnds.push_back( - {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {lastId}}); - phi_in_opnds.push_back( - {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {*idp}}); - } - } - else { - lastId = *idp; - } - ++icnt; - }); + [&deadPreds, &icnt, &phi_in_opnds, &lastId, this](uint32_t* idp) { + if (icnt % 2 == 1) { + if (deadPreds.find(cfg()->block(*idp)) == deadPreds.end()) { + phi_in_opnds.push_back( + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {lastId}}); + phi_in_opnds.push_back( + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {*idp}}); + } + } else { + lastId = *idp; + } + ++icnt; + }); std::unique_ptr<ir::Instruction> newPhi(new ir::Instruction( SpvOpPhi, pii->type_id(), replId, phi_in_opnds)); get_def_use_mgr()->AnalyzeInstDefUse(&*newPhi); @@ -337,7 +314,7 @@ bool DeadBranchElimPass::EliminateDeadBranches(ir::Function* func) { } // Erase dead blocks - for (auto ebi = func->begin(); ebi != func->end(); ) + for (auto ebi = func->begin(); ebi != func->end();) if (elimBlocks.find(&*ebi) != elimBlocks.end()) ebi = ebi.Erase(); else @@ -355,8 +332,8 @@ void DeadBranchElimPass::Initialize(ir::IRContext* c) { bool DeadBranchElimPass::AllExtensionsSupported() const { // If any extension not in whitelist, return false for (auto& ei : get_module()->extensions()) { - const char* extName = reinterpret_cast<const char*>( - &ei.GetInOperand(0).words[0]); + const char* extName = + reinterpret_cast<const char*>(&ei.GetInOperand(0).words[0]); if (extensions_whitelist_.find(extName) == extensions_whitelist_.end()) return false; } @@ -364,7 +341,7 @@ bool DeadBranchElimPass::AllExtensionsSupported() const { } Pass::Status DeadBranchElimPass::ProcessImpl() { - // Current functionality assumes structured control flow. + // Current functionality assumes structured control flow. // TODO(greg-lunarg): Handle non-structured control-flow. if (!get_module()->HasCapability(SpvCapabilityShader)) return Status::SuccessWithoutChange; @@ -372,11 +349,9 @@ Pass::Status DeadBranchElimPass::ProcessImpl() { // support required in KillNamesAndDecorates(). // TODO(greg-lunarg): Add support for OpGroupDecorate for (auto& ai : get_module()->annotations()) - if (ai.opcode() == SpvOpGroupDecorate) - return Status::SuccessWithoutChange; + if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange; // Do not process if any disallowed extensions are enabled - if (!AllExtensionsSupported()) - return Status::SuccessWithoutChange; + if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; // Process all entry point functions ProcessFunction pfn = [this](ir::Function* fp) { return EliminateDeadBranches(fp); @@ -395,31 +370,30 @@ Pass::Status DeadBranchElimPass::Process(ir::IRContext* module) { void DeadBranchElimPass::InitExtensions() { extensions_whitelist_.clear(); extensions_whitelist_.insert({ - "SPV_AMD_shader_explicit_vertex_parameter", - "SPV_AMD_shader_trinary_minmax", - "SPV_AMD_gcn_shader", - "SPV_KHR_shader_ballot", - "SPV_AMD_shader_ballot", - "SPV_AMD_gpu_shader_half_float", - "SPV_KHR_shader_draw_parameters", - "SPV_KHR_subgroup_vote", - "SPV_KHR_16bit_storage", - "SPV_KHR_device_group", - "SPV_KHR_multiview", - "SPV_NVX_multiview_per_view_attributes", - "SPV_NV_viewport_array2", - "SPV_NV_stereo_view_rendering", - "SPV_NV_sample_mask_override_coverage", - "SPV_NV_geometry_shader_passthrough", - "SPV_AMD_texture_gather_bias_lod", - "SPV_KHR_storage_buffer_storage_class", - "SPV_KHR_variable_pointers", - "SPV_AMD_gpu_shader_int16", - "SPV_KHR_post_depth_coverage", - "SPV_KHR_shader_atomic_counter_ops", + "SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", + "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", + "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", + "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", + "SPV_KHR_16bit_storage", + "SPV_KHR_device_group", + "SPV_KHR_multiview", + "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", + "SPV_NV_stereo_view_rendering", + "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", + "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers", + "SPV_AMD_gpu_shader_int16", + "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", }); } } // namespace opt } // namespace spvtools - diff --git a/source/opt/dead_branch_elim_pass.h b/source/opt/dead_branch_elim_pass.h index a27c5716..e7b648e8 100644 --- a/source/opt/dead_branch_elim_pass.h +++ b/source/opt/dead_branch_elim_pass.h @@ -17,7 +17,6 @@ #ifndef LIBSPIRV_OPT_DEAD_BRANCH_ELIM_PASS_H_ #define LIBSPIRV_OPT_DEAD_BRANCH_ELIM_PASS_H_ - #include <algorithm> #include <map> #include <queue> @@ -27,20 +26,19 @@ #include "basic_block.h" #include "def_use_manager.h" -#include "module.h" #include "mem_pass.h" +#include "module.h" namespace spvtools { namespace opt { // See optimizer.hpp for documentation. class DeadBranchElimPass : public MemPass { - using cbb_ptr = const ir::BasicBlock*; public: - using GetBlocksFunction = - std::function<std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>; + using GetBlocksFunction = + std::function<std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>; DeadBranchElimPass(); const char* name() const override { return "eliminate-dead-branches"; } @@ -64,13 +62,13 @@ class DeadBranchElimPass : public MemPass { // Add conditional branch of |condId|, |trueLabId| and |falseLabId| to end // of block |bp|. void AddBranchConditional(uint32_t condId, uint32_t trueLabId, - uint32_t falseLabId, ir::BasicBlock* bp); + uint32_t falseLabId, ir::BasicBlock* bp); // If block |bp| contains conditional branch or switch preceeded by an // OpSelctionMerge, return true and return branch and merge instructions - // in |branchInst| and |mergeInst| and the conditional id in |condId|. + // in |branchInst| and |mergeInst| and the conditional id in |condId|. bool GetSelectionBranch(ir::BasicBlock* bp, ir::Instruction** branchInst, - ir::Instruction** mergeInst, uint32_t *condId); + ir::Instruction** mergeInst, uint32_t* condId); // Return true if |labelId| has any non-phi, non-backedge references bool HasNonPhiNonBackedgeRef(uint32_t labelId); @@ -106,4 +104,3 @@ class DeadBranchElimPass : public MemPass { } // namespace spvtools #endif // LIBSPIRV_OPT_DEAD_BRANCH_ELIM_PASS_H_ - diff --git a/source/opt/dead_variable_elimination.cpp b/source/opt/dead_variable_elimination.cpp index 4fd6b2d0..70d2eb5b 100644 --- a/source/opt/dead_variable_elimination.cpp +++ b/source/opt/dead_variable_elimination.cpp @@ -24,7 +24,8 @@ namespace opt { Pass::Status DeadVariableElimination::Process(ir::IRContext* c) { // The algorithm will compute the reference count for every global variable. // Anything with a reference count of 0 will then be deleted. For variables - // that might have references that are not explicit in this context, we use the + // that might have references that are not explicit in this context, we use + // the // value kMustKeep as the reference count. InitializeProcessing(c); @@ -61,7 +62,7 @@ Pass::Status DeadVariableElimination::Process(ir::IRContext* c) { count = std::count_if( uses->begin(), uses->end(), [](const analysis::Use& u) { return (!ir::IsAnnotationInst(u.inst->opcode()) && - u.inst->opcode() != SpvOpName); + u.inst->opcode() != SpvOpName); }); } } @@ -85,7 +86,7 @@ Pass::Status DeadVariableElimination::Process(ir::IRContext* c) { void DeadVariableElimination::DeleteVariable(uint32_t result_id) { ir::Instruction* inst = get_def_use_mgr()->GetDef(result_id); assert(inst->opcode() == SpvOpVariable && - "Should not be trying to delete anything other than an OpVariable."); + "Should not be trying to delete anything other than an OpVariable."); // Look for an initializer that references another variable. We need to know // if that variable can be deleted after the reference is removed. diff --git a/source/opt/dead_variable_elimination.h b/source/opt/dead_variable_elimination.h index 8412b1ee..8b6a27fa 100644 --- a/source/opt/dead_variable_elimination.h +++ b/source/opt/dead_variable_elimination.h @@ -15,8 +15,8 @@ #ifndef SPIRV_TOOLS_DEAD_VARIABLE_ELIMINATION_H #define SPIRV_TOOLS_DEAD_VARIABLE_ELIMINATION_H -#include <unordered_map> #include <climits> +#include <unordered_map> #include "decoration_manager.h" #include "mem_pass.h" diff --git a/source/opt/decoration_manager.cpp b/source/opt/decoration_manager.cpp index b12670bf..b1c43d5a 100644 --- a/source/opt/decoration_manager.cpp +++ b/source/opt/decoration_manager.cpp @@ -29,8 +29,9 @@ void DecorationManager::RemoveDecorationsFrom(uint32_t id, bool keep_linkage) { case SpvOpDecorate: case SpvOpDecorateId: case SpvOpMemberDecorate: - if (!(keep_linkage && inst->GetSingleWordInOperand(1u) == - SpvDecorationLinkageAttributes)) + if (!(keep_linkage && + inst->GetSingleWordInOperand(1u) == + SpvDecorationLinkageAttributes)) inst->ToNop(); break; case SpvOpGroupDecorate: @@ -229,9 +230,9 @@ std::vector<T> DecorationManager::InternalGetDecorationsFor( return decorations; } -void DecorationManager::ForEachDecoration(uint32_t id, - uint32_t decoration, - std::function<void(const ir::Instruction&)> f) const { +void DecorationManager::ForEachDecoration( + uint32_t id, uint32_t decoration, + std::function<void(const ir::Instruction&)> f) const { auto decoration_list = id_to_decoration_insts_.find(id); if (decoration_list != id_to_decoration_insts_.end()) { for (const ir::Instruction* inst : decoration_list->second) { diff --git a/source/opt/def_use_manager.cpp b/source/opt/def_use_manager.cpp index 1444a27f..d3c050ca 100644 --- a/source/opt/def_use_manager.cpp +++ b/source/opt/def_use_manager.cpp @@ -31,8 +31,7 @@ void DefUseManager::AnalyzeInstDef(ir::Instruction* inst) { ClearInst(iter->second); } id_to_def_[def_id] = inst; - } - else { + } else { ClearInst(inst); } } @@ -46,16 +45,16 @@ void DefUseManager::AnalyzeInstUse(ir::Instruction* inst) { for (uint32_t i = 0; i < inst->NumOperands(); ++i) { switch (inst->GetOperand(i).type) { // For any id type but result id type - case SPV_OPERAND_TYPE_ID: - case SPV_OPERAND_TYPE_TYPE_ID: - case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID: - case SPV_OPERAND_TYPE_SCOPE_ID: { - uint32_t use_id = inst->GetSingleWordOperand(i); - id_to_uses_[use_id].push_back({ inst, i }); - inst_to_used_ids_[inst].push_back(use_id); - } break; - default: - break; + case SPV_OPERAND_TYPE_ID: + case SPV_OPERAND_TYPE_TYPE_ID: + case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID: + case SPV_OPERAND_TYPE_SCOPE_ID: { + uint32_t use_id = inst->GetSingleWordOperand(i); + id_to_uses_[use_id].push_back({inst, i}); + inst_to_used_ids_[inst].push_back(use_id); + } break; + default: + break; } } } @@ -101,7 +100,6 @@ std::vector<ir::Instruction*> DefUseManager::GetAnnotations(uint32_t id) const { return annos; } - void DefUseManager::AnalyzeDefUse(ir::Module* module) { if (!module) return; module->ForEachInst(std::bind(&DefUseManager::AnalyzeInstDefUse, this, diff --git a/source/opt/def_use_manager.h b/source/opt/def_use_manager.h index d4b7fc26..1b9f41ea 100644 --- a/source/opt/def_use_manager.h +++ b/source/opt/def_use_manager.h @@ -49,9 +49,7 @@ class DefUseManager { // will be communicated to the outside via the given message |consumer|. This // instance only keeps a reference to the |consumer|, so the |consumer| should // outlive this instance. - DefUseManager(ir::Module* module) { - AnalyzeDefUse(module); - } + DefUseManager(ir::Module* module) { AnalyzeDefUse(module); } DefUseManager(const DefUseManager&) = delete; DefUseManager(DefUseManager&&) = delete; @@ -105,8 +103,8 @@ class DefUseManager { // structures in this class. Does nothing if |module| is nullptr. void AnalyzeDefUse(ir::Module* module); - IdToDefMap id_to_def_; // Mapping from ids to their definitions - IdToUsesMap id_to_uses_; // Mapping from ids to their uses + IdToDefMap id_to_def_; // Mapping from ids to their definitions + IdToUsesMap id_to_uses_; // Mapping from ids to their uses // Mapping from instructions to the ids used in the instruction. InstToUsedIdsMap inst_to_used_ids_; }; diff --git a/source/opt/eliminate_dead_constant_pass.cpp b/source/opt/eliminate_dead_constant_pass.cpp index 4d33ccf1..32fc5da5 100644 --- a/source/opt/eliminate_dead_constant_pass.cpp +++ b/source/opt/eliminate_dead_constant_pass.cpp @@ -19,9 +19,9 @@ #include <unordered_set> #include "def_use_manager.h" +#include "ir_context.h" #include "log.h" #include "reflect.h" -#include "ir_context.h" namespace spvtools { namespace opt { @@ -36,7 +36,8 @@ Pass::Status EliminateDeadConstantPass::Process(ir::IRContext* irContext) { for (auto* c : constants) { uint32_t const_id = c->result_id(); size_t count = 0; - if (analysis::UseList* uses = irContext->get_def_use_mgr()->GetUses(const_id)) { + if (analysis::UseList* uses = + irContext->get_def_use_mgr()->GetUses(const_id)) { count = std::count_if(uses->begin(), uses->end(), [](const analysis::Use& u) { return !(ir::IsAnnotationInst(u.inst->opcode()) || @@ -68,7 +69,8 @@ Pass::Status EliminateDeadConstantPass::Process(ir::IRContext* irContext) { continue; } uint32_t operand_id = inst->GetSingleWordInOperand(i); - ir::Instruction* def_inst = irContext->get_def_use_mgr()->GetDef(operand_id); + ir::Instruction* def_inst = + irContext->get_def_use_mgr()->GetDef(operand_id); // If the use_count does not have any count for the def_inst, // def_inst must not be a constant, and should be ignored here. if (!use_counts.count(def_inst)) { @@ -94,7 +96,8 @@ Pass::Status EliminateDeadConstantPass::Process(ir::IRContext* irContext) { // constants. std::unordered_set<ir::Instruction*> dead_others; for (auto* dc : dead_consts) { - if (analysis::UseList* uses = irContext->get_def_use_mgr()->GetUses(dc->result_id())) { + if (analysis::UseList* uses = + irContext->get_def_use_mgr()->GetUses(dc->result_id())) { for (const auto& u : *uses) { if (ir::IsAnnotationInst(u.inst->opcode()) || ir::IsDebug1Inst(u.inst->opcode()) || diff --git a/source/opt/eliminate_dead_constant_pass.h b/source/opt/eliminate_dead_constant_pass.h index cf6957f9..3ff69f5c 100644 --- a/source/opt/eliminate_dead_constant_pass.h +++ b/source/opt/eliminate_dead_constant_pass.h @@ -15,9 +15,9 @@ #ifndef LIBSPIRV_OPT_ELIMINATE_DEAD_CONSTANT_PASS_H_ #define LIBSPIRV_OPT_ELIMINATE_DEAD_CONSTANT_PASS_H_ +#include "ir_context.h" #include "module.h" #include "pass.h" -#include "ir_context.h" namespace spvtools { namespace opt { diff --git a/source/opt/flatten_decoration_pass.cpp b/source/opt/flatten_decoration_pass.cpp index 094c5803..e92935d8 100644 --- a/source/opt/flatten_decoration_pass.cpp +++ b/source/opt/flatten_decoration_pass.cpp @@ -16,9 +16,9 @@ #include "ir_context.h" #include <cassert> -#include <vector> #include <unordered_map> #include <unordered_set> +#include <vector> namespace spvtools { namespace opt { diff --git a/source/opt/flatten_decoration_pass.h b/source/opt/flatten_decoration_pass.h index 345b39b4..7db6f864 100644 --- a/source/opt/flatten_decoration_pass.h +++ b/source/opt/flatten_decoration_pass.h @@ -15,9 +15,9 @@ #ifndef LIBSPIRV_OPT_FLATTEN_DECORATION_PASS_H_ #define LIBSPIRV_OPT_FLATTEN_DECORATION_PASS_H_ +#include "ir_context.h" #include "module.h" #include "pass.h" -#include "ir_context.h" namespace spvtools { namespace opt { diff --git a/source/opt/fold.h b/source/opt/fold.h index c6e61d68..f1e5ea1a 100644 --- a/source/opt/fold.h +++ b/source/opt/fold.h @@ -15,8 +15,8 @@ #ifndef LIBSPIRV_UTIL_FOLD_H_ #define LIBSPIRV_UTIL_FOLD_H_ -#include "def_use_manager.h" #include "constants.h" +#include "def_use_manager.h" #include <cstdint> #include <vector> diff --git a/source/opt/fold_spec_constant_op_and_composite_pass.cpp b/source/opt/fold_spec_constant_op_and_composite_pass.cpp index ad078fd9..a630d8a3 100644 --- a/source/opt/fold_spec_constant_op_and_composite_pass.cpp +++ b/source/opt/fold_spec_constant_op_and_composite_pass.cpp @@ -19,8 +19,8 @@ #include <tuple> #include "constants.h" -#include "make_unique.h" #include "ir_context.h" +#include "make_unique.h" namespace spvtools { namespace opt { @@ -245,7 +245,8 @@ std::vector<uint32_t> OperateVectors( FoldSpecConstantOpAndCompositePass::FoldSpecConstantOpAndCompositePass() : max_id_(0), type_mgr_(nullptr), id_to_const_val_() {} -Pass::Status FoldSpecConstantOpAndCompositePass::Process(ir::IRContext* irContext) { +Pass::Status FoldSpecConstantOpAndCompositePass::Process( + ir::IRContext* irContext) { Initialize(irContext); return ProcessImpl(irContext); } diff --git a/source/opt/fold_spec_constant_op_and_composite_pass.h b/source/opt/fold_spec_constant_op_and_composite_pass.h index fd1ff6b3..b1cfd0c8 100644 --- a/source/opt/fold_spec_constant_op_and_composite_pass.h +++ b/source/opt/fold_spec_constant_op_and_composite_pass.h @@ -21,10 +21,10 @@ #include "constants.h" #include "def_use_manager.h" +#include "ir_context.h" #include "module.h" #include "pass.h" #include "type_manager.h" -#include "ir_context.h" namespace spvtools { namespace opt { diff --git a/source/opt/freeze_spec_constant_value_pass.h b/source/opt/freeze_spec_constant_value_pass.h index 8d163d0d..fc7f44e7 100644 --- a/source/opt/freeze_spec_constant_value_pass.h +++ b/source/opt/freeze_spec_constant_value_pass.h @@ -15,9 +15,9 @@ #ifndef LIBSPIRV_OPT_FREEZE_SPEC_CONSTANT_VALUE_PASS_H_ #define LIBSPIRV_OPT_FREEZE_SPEC_CONSTANT_VALUE_PASS_H_ +#include "ir_context.h" #include "module.h" #include "pass.h" -#include "ir_context.h" namespace spvtools { namespace opt { diff --git a/source/opt/function.h b/source/opt/function.h index a67c3299..618eb7d2 100644 --- a/source/opt/function.h +++ b/source/opt/function.h @@ -64,8 +64,9 @@ class Function { // Returns function's id inline uint32_t result_id() const { return def_inst_->result_id(); } -// // Returns function's type id -// inline uint32_t type_id() const { return def_inst_->GetSingleWordInOperand(1u); } + // // Returns function's type id + // inline uint32_t type_id() const { return + // def_inst_->GetSingleWordInOperand(1u); } // Returns function's return type id inline uint32_t type_id() const { return def_inst_->type_id(); } diff --git a/source/opt/inline_exhaustive_pass.cpp b/source/opt/inline_exhaustive_pass.cpp index 5be0329b..d829f36c 100644 --- a/source/opt/inline_exhaustive_pass.cpp +++ b/source/opt/inline_exhaustive_pass.cpp @@ -31,13 +31,13 @@ bool InlineExhaustivePass::InlineExhaustive(ir::Function* func) { GenInlineCode(&newBlocks, &newVars, ii, bi); // If call block is replaced with more than one block, point // succeeding phis at new last block. - if (newBlocks.size() > 1) - UpdateSucceedingPhis(newBlocks); + if (newBlocks.size() > 1) UpdateSucceedingPhis(newBlocks); // Replace old calling block with new block(s). bi = bi.Erase(); bi = bi.InsertBefore(&newBlocks); // Insert new function variables. - if (newVars.size() > 0) func->begin()->begin().InsertBefore(std::move(newVars)); + if (newVars.size() > 0) + func->begin()->begin().InsertBefore(std::move(newVars)); // Restart inlining at beginning of calling block. ii = bi->begin(); modified = true; diff --git a/source/opt/inline_exhaustive_pass.h b/source/opt/inline_exhaustive_pass.h index 9d3076b9..08b4387b 100644 --- a/source/opt/inline_exhaustive_pass.h +++ b/source/opt/inline_exhaustive_pass.h @@ -20,19 +20,18 @@ #include <algorithm> #include <list> #include <memory> -#include <vector> #include <unordered_map> +#include <vector> #include "def_use_manager.h" -#include "module.h" #include "inline_pass.h" +#include "module.h" namespace spvtools { namespace opt { // See optimizer.hpp for documentation. class InlineExhaustivePass : public InlinePass { - public: InlineExhaustivePass(); Status Process(ir::IRContext* c) override; diff --git a/source/opt/inline_opaque_pass.cpp b/source/opt/inline_opaque_pass.cpp index e4762eb5..2f6c6692 100644 --- a/source/opt/inline_opaque_pass.cpp +++ b/source/opt/inline_opaque_pass.cpp @@ -21,9 +21,9 @@ namespace opt { namespace { - const uint32_t kTypePointerTypeIdInIdx = 1; +const uint32_t kTypePointerTypeIdInIdx = 1; -} // anonymous namespace +} // anonymous namespace bool InlineOpaquePass::IsOpaqueType(uint32_t typeId) { const ir::Instruction* typeInst = get_def_use_mgr()->GetDef(typeId); @@ -33,17 +33,16 @@ bool InlineOpaquePass::IsOpaqueType(uint32_t typeId) { case SpvOpTypeSampledImage: return true; case SpvOpTypePointer: - return IsOpaqueType(typeInst->GetSingleWordInOperand( - kTypePointerTypeIdInIdx)); + return IsOpaqueType( + typeInst->GetSingleWordInOperand(kTypePointerTypeIdInIdx)); default: break; } // TODO(greg-lunarg): Handle arrays containing opaque type - if (typeInst->opcode() != SpvOpTypeStruct) - return false; + if (typeInst->opcode() != SpvOpTypeStruct) return false; // Return true if any member is opaque int ocnt = 0; - typeInst->ForEachInId([&ocnt,this](const uint32_t* tid) { + typeInst->ForEachInId([&ocnt, this](const uint32_t* tid) { if (ocnt == 0 && IsOpaqueType(*tid)) ++ocnt; }); return ocnt > 0; @@ -51,16 +50,14 @@ bool InlineOpaquePass::IsOpaqueType(uint32_t typeId) { bool InlineOpaquePass::HasOpaqueArgsOrReturn(const ir::Instruction* callInst) { // Check return type - if (IsOpaqueType(callInst->type_id())) - return true; + if (IsOpaqueType(callInst->type_id())) return true; // Check args int icnt = 0; int ocnt = 0; - callInst->ForEachInId([&icnt,&ocnt,this](const uint32_t *iid) { + callInst->ForEachInId([&icnt, &ocnt, this](const uint32_t* iid) { if (icnt > 0) { const ir::Instruction* argInst = get_def_use_mgr()->GetDef(*iid); - if (IsOpaqueType(argInst->type_id())) - ++ocnt; + if (IsOpaqueType(argInst->type_id())) ++ocnt; } ++icnt; }); @@ -79,13 +76,13 @@ bool InlineOpaquePass::InlineOpaque(ir::Function* func) { GenInlineCode(&newBlocks, &newVars, ii, bi); // If call block is replaced with more than one block, point // succeeding phis at new last block. - if (newBlocks.size() > 1) - UpdateSucceedingPhis(newBlocks); + if (newBlocks.size() > 1) UpdateSucceedingPhis(newBlocks); // Replace old calling block with new block(s). bi = bi.Erase(); bi = bi.InsertBefore(&newBlocks); // Insert new function variables. - if (newVars.size() > 0) func->begin()->begin().InsertBefore(std::move(newVars)); + if (newVars.size() > 0) + func->begin()->begin().InsertBefore(std::move(newVars)); // Restart inlining at beginning of calling block. ii = bi->begin(); modified = true; @@ -97,15 +94,11 @@ bool InlineOpaquePass::InlineOpaque(ir::Function* func) { return modified; } -void InlineOpaquePass::Initialize(ir::IRContext* c) { - InitializeInline(c); -}; +void InlineOpaquePass::Initialize(ir::IRContext* c) { InitializeInline(c); }; Pass::Status InlineOpaquePass::ProcessImpl() { // Do opaque inlining on each function in entry point call tree - ProcessFunction pfn = [this](ir::Function* fp) { - return InlineOpaque(fp); - }; + ProcessFunction pfn = [this](ir::Function* fp) { return InlineOpaque(fp); }; bool modified = ProcessEntryPointCallTree(pfn, get_module()); return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; } diff --git a/source/opt/inline_opaque_pass.h b/source/opt/inline_opaque_pass.h index 6ad1a362..0a6cf0ec 100644 --- a/source/opt/inline_opaque_pass.h +++ b/source/opt/inline_opaque_pass.h @@ -20,19 +20,18 @@ #include <algorithm> #include <list> #include <memory> -#include <vector> #include <unordered_map> +#include <vector> #include "def_use_manager.h" -#include "module.h" #include "inline_pass.h" +#include "module.h" namespace spvtools { namespace opt { // See optimizer.hpp for documentation. class InlineOpaquePass : public InlinePass { - public: InlineOpaquePass(); Status Process(ir::IRContext* c) override; diff --git a/source/opt/inline_pass.cpp b/source/opt/inline_pass.cpp index 83d365cd..706af448 100644 --- a/source/opt/inline_pass.cpp +++ b/source/opt/inline_pass.cpp @@ -58,25 +58,26 @@ uint32_t InlinePass::AddPointerToType(uint32_t type_id, } void InlinePass::AddBranch(uint32_t label_id, - std::unique_ptr<ir::BasicBlock>* block_ptr) { + std::unique_ptr<ir::BasicBlock>* block_ptr) { std::unique_ptr<ir::Instruction> newBranch(new ir::Instruction( - SpvOpBranch, 0, 0, - {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {label_id}}})); + SpvOpBranch, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {label_id}}})); (*block_ptr)->AddInstruction(std::move(newBranch)); } void InlinePass::AddBranchCond(uint32_t cond_id, uint32_t true_id, - uint32_t false_id, std::unique_ptr<ir::BasicBlock>* block_ptr) { + uint32_t false_id, + std::unique_ptr<ir::BasicBlock>* block_ptr) { std::unique_ptr<ir::Instruction> newBranch(new ir::Instruction( - SpvOpBranchConditional, 0, 0, - {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {cond_id}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {true_id}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {false_id}}})); + SpvOpBranchConditional, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {cond_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {true_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {false_id}}})); (*block_ptr)->AddInstruction(std::move(newBranch)); } void InlinePass::AddLoopMerge(uint32_t merge_id, uint32_t continue_id, - std::unique_ptr<ir::BasicBlock>* block_ptr) { + std::unique_ptr<ir::BasicBlock>* block_ptr) { std::unique_ptr<ir::Instruction> newLoopMerge(new ir::Instruction( SpvOpLoopMerge, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {merge_id}}, @@ -88,8 +89,9 @@ void InlinePass::AddLoopMerge(uint32_t merge_id, uint32_t continue_id, void InlinePass::AddStore(uint32_t ptr_id, uint32_t val_id, std::unique_ptr<ir::BasicBlock>* block_ptr) { std::unique_ptr<ir::Instruction> newStore(new ir::Instruction( - SpvOpStore, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ptr_id}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {val_id}}})); + SpvOpStore, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ptr_id}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {val_id}}})); (*block_ptr)->AddInstruction(std::move(newStore)); } @@ -108,11 +110,9 @@ std::unique_ptr<ir::Instruction> InlinePass::NewLabel(uint32_t label_id) { } uint32_t InlinePass::GetFalseId() { - if (false_id_ != 0) - return false_id_; + if (false_id_ != 0) return false_id_; false_id_ = get_module()->GetGlobalValue(SpvOpConstantFalse); - if (false_id_ != 0) - return false_id_; + if (false_id_ != 0) return false_id_; uint32_t boolId = get_module()->GetGlobalValue(SpvOpTypeBool); if (boolId == 0) { boolId = TakeNextId(); @@ -124,8 +124,7 @@ uint32_t InlinePass::GetFalseId() { } void InlinePass::MapParams( - ir::Function* calleeFn, - ir::BasicBlock::iterator call_inst_itr, + ir::Function* calleeFn, ir::BasicBlock::iterator call_inst_itr, std::unordered_map<uint32_t, uint32_t>* callee2caller) { int param_idx = 0; calleeFn->ForEachParam( @@ -186,8 +185,8 @@ void InlinePass::CloneSameBlockOps( std::unordered_map<uint32_t, uint32_t>* postCallSB, std::unordered_map<uint32_t, ir::Instruction*>* preCallSB, std::unique_ptr<ir::BasicBlock>* block_ptr) { - (*inst) - ->ForEachInId([&postCallSB, &preCallSB, &block_ptr, this](uint32_t* iid) { + (*inst)->ForEachInId( + [&postCallSB, &preCallSB, &block_ptr, this](uint32_t* iid) { const auto mapItr = (*postCallSB).find(*iid); if (mapItr == (*postCallSB).end()) { const auto mapItr2 = (*preCallSB).find(*iid); @@ -242,11 +241,9 @@ void InlinePass::GenInlineCode( // Create set of callee result ids. Used to detect forward references std::unordered_set<uint32_t> callee_result_ids; - calleeFn->ForEachInst([&callee_result_ids]( - const ir::Instruction* cpi) { + calleeFn->ForEachInst([&callee_result_ids](const ir::Instruction* cpi) { const uint32_t rid = cpi->result_id(); - if (rid != 0) - callee_result_ids.insert(rid); + if (rid != 0) callee_result_ids.insert(rid); }); // If the caller is in a single-block loop, and the callee has multiple @@ -333,8 +330,7 @@ void InlinePass::GenInlineCode( } new_blk_ptr->AddInstruction(std::move(cp_inst)); } - if (caller_is_loop_header && - callee_begins_with_structured_header) { + if (caller_is_loop_header && callee_begins_with_structured_header) { // We can't place both the caller's merge instruction and another // merge instruction in the same block. So split the calling block. // Insert an unconditional branch to a new guard block. Later, @@ -366,8 +362,8 @@ void InlinePass::GenInlineCode( singleTripLoopHeaderId = this->TakeNextId(); AddBranch(singleTripLoopHeaderId, &new_blk_ptr); new_blocks->push_back(std::move(new_blk_ptr)); - new_blk_ptr.reset(new ir::BasicBlock(NewLabel( - singleTripLoopHeaderId))); + new_blk_ptr.reset( + new ir::BasicBlock(NewLabel(singleTripLoopHeaderId))); returnLabelId = this->TakeNextId(); singleTripLoopContinueId = this->TakeNextId(); AddLoopMerge(returnLabelId, singleTripLoopContinueId, &new_blk_ptr); @@ -475,8 +471,7 @@ void InlinePass::GenInlineCode( uint32_t nid; if (mapItr != callee2caller.end()) { nid = mapItr->second; - } - else { + } else { nid = this->TakeNextId(); callee2caller[rid] = nid; } @@ -530,15 +525,14 @@ void InlinePass::UpdateSucceedingPhis( const auto lastBlk = new_blocks.end() - 1; const uint32_t firstId = (*firstBlk)->id(); const uint32_t lastId = (*lastBlk)->id(); - (*lastBlk)->ForEachSuccessorLabel( - [&firstId, &lastId, this](uint32_t succ) { - ir::BasicBlock* sbp = this->id2block_[succ]; - sbp->ForEachPhiInst([&firstId, &lastId](ir::Instruction* phi) { - phi->ForEachInId([&firstId, &lastId](uint32_t* id) { - if (*id == firstId) *id = lastId; - }); - }); + (*lastBlk)->ForEachSuccessorLabel([&firstId, &lastId, this](uint32_t succ) { + ir::BasicBlock* sbp = this->id2block_[succ]; + sbp->ForEachPhiInst([&firstId, &lastId](ir::Instruction* phi) { + phi->ForEachInId([&firstId, &lastId](uint32_t* id) { + if (*id == firstId) *id = lastId; }); + }); + }); } bool InlinePass::HasMultipleReturns(ir::Function* func) { @@ -547,7 +541,7 @@ bool InlinePass::HasMultipleReturns(ir::Function* func) { for (auto& blk : *func) { auto terminal_ii = blk.cend(); --terminal_ii; - if (terminal_ii->opcode() == SpvOpReturn || + if (terminal_ii->opcode() == SpvOpReturn || terminal_ii->opcode() == SpvOpReturnValue) { if (seenReturn) { multipleReturns = true; @@ -559,7 +553,6 @@ bool InlinePass::HasMultipleReturns(ir::Function* func) { return multipleReturns; } - void InlinePass::ComputeStructuredSuccessors(ir::Function* func) { // If header, make merge block first successor. for (auto& blk : *func) { @@ -584,8 +577,7 @@ InlinePass::GetBlocksFunction InlinePass::StructuredSuccessorsFunction() { bool InlinePass::HasNoReturnInLoop(ir::Function* func) { // If control not structured, do not do loop/return analysis // TODO: Analyze returns in non-structured control flow - if (!get_module()->HasCapability(SpvCapabilityShader)) - return false; + if (!get_module()->HasCapability(SpvCapabilityShader)) return false; // Compute structured block order. This order has the property // that dominators are before all blocks they dominate and merge blocks // are after all blocks that are in the control constructs of their header. @@ -594,32 +586,30 @@ bool InlinePass::HasNoReturnInLoop(ir::Function* func) { auto ignore_edge = [](cbb_ptr, cbb_ptr) {}; std::list<const ir::BasicBlock*> structuredOrder; spvtools::CFA<ir::BasicBlock>::DepthFirstTraversal( - &*func->begin(), StructuredSuccessorsFunction(), ignore_block, - [&](cbb_ptr b) { structuredOrder.push_front(b); }, ignore_edge); + &*func->begin(), StructuredSuccessorsFunction(), ignore_block, + [&](cbb_ptr b) { structuredOrder.push_front(b); }, ignore_edge); // Search for returns in loops. Only need to track outermost loop bool return_in_loop = false; uint32_t outerLoopMergeId = 0; for (auto& blk : structuredOrder) { // Exiting current outer loop - if (blk->id() == outerLoopMergeId) - outerLoopMergeId = 0; + if (blk->id() == outerLoopMergeId) outerLoopMergeId = 0; // Return block auto terminal_ii = blk->cend(); --terminal_ii; - if (terminal_ii->opcode() == SpvOpReturn || + if (terminal_ii->opcode() == SpvOpReturn || terminal_ii->opcode() == SpvOpReturnValue) { if (outerLoopMergeId != 0) { return_in_loop = true; break; } - } - else if (terminal_ii != blk->cbegin()) { + } else if (terminal_ii != blk->cbegin()) { auto merge_ii = terminal_ii; --merge_ii; // Entering outermost loop if (merge_ii->opcode() == SpvOpLoopMerge && outerLoopMergeId == 0) - outerLoopMergeId = merge_ii->GetSingleWordOperand( - kSpvLoopMergeMergeBlockId); + outerLoopMergeId = + merge_ii->GetSingleWordOperand(kSpvLoopMergeMergeBlockId); } } return !return_in_loop; @@ -633,14 +623,12 @@ void InlinePass::AnalyzeReturns(ir::Function* func) { } multi_return_funcs_.insert(func->result_id()); // If multiple returns, see if any are in a loop - if (HasNoReturnInLoop(func)) - no_return_in_loop_.insert(func->result_id()); + if (HasNoReturnInLoop(func)) no_return_in_loop_.insert(func->result_id()); } bool InlinePass::IsInlinableFunction(ir::Function* func) { // We can only inline a function if it has blocks. - if (func->cbegin() == func->cend()) - return false; + if (func->cbegin() == func->cend()) return false; // Do not inline functions with returns in loops. Currently early return // functions are inlined by wrapping them in a one trip loop and implementing // the returns as a branch to the loop's merge block. However, this can only @@ -671,8 +659,7 @@ void InlinePass::InitializeInline(ir::IRContext* c) { id2block_[blk.id()] = &blk; } // Compute inlinability - if (IsInlinableFunction(&fn)) - inlinable_.insert(fn.result_id()); + if (IsInlinableFunction(&fn)) inlinable_.insert(fn.result_id()); } }; diff --git a/source/opt/inline_pass.h b/source/opt/inline_pass.h index 1eae3f07..61d0b7ff 100644 --- a/source/opt/inline_pass.h +++ b/source/opt/inline_pass.h @@ -18,10 +18,10 @@ #define LIBSPIRV_OPT_INLINE_PASS_H_ #include <algorithm> +#include <list> #include <memory> #include <unordered_map> #include <vector> -#include <list> #include "def_use_manager.h" #include "module.h" @@ -32,12 +32,11 @@ namespace opt { // See optimizer.hpp for documentation. class InlinePass : public Pass { - using cbb_ptr = const ir::BasicBlock*; public: - using GetBlocksFunction = - std::function<std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>; + using GetBlocksFunction = + std::function<std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>; InlinePass(); virtual ~InlinePass() = default; @@ -54,8 +53,8 @@ class InlinePass : public Pass { void AddBranch(uint32_t labelId, std::unique_ptr<ir::BasicBlock>* block_ptr); // Add conditional branch to end of block |block_ptr|. - void AddBranchCond(uint32_t cond_id, uint32_t true_id, - uint32_t false_id, std::unique_ptr<ir::BasicBlock>* block_ptr); + void AddBranchCond(uint32_t cond_id, uint32_t true_id, uint32_t false_id, + std::unique_ptr<ir::BasicBlock>* block_ptr); // Add unconditional branch to labelId to end of block block_ptr. void AddLoopMerge(uint32_t merge_id, uint32_t continue_id, @@ -77,8 +76,7 @@ class InlinePass : public Pass { uint32_t GetFalseId(); // Map callee params to caller args - void MapParams(ir::Function* calleeFn, - ir::BasicBlock::iterator call_inst_itr, + void MapParams(ir::Function* calleeFn, ir::BasicBlock::iterator call_inst_itr, std::unordered_map<uint32_t, uint32_t>* callee2caller); // Clone and map callee locals @@ -133,11 +131,11 @@ class InlinePass : public Pass { // A block's structured successors are the blocks it branches to // together with its declared merge block if it has one. // When order matters, the merge block always appears first. - // This assures correct depth first search in the presence of early + // This assures correct depth first search in the presence of early // returns and kills. If the successor vector contain duplicates // if the merge block, they are safely ignored by DFS. void ComputeStructuredSuccessors(ir::Function* func); - + // Return function to return ordered structure successors for a given block // Assumes ComputeStructuredSuccessors() has been called. GetBlocksFunction StructuredSuccessorsFunction(); diff --git a/source/opt/insert_extract_elim.cpp b/source/opt/insert_extract_elim.cpp index c44ec48d..d3c64854 100644 --- a/source/opt/insert_extract_elim.cpp +++ b/source/opt/insert_extract_elim.cpp @@ -16,8 +16,8 @@ #include "insert_extract_elim.h" -#include "iterator.h" #include "ir_context.h" +#include "iterator.h" namespace spvtools { namespace opt { @@ -28,12 +28,11 @@ const uint32_t kExtractCompositeIdInIdx = 0; const uint32_t kInsertObjectIdInIdx = 0; const uint32_t kInsertCompositeIdInIdx = 1; -} // anonymous namespace +} // anonymous namespace bool InsertExtractElimPass::ExtInsMatch(const ir::Instruction* extInst, - const ir::Instruction* insInst) const { - if (extInst->NumInOperands() != insInst->NumInOperands() - 1) - return false; + const ir::Instruction* insInst) const { + if (extInst->NumInOperands() != insInst->NumInOperands() - 1) return false; uint32_t numIdx = extInst->NumInOperands() - 1; for (uint32_t i = 0; i < numIdx; ++i) if (extInst->GetSingleWordInOperand(i + 1) != @@ -42,10 +41,9 @@ bool InsertExtractElimPass::ExtInsMatch(const ir::Instruction* extInst, return true; } -bool InsertExtractElimPass::ExtInsConflict(const ir::Instruction* extInst, - const ir::Instruction* insInst) const { - if (extInst->NumInOperands() == insInst->NumInOperands() - 1) - return false; +bool InsertExtractElimPass::ExtInsConflict( + const ir::Instruction* extInst, const ir::Instruction* insInst) const { + if (extInst->NumInOperands() == insInst->NumInOperands() - 1) return false; uint32_t extNumIdx = extInst->NumInOperands() - 1; uint32_t insNumIdx = insInst->NumInOperands() - 2; uint32_t numIdx = std::min(extNumIdx, insNumIdx); @@ -71,8 +69,7 @@ bool InsertExtractElimPass::EliminateInsertExtract(ir::Function* func) { ir::Instruction* cinst = get_def_use_mgr()->GetDef(cid); uint32_t replId = 0; while (cinst->opcode() == SpvOpCompositeInsert) { - if (ExtInsConflict(&*ii, cinst)) - break; + if (ExtInsConflict(&*ii, cinst)) break; if (ExtInsMatch(&*ii, cinst)) { replId = cinst->GetSingleWordInOperand(kInsertObjectIdInIdx); break; @@ -96,14 +93,12 @@ bool InsertExtractElimPass::EliminateInsertExtract(ir::Function* func) { for (; i <= compIdx; i++) { uint32_t compId = cinst->GetSingleWordInOperand(i); ir::Instruction* compInst = get_def_use_mgr()->GetDef(compId); - if (compInst->type_id() != (*ii).type_id()) - break; + if (compInst->type_id() != (*ii).type_id()) break; } if (i > compIdx) replId = cinst->GetSingleWordInOperand(compIdx); } - } - else { + } else { replId = cinst->GetSingleWordInOperand(compIdx); } } @@ -132,8 +127,8 @@ void InsertExtractElimPass::Initialize(ir::IRContext* c) { bool InsertExtractElimPass::AllExtensionsSupported() const { // If any extension not in whitelist, return false for (auto& ei : get_module()->extensions()) { - const char* extName = reinterpret_cast<const char*>( - &ei.GetInOperand(0).words[0]); + const char* extName = + reinterpret_cast<const char*>(&ei.GetInOperand(0).words[0]); if (extensions_whitelist_.find(extName) == extensions_whitelist_.end()) return false; } @@ -142,8 +137,7 @@ bool InsertExtractElimPass::AllExtensionsSupported() const { Pass::Status InsertExtractElimPass::ProcessImpl() { // Do not process if any disallowed extensions are enabled - if (!AllExtensionsSupported()) - return Status::SuccessWithoutChange; + if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; // Process all entry point functions. ProcessFunction pfn = [this](ir::Function* fp) { return EliminateInsertExtract(fp); @@ -162,31 +156,30 @@ Pass::Status InsertExtractElimPass::Process(ir::IRContext* c) { void InsertExtractElimPass::InitExtensions() { extensions_whitelist_.clear(); extensions_whitelist_.insert({ - "SPV_AMD_shader_explicit_vertex_parameter", - "SPV_AMD_shader_trinary_minmax", - "SPV_AMD_gcn_shader", - "SPV_KHR_shader_ballot", - "SPV_AMD_shader_ballot", - "SPV_AMD_gpu_shader_half_float", - "SPV_KHR_shader_draw_parameters", - "SPV_KHR_subgroup_vote", - "SPV_KHR_16bit_storage", - "SPV_KHR_device_group", - "SPV_KHR_multiview", - "SPV_NVX_multiview_per_view_attributes", - "SPV_NV_viewport_array2", - "SPV_NV_stereo_view_rendering", - "SPV_NV_sample_mask_override_coverage", - "SPV_NV_geometry_shader_passthrough", - "SPV_AMD_texture_gather_bias_lod", - "SPV_KHR_storage_buffer_storage_class", - "SPV_KHR_variable_pointers", - "SPV_AMD_gpu_shader_int16", - "SPV_KHR_post_depth_coverage", - "SPV_KHR_shader_atomic_counter_ops", + "SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", + "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", + "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", + "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", + "SPV_KHR_16bit_storage", + "SPV_KHR_device_group", + "SPV_KHR_multiview", + "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", + "SPV_NV_stereo_view_rendering", + "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", + "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + "SPV_KHR_variable_pointers", + "SPV_AMD_gpu_shader_int16", + "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", }); } } // namespace opt } // namespace spvtools - diff --git a/source/opt/insert_extract_elim.h b/source/opt/insert_extract_elim.h index fc475800..d5dba00f 100644 --- a/source/opt/insert_extract_elim.h +++ b/source/opt/insert_extract_elim.h @@ -17,7 +17,6 @@ #ifndef LIBSPIRV_OPT_INSERT_EXTRACT_ELIM_PASS_H_ #define LIBSPIRV_OPT_INSERT_EXTRACT_ELIM_PASS_H_ - #include <algorithm> #include <map> #include <unordered_map> @@ -26,9 +25,9 @@ #include "basic_block.h" #include "def_use_manager.h" +#include "ir_context.h" #include "module.h" #include "pass.h" -#include "ir_context.h" namespace spvtools { namespace opt { @@ -42,16 +41,16 @@ class InsertExtractElimPass : public Pass { private: // Return true if indices of extract |extInst| and insert |insInst| match - bool ExtInsMatch( - const ir::Instruction* extInst, const ir::Instruction* insInst) const; + bool ExtInsMatch(const ir::Instruction* extInst, + const ir::Instruction* insInst) const; // Return true if indices of extract |extInst| and insert |insInst| conflict, // specifically, if the insert changes bits specified by the extract, but // changes either more bits or less bits than the extract specifies, // meaning the exact value being inserted cannot be used to replace // the extract. - bool ExtInsConflict( - const ir::Instruction* extInst, const ir::Instruction* insInst) const; + bool ExtInsConflict(const ir::Instruction* extInst, + const ir::Instruction* insInst) const; // Return true if |typeId| is a vector type bool IsVectorType(uint32_t typeId); @@ -79,4 +78,3 @@ class InsertExtractElimPass : public Pass { } // namespace spvtools #endif // LIBSPIRV_OPT_INSERT_EXTRACT_ELIM_PASS_H_ - diff --git a/source/opt/instruction.h b/source/opt/instruction.h index 95ac0d5b..cc4474e2 100644 --- a/source/opt/instruction.h +++ b/source/opt/instruction.h @@ -219,8 +219,8 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> { // Runs the given function |f| on all "in" operands inline void ForEachInOperand(const std::function<void(uint32_t*)>& f); - inline void ForEachInOperand(const std::function<void(const uint32_t*)>& f) - const; + inline void ForEachInOperand( + const std::function<void(const uint32_t*)>& f) const; // Returns true if any operands can be labels inline bool HasLabels() const; @@ -308,9 +308,9 @@ inline void Instruction::ForEachInst( inline void Instruction::ForEachId(const std::function<void(uint32_t*)>& f) { for (auto& opnd : operands_) if (spvIsIdType(opnd.type)) f(&opnd.words[0]); - if (type_id_ != 0u) - type_id_ = GetSingleWordOperand(0u); - if (result_id_ != 0u) result_id_ = GetSingleWordOperand(type_id_ == 0u ? 0u : 1u); + if (type_id_ != 0u) type_id_ = GetSingleWordOperand(0u); + if (result_id_ != 0u) + result_id_ = GetSingleWordOperand(type_id_ == 0u ? 0u : 1u); } inline void Instruction::ForEachId( @@ -347,7 +347,7 @@ inline void Instruction::ForEachInId( } inline void Instruction::ForEachInOperand( - const std::function<void(uint32_t*)>& f) { + const std::function<void(uint32_t*)>& f) { for (auto& opnd : operands_) { switch (opnd.type) { case SPV_OPERAND_TYPE_RESULT_ID: diff --git a/source/opt/instruction_list.cpp b/source/opt/instruction_list.cpp index 904a0b32..d8ddb84e 100644 --- a/source/opt/instruction_list.cpp +++ b/source/opt/instruction_list.cpp @@ -17,7 +17,6 @@ namespace spvtools { namespace ir { - InstructionList::iterator InstructionList::iterator::InsertBefore( std::vector<std::unique_ptr<Instruction>>&& list) { Instruction* first_node = list.front().get(); diff --git a/source/opt/ir_context.cpp b/source/opt/ir_context.cpp index 85d3298e..122aff03 100644 --- a/source/opt/ir_context.cpp +++ b/source/opt/ir_context.cpp @@ -24,7 +24,8 @@ void IRContext::BuildInvalidAnalyses(IRContext::Analysis set) { } } -void IRContext::InvalidateAnalysesExceptFor(IRContext::Analysis preserved_analyses) { +void IRContext::InvalidateAnalysesExceptFor( + IRContext::Analysis preserved_analyses) { uint32_t analyses_to_invalidate = valid_analyses_ & (~preserved_analyses); if (analyses_to_invalidate & kAnalysisDefUse) { def_use_mgr_.reset(nullptr); @@ -75,7 +76,7 @@ bool IRContext::ReplaceAllUsesWith(uint32_t before, uint32_t after) { } else if (use.inst->type_id() == 0) { SPIRV_ASSERT(consumer_, false, "Result type id considered as use while the instruction " - "doesn't have a result type id."); + "doesn't have a result type id."); (void)consumer_; // Makes the compiler happy for release build. } else { SPIRV_ASSERT(consumer_, false, diff --git a/source/opt/iterator.h b/source/opt/iterator.h index e62bb74c..d2247f49 100644 --- a/source/opt/iterator.h +++ b/source/opt/iterator.h @@ -123,21 +123,23 @@ class IteratorRange { // Returns a (begin, end) iterator pair for the given iterators. // The iterators must belong to the same container. -template<typename IteratorType> -inline IteratorRange<IteratorType> make_range(IteratorType& begin, IteratorType& end) { +template <typename IteratorType> +inline IteratorRange<IteratorType> make_range(IteratorType& begin, + IteratorType& end) { return {begin, end}; } // Returns a (begin, end) iterator pair for the given iterators. // The iterators must belong to the same container. -template<typename IteratorType> -inline IteratorRange<IteratorType> make_range(IteratorType&& begin, IteratorType&& end) { +template <typename IteratorType> +inline IteratorRange<IteratorType> make_range(IteratorType&& begin, + IteratorType&& end) { return {begin, end}; } // Returns a (begin, end) iterator pair for the given container. -template<typename ValueType, - class IteratorType = UptrVectorIterator<ValueType>> +template <typename ValueType, + class IteratorType = UptrVectorIterator<ValueType>> inline IteratorRange<IteratorType> make_range( std::vector<std::unique_ptr<ValueType>>& container) { return {IteratorType(&container, container.begin()), diff --git a/source/opt/local_access_chain_convert_pass.cpp b/source/opt/local_access_chain_convert_pass.cpp index 1ea52251..41c92885 100644 --- a/source/opt/local_access_chain_convert_pass.cpp +++ b/source/opt/local_access_chain_convert_pass.cpp @@ -28,7 +28,7 @@ const uint32_t kAccessChainPtrIdInIdx = 0; const uint32_t kConstantValueInIdx = 0; const uint32_t kTypeIntWidthInIdx = 0; -} // anonymous namespace +} // anonymous namespace void LocalAccessChainConvertPass::DeleteIfUseless(ir::Instruction* inst) { const uint32_t resId = inst->result_id(); @@ -40,21 +40,17 @@ void LocalAccessChainConvertPass::DeleteIfUseless(ir::Instruction* inst) { } void LocalAccessChainConvertPass::BuildAndAppendInst( - SpvOp opcode, - uint32_t typeId, - uint32_t resultId, + SpvOp opcode, uint32_t typeId, uint32_t resultId, const std::vector<ir::Operand>& in_opnds, std::vector<std::unique_ptr<ir::Instruction>>* newInsts) { - std::unique_ptr<ir::Instruction> newInst(new ir::Instruction( - opcode, typeId, resultId, in_opnds)); + std::unique_ptr<ir::Instruction> newInst( + new ir::Instruction(opcode, typeId, resultId, in_opnds)); get_def_use_mgr()->AnalyzeInstDefUse(&*newInst); newInsts->emplace_back(std::move(newInst)); } uint32_t LocalAccessChainConvertPass::BuildAndAppendVarLoad( - const ir::Instruction* ptrInst, - uint32_t* varId, - uint32_t* varPteTypeId, + const ir::Instruction* ptrInst, uint32_t* varId, uint32_t* varPteTypeId, std::vector<std::unique_ptr<ir::Instruction>>* newInsts) { const uint32_t ldResultId = TakeNextId(); *varId = ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx); @@ -62,20 +58,20 @@ uint32_t LocalAccessChainConvertPass::BuildAndAppendVarLoad( assert(varInst->opcode() == SpvOpVariable); *varPteTypeId = GetPointeeTypeId(varInst); BuildAndAppendInst(SpvOpLoad, *varPteTypeId, ldResultId, - {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {*varId}}}, newInsts); + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {*varId}}}, + newInsts); return ldResultId; } void LocalAccessChainConvertPass::AppendConstantOperands( - const ir::Instruction* ptrInst, - std::vector<ir::Operand>* in_opnds) { + const ir::Instruction* ptrInst, std::vector<ir::Operand>* in_opnds) { uint32_t iidIdx = 0; - ptrInst->ForEachInId([&iidIdx, &in_opnds, this](const uint32_t *iid) { + ptrInst->ForEachInId([&iidIdx, &in_opnds, this](const uint32_t* iid) { if (iidIdx > 0) { const ir::Instruction* cInst = get_def_use_mgr()->GetDef(*iid); uint32_t val = cInst->GetSingleWordInOperand(kConstantValueInIdx); in_opnds->push_back( - {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {val}}); + {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {val}}); } ++iidIdx; }); @@ -84,12 +80,11 @@ void LocalAccessChainConvertPass::AppendConstantOperands( uint32_t LocalAccessChainConvertPass::GenAccessChainLoadReplacement( const ir::Instruction* ptrInst, std::vector<std::unique_ptr<ir::Instruction>>* newInsts) { - // Build and append load of variable in ptrInst uint32_t varId; uint32_t varPteTypeId; - const uint32_t ldResultId = BuildAndAppendVarLoad(ptrInst, &varId, - &varPteTypeId, newInsts); + const uint32_t ldResultId = + BuildAndAppendVarLoad(ptrInst, &varId, &varPteTypeId, newInsts); // Build and append Extract const uint32_t extResultId = TakeNextId(); @@ -103,30 +98,28 @@ uint32_t LocalAccessChainConvertPass::GenAccessChainLoadReplacement( } void LocalAccessChainConvertPass::GenAccessChainStoreReplacement( - const ir::Instruction* ptrInst, - uint32_t valId, + const ir::Instruction* ptrInst, uint32_t valId, std::vector<std::unique_ptr<ir::Instruction>>* newInsts) { - // Build and append load of variable in ptrInst uint32_t varId; uint32_t varPteTypeId; - const uint32_t ldResultId = BuildAndAppendVarLoad(ptrInst, &varId, - &varPteTypeId, newInsts); + const uint32_t ldResultId = + BuildAndAppendVarLoad(ptrInst, &varId, &varPteTypeId, newInsts); // Build and append Insert const uint32_t insResultId = TakeNextId(); - std::vector<ir::Operand> ins_in_opnds = - {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {valId}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ldResultId}}}; + std::vector<ir::Operand> ins_in_opnds = { + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {valId}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ldResultId}}}; AppendConstantOperands(ptrInst, &ins_in_opnds); - BuildAndAppendInst( - SpvOpCompositeInsert, varPteTypeId, insResultId, ins_in_opnds, newInsts); + BuildAndAppendInst(SpvOpCompositeInsert, varPteTypeId, insResultId, + ins_in_opnds, newInsts); // Build and append Store - BuildAndAppendInst(SpvOpStore, 0, 0, - {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {varId}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {insResultId}}}, - newInsts); + BuildAndAppendInst(SpvOpStore, 0, 0, + {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {varId}}, + {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {insResultId}}}, + newInsts); } bool LocalAccessChainConvertPass::IsConstantIndexAccessChain( @@ -144,8 +137,7 @@ bool LocalAccessChainConvertPass::IsConstantIndexAccessChain( } bool LocalAccessChainConvertPass::HasOnlySupportedRefs(uint32_t ptrId) { - if (supported_ref_ptrs_.find(ptrId) != supported_ref_ptrs_.end()) - return true; + if (supported_ref_ptrs_.find(ptrId) != supported_ref_ptrs_.end()) return true; analysis::UseList* uses = get_def_use_mgr()->GetUses(ptrId); assert(uses != nullptr); for (auto u : *uses) { @@ -164,36 +156,36 @@ void LocalAccessChainConvertPass::FindTargetVars(ir::Function* func) { for (auto bi = func->begin(); bi != func->end(); ++bi) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { switch (ii->opcode()) { - case SpvOpStore: - case SpvOpLoad: { - uint32_t varId; - ir::Instruction* ptrInst = GetPtr(&*ii, &varId); - if (!IsTargetVar(varId)) - break; - const SpvOp op = ptrInst->opcode(); - // Rule out variables with non-supported refs eg function calls - if (!HasOnlySupportedRefs(varId)) { - seen_non_target_vars_.insert(varId); - seen_target_vars_.erase(varId); + case SpvOpStore: + case SpvOpLoad: { + uint32_t varId; + ir::Instruction* ptrInst = GetPtr(&*ii, &varId); + if (!IsTargetVar(varId)) break; + const SpvOp op = ptrInst->opcode(); + // Rule out variables with non-supported refs eg function calls + if (!HasOnlySupportedRefs(varId)) { + seen_non_target_vars_.insert(varId); + seen_target_vars_.erase(varId); + break; + } + // Rule out variables with nested access chains + // TODO(): Convert nested access chains + if (IsNonPtrAccessChain(op) && + ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx) != + varId) { + seen_non_target_vars_.insert(varId); + seen_target_vars_.erase(varId); + break; + } + // Rule out variables accessed with non-constant indices + if (!IsConstantIndexAccessChain(ptrInst)) { + seen_non_target_vars_.insert(varId); + seen_target_vars_.erase(varId); + break; + } + } break; + default: break; - } - // Rule out variables with nested access chains - // TODO(): Convert nested access chains - if (IsNonPtrAccessChain(op) && - ptrInst->GetSingleWordInOperand(kAccessChainPtrIdInIdx) != varId) { - seen_non_target_vars_.insert(varId); - seen_target_vars_.erase(varId); - break; - } - // Rule out variables accessed with non-constant indices - if (!IsConstantIndexAccessChain(ptrInst)) { - seen_non_target_vars_.insert(varId); - seen_target_vars_.erase(varId); - break; - } - } break; - default: - break; } } } @@ -207,42 +199,37 @@ bool LocalAccessChainConvertPass::ConvertLocalAccessChains(ir::Function* func) { for (auto bi = func->begin(); bi != func->end(); ++bi) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { switch (ii->opcode()) { - case SpvOpLoad: { - uint32_t varId; - ir::Instruction* ptrInst = GetPtr(&*ii, &varId); - if (!IsNonPtrAccessChain(ptrInst->opcode())) - break; - if (!IsTargetVar(varId)) - break; - std::vector<std::unique_ptr<ir::Instruction>> newInsts; - uint32_t replId = - GenAccessChainLoadReplacement(ptrInst, &newInsts); - ReplaceAndDeleteLoad(&*ii, replId); - ++ii; - ii = ii.InsertBefore(std::move(newInsts)); - ++ii; - modified = true; - } break; - case SpvOpStore: { - uint32_t varId; - ir::Instruction* ptrInst = GetPtr(&*ii, &varId); - if (!IsNonPtrAccessChain(ptrInst->opcode())) + case SpvOpLoad: { + uint32_t varId; + ir::Instruction* ptrInst = GetPtr(&*ii, &varId); + if (!IsNonPtrAccessChain(ptrInst->opcode())) break; + if (!IsTargetVar(varId)) break; + std::vector<std::unique_ptr<ir::Instruction>> newInsts; + uint32_t replId = GenAccessChainLoadReplacement(ptrInst, &newInsts); + ReplaceAndDeleteLoad(&*ii, replId); + ++ii; + ii = ii.InsertBefore(std::move(newInsts)); + ++ii; + modified = true; + } break; + case SpvOpStore: { + uint32_t varId; + ir::Instruction* ptrInst = GetPtr(&*ii, &varId); + if (!IsNonPtrAccessChain(ptrInst->opcode())) break; + if (!IsTargetVar(varId)) break; + std::vector<std::unique_ptr<ir::Instruction>> newInsts; + uint32_t valId = ii->GetSingleWordInOperand(kStoreValIdInIdx); + GenAccessChainStoreReplacement(ptrInst, valId, &newInsts); + context()->KillInst(&*ii); + DeleteIfUseless(ptrInst); + ++ii; + ii = ii.InsertBefore(std::move(newInsts)); + ++ii; + ++ii; + modified = true; + } break; + default: break; - if (!IsTargetVar(varId)) - break; - std::vector<std::unique_ptr<ir::Instruction>> newInsts; - uint32_t valId = ii->GetSingleWordInOperand(kStoreValIdInIdx); - GenAccessChainStoreReplacement(ptrInst, valId, &newInsts); - context()->KillInst(&*ii); - DeleteIfUseless(ptrInst); - ++ii; - ii = ii.InsertBefore(std::move(newInsts)); - ++ii; - ++ii; - modified = true; - } break; - default: - break; } } } @@ -266,8 +253,8 @@ void LocalAccessChainConvertPass::Initialize(ir::IRContext* c) { bool LocalAccessChainConvertPass::AllExtensionsSupported() const { // If any extension not in whitelist, return false for (auto& ei : get_module()->extensions()) { - const char* extName = reinterpret_cast<const char*>( - &ei.GetInOperand(0).words[0]); + const char* extName = + reinterpret_cast<const char*>(&ei.GetInOperand(0).words[0]); if (extensions_whitelist_.find(extName) == extensions_whitelist_.end()) return false; } @@ -285,11 +272,9 @@ Pass::Status LocalAccessChainConvertPass::ProcessImpl() { // support required in KillNamesAndDecorates(). // TODO(greg-lunarg): Add support for OpGroupDecorate for (auto& ai : get_module()->annotations()) - if (ai.opcode() == SpvOpGroupDecorate) - return Status::SuccessWithoutChange; + if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange; // Do not process if any disallowed extensions are enabled - if (!AllExtensionsSupported()) - return Status::SuccessWithoutChange; + if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; // Process all entry point functions. ProcessFunction pfn = [this](ir::Function* fp) { return ConvertLocalAccessChains(fp); @@ -308,32 +293,22 @@ Pass::Status LocalAccessChainConvertPass::Process(ir::IRContext* c) { void LocalAccessChainConvertPass::InitExtensions() { extensions_whitelist_.clear(); extensions_whitelist_.insert({ - "SPV_AMD_shader_explicit_vertex_parameter", - "SPV_AMD_shader_trinary_minmax", - "SPV_AMD_gcn_shader", - "SPV_KHR_shader_ballot", - "SPV_AMD_shader_ballot", - "SPV_AMD_gpu_shader_half_float", - "SPV_KHR_shader_draw_parameters", - "SPV_KHR_subgroup_vote", - "SPV_KHR_16bit_storage", - "SPV_KHR_device_group", - "SPV_KHR_multiview", - "SPV_NVX_multiview_per_view_attributes", - "SPV_NV_viewport_array2", - "SPV_NV_stereo_view_rendering", - "SPV_NV_sample_mask_override_coverage", - "SPV_NV_geometry_shader_passthrough", - "SPV_AMD_texture_gather_bias_lod", - "SPV_KHR_storage_buffer_storage_class", - // SPV_KHR_variable_pointers - // Currently do not support extended pointer expressions - "SPV_AMD_gpu_shader_int16", - "SPV_KHR_post_depth_coverage", - "SPV_KHR_shader_atomic_counter_ops", + "SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", "SPV_KHR_16bit_storage", "SPV_KHR_device_group", + "SPV_KHR_multiview", "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", "SPV_NV_stereo_view_rendering", + "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + // SPV_KHR_variable_pointers + // Currently do not support extended pointer expressions + "SPV_AMD_gpu_shader_int16", "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", }); } } // namespace opt } // namespace spvtools - diff --git a/source/opt/local_access_chain_convert_pass.h b/source/opt/local_access_chain_convert_pass.h index 07c03a44..152e71c7 100644 --- a/source/opt/local_access_chain_convert_pass.h +++ b/source/opt/local_access_chain_convert_pass.h @@ -17,7 +17,6 @@ #ifndef LIBSPIRV_OPT_LOCAL_ACCESS_CHAIN_CONVERT_PASS_H_ #define LIBSPIRV_OPT_LOCAL_ACCESS_CHAIN_CONVERT_PASS_H_ - #include <algorithm> #include <map> #include <queue> @@ -27,8 +26,8 @@ #include "basic_block.h" #include "def_use_manager.h" -#include "module.h" #include "mem_pass.h" +#include "module.h" namespace spvtools { namespace opt { @@ -59,38 +58,40 @@ class LocalAccessChainConvertPass : public MemPass { // Build instruction from |opcode|, |typeId|, |resultId|, and |in_opnds|. // Append to |newInsts|. - void BuildAndAppendInst(SpvOp opcode, uint32_t typeId, uint32_t resultId, - const std::vector<ir::Operand>& in_opnds, - std::vector<std::unique_ptr<ir::Instruction>>* newInsts); + void BuildAndAppendInst( + SpvOp opcode, uint32_t typeId, uint32_t resultId, + const std::vector<ir::Operand>& in_opnds, + std::vector<std::unique_ptr<ir::Instruction>>* newInsts); // Build load of variable in |ptrInst| and append to |newInsts|. // Return var in |varId| and its pointee type in |varPteTypeId|. - uint32_t BuildAndAppendVarLoad(const ir::Instruction* ptrInst, - uint32_t* varId, uint32_t* varPteTypeId, - std::vector<std::unique_ptr<ir::Instruction>>* newInsts); + uint32_t BuildAndAppendVarLoad( + const ir::Instruction* ptrInst, uint32_t* varId, uint32_t* varPteTypeId, + std::vector<std::unique_ptr<ir::Instruction>>* newInsts); // Append literal integer operands to |in_opnds| corresponding to constant // integer operands from access chain |ptrInst|. Assumes all indices in // access chains are OpConstant. - void AppendConstantOperands( const ir::Instruction* ptrInst, - std::vector<ir::Operand>* in_opnds); + void AppendConstantOperands(const ir::Instruction* ptrInst, + std::vector<ir::Operand>* in_opnds); // Create a load/insert/store equivalent to a store of // |valId| through (constant index) access chaing |ptrInst|. // Append to |newInsts|. - void GenAccessChainStoreReplacement(const ir::Instruction* ptrInst, - uint32_t valId, + void GenAccessChainStoreReplacement( + const ir::Instruction* ptrInst, uint32_t valId, std::vector<std::unique_ptr<ir::Instruction>>* newInsts); // For the (constant index) access chain |ptrInst|, create an // equivalent load and extract. Append to |newInsts|. - uint32_t GenAccessChainLoadReplacement(const ir::Instruction* ptrInst, + uint32_t GenAccessChainLoadReplacement( + const ir::Instruction* ptrInst, std::vector<std::unique_ptr<ir::Instruction>>* newInsts); // Return true if all indices of access chain |acp| are OpConstant integers bool IsConstantIndexAccessChain(const ir::Instruction* acp) const; - // Identify all function scope variables of target type which are + // Identify all function scope variables of target type which are // accessed only with loads, stores and access chains with constant // indices. Convert all loads and stores of such variables into equivalent // loads, stores, extracts and inserts. This unifies access to these @@ -122,4 +123,3 @@ class LocalAccessChainConvertPass : public MemPass { } // namespace spvtools #endif // LIBSPIRV_OPT_LOCAL_ACCESS_CHAIN_CONVERT_PASS_H_ - diff --git a/source/opt/local_single_block_elim_pass.cpp b/source/opt/local_single_block_elim_pass.cpp index 04916d86..8fd40238 100644 --- a/source/opt/local_single_block_elim_pass.cpp +++ b/source/opt/local_single_block_elim_pass.cpp @@ -25,11 +25,10 @@ namespace { const uint32_t kStoreValIdInIdx = 1; -} // anonymous namespace +} // anonymous namespace bool LocalSingleBlockLoadStoreElimPass::HasOnlySupportedRefs(uint32_t ptrId) { - if (supported_ref_ptrs_.find(ptrId) != supported_ref_ptrs_.end()) - return true; + if (supported_ref_ptrs_.find(ptrId) != supported_ref_ptrs_.end()) return true; analysis::UseList* uses = get_def_use_mgr()->GetUses(ptrId); assert(uses != nullptr); for (auto u : *uses) { @@ -54,83 +53,74 @@ bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim( pinned_vars_.clear(); for (auto ii = bi->begin(); ii != bi->end(); ++ii) { switch (ii->opcode()) { - case SpvOpStore: { - // Verify store variable is target type - uint32_t varId; - ir::Instruction* ptrInst = GetPtr(&*ii, &varId); - if (!IsTargetVar(varId)) - continue; - if (!HasOnlySupportedRefs(varId)) - continue; - // Register the store - if (ptrInst->opcode() == SpvOpVariable) { - // if not pinned, look for WAW - if (pinned_vars_.find(varId) == pinned_vars_.end()) { + case SpvOpStore: { + // Verify store variable is target type + uint32_t varId; + ir::Instruction* ptrInst = GetPtr(&*ii, &varId); + if (!IsTargetVar(varId)) continue; + if (!HasOnlySupportedRefs(varId)) continue; + // Register the store + if (ptrInst->opcode() == SpvOpVariable) { + // if not pinned, look for WAW + if (pinned_vars_.find(varId) == pinned_vars_.end()) { + auto si = var2store_.find(varId); + if (si != var2store_.end()) { + context()->KillInst(si->second); + } + } + var2store_[varId] = &*ii; + } else { + assert(IsNonPtrAccessChain(ptrInst->opcode())); + var2store_.erase(varId); + } + pinned_vars_.erase(varId); + var2load_.erase(varId); + } break; + case SpvOpLoad: { + // Verify store variable is target type + uint32_t varId; + ir::Instruction* ptrInst = GetPtr(&*ii, &varId); + if (!IsTargetVar(varId)) continue; + if (!HasOnlySupportedRefs(varId)) continue; + // Look for previous store or load + uint32_t replId = 0; + if (ptrInst->opcode() == SpvOpVariable) { auto si = var2store_.find(varId); if (si != var2store_.end()) { - context()->KillInst(si->second); + replId = si->second->GetSingleWordInOperand(kStoreValIdInIdx); + } else { + auto li = var2load_.find(varId); + if (li != var2load_.end()) { + replId = li->second->result_id(); + } } } - var2store_[varId] = &*ii; - } - else { - assert(IsNonPtrAccessChain(ptrInst->opcode())); - var2store_.erase(varId); - } - pinned_vars_.erase(varId); - var2load_.erase(varId); - } break; - case SpvOpLoad: { - // Verify store variable is target type - uint32_t varId; - ir::Instruction* ptrInst = GetPtr(&*ii, &varId); - if (!IsTargetVar(varId)) - continue; - if (!HasOnlySupportedRefs(varId)) - continue; - // Look for previous store or load - uint32_t replId = 0; - if (ptrInst->opcode() == SpvOpVariable) { - auto si = var2store_.find(varId); - if (si != var2store_.end()) { - replId = si->second->GetSingleWordInOperand(kStoreValIdInIdx); + if (replId != 0) { + // replace load's result id and delete load + ReplaceAndDeleteLoad(&*ii, replId); + modified = true; + } else { + if (ptrInst->opcode() == SpvOpVariable) + var2load_[varId] = &*ii; // register load + pinned_vars_.insert(varId); } - else { - auto li = var2load_.find(varId); - if (li != var2load_.end()) { - replId = li->second->result_id(); - } - } - } - if (replId != 0) { - // replace load's result id and delete load - ReplaceAndDeleteLoad(&*ii, replId); - modified = true; - } - else { - if (ptrInst->opcode() == SpvOpVariable) - var2load_[varId] = &*ii; // register load - pinned_vars_.insert(varId); - } - } break; - case SpvOpFunctionCall: { - // Conservatively assume all locals are redefined for now. - // TODO(): Handle more optimally - var2store_.clear(); - var2load_.clear(); - pinned_vars_.clear(); - } break; - default: - break; + } break; + case SpvOpFunctionCall: { + // Conservatively assume all locals are redefined for now. + // TODO(): Handle more optimally + var2store_.clear(); + var2load_.clear(); + pinned_vars_.clear(); + } break; + default: + break; } } // Go back and delete useless stores in block // TODO(greg-lunarg): Consider moving DCE into separate pass for (auto ii = bi->begin(); ii != bi->end(); ++ii) { - if (ii->opcode() != SpvOpStore) - continue; - if (IsLiveStore(&*ii)) - continue; + if (ii->opcode() != SpvOpStore) continue; + if (IsLiveStore(&*ii)) continue; DCEInst(&*ii); } } @@ -154,8 +144,8 @@ void LocalSingleBlockLoadStoreElimPass::Initialize(ir::IRContext* c) { bool LocalSingleBlockLoadStoreElimPass::AllExtensionsSupported() const { // If any extension not in whitelist, return false for (auto& ei : get_module()->extensions()) { - const char* extName = reinterpret_cast<const char*>( - &ei.GetInOperand(0).words[0]); + const char* extName = + reinterpret_cast<const char*>(&ei.GetInOperand(0).words[0]); if (extensions_whitelist_.find(extName) == extensions_whitelist_.end()) return false; } @@ -170,12 +160,10 @@ Pass::Status LocalSingleBlockLoadStoreElimPass::ProcessImpl() { // support required in KillNamesAndDecorates(). // TODO(greg-lunarg): Add support for OpGroupDecorate for (auto& ai : get_module()->annotations()) - if (ai.opcode() == SpvOpGroupDecorate) - return Status::SuccessWithoutChange; + if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange; // If any extensions in the module are not explicitly supported, - // return unmodified. - if (!AllExtensionsSupported()) - return Status::SuccessWithoutChange; + // return unmodified. + if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; // Process all entry point functions ProcessFunction pfn = [this](ir::Function* fp) { return LocalSingleBlockLoadStoreElim(fp); @@ -194,29 +182,20 @@ Pass::Status LocalSingleBlockLoadStoreElimPass::Process(ir::IRContext* c) { void LocalSingleBlockLoadStoreElimPass::InitExtensions() { extensions_whitelist_.clear(); extensions_whitelist_.insert({ - "SPV_AMD_shader_explicit_vertex_parameter", - "SPV_AMD_shader_trinary_minmax", - "SPV_AMD_gcn_shader", - "SPV_KHR_shader_ballot", - "SPV_AMD_shader_ballot", - "SPV_AMD_gpu_shader_half_float", - "SPV_KHR_shader_draw_parameters", - "SPV_KHR_subgroup_vote", - "SPV_KHR_16bit_storage", - "SPV_KHR_device_group", - "SPV_KHR_multiview", - "SPV_NVX_multiview_per_view_attributes", - "SPV_NV_viewport_array2", - "SPV_NV_stereo_view_rendering", - "SPV_NV_sample_mask_override_coverage", - "SPV_NV_geometry_shader_passthrough", - "SPV_AMD_texture_gather_bias_lod", - "SPV_KHR_storage_buffer_storage_class", - // SPV_KHR_variable_pointers - // Currently do not support extended pointer expressions - "SPV_AMD_gpu_shader_int16", - "SPV_KHR_post_depth_coverage", - "SPV_KHR_shader_atomic_counter_ops", + "SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", "SPV_KHR_16bit_storage", "SPV_KHR_device_group", + "SPV_KHR_multiview", "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", "SPV_NV_stereo_view_rendering", + "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + // SPV_KHR_variable_pointers + // Currently do not support extended pointer expressions + "SPV_AMD_gpu_shader_int16", "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", }); } diff --git a/source/opt/local_single_block_elim_pass.h b/source/opt/local_single_block_elim_pass.h index f178304d..5ceb3784 100644 --- a/source/opt/local_single_block_elim_pass.h +++ b/source/opt/local_single_block_elim_pass.h @@ -17,18 +17,17 @@ #ifndef LIBSPIRV_OPT_LOCAL_SINGLE_BLOCK_ELIM_PASS_H_ #define LIBSPIRV_OPT_LOCAL_SINGLE_BLOCK_ELIM_PASS_H_ - #include <algorithm> #include <map> #include <queue> -#include <utility> #include <unordered_map> #include <unordered_set> +#include <utility> #include "basic_block.h" #include "def_use_manager.h" -#include "module.h" #include "mem_pass.h" +#include "module.h" namespace spvtools { namespace opt { @@ -98,4 +97,3 @@ class LocalSingleBlockLoadStoreElimPass : public MemPass { } // namespace spvtools #endif // LIBSPIRV_OPT_LOCAL_SINGLE_BLOCK_ELIM_PASS_H_ - diff --git a/source/opt/local_single_store_elim_pass.cpp b/source/opt/local_single_store_elim_pass.cpp index 83f6f3a8..e3a00ba9 100644 --- a/source/opt/local_single_store_elim_pass.cpp +++ b/source/opt/local_single_store_elim_pass.cpp @@ -27,11 +27,10 @@ namespace { const uint32_t kStoreValIdInIdx = 1; -} // anonymous namespace +} // anonymous namespace bool LocalSingleStoreElimPass::HasOnlySupportedRefs(uint32_t ptrId) { - if (supported_ref_ptrs_.find(ptrId) != supported_ref_ptrs_.end()) - return true; + if (supported_ref_ptrs_.find(ptrId) != supported_ref_ptrs_.end()) return true; analysis::UseList* uses = get_def_use_mgr()->GetUses(ptrId); assert(uses != nullptr); for (auto u : *uses) { @@ -55,41 +54,40 @@ void LocalSingleStoreElimPass::SingleStoreAnalyze(ir::Function* func) { uint32_t instIdx = 0; for (auto ii = bi->begin(); ii != bi->end(); ++ii, ++instIdx) { switch (ii->opcode()) { - case SpvOpStore: { - // Verify store variable is target type - uint32_t varId; - ir::Instruction* ptrInst = GetPtr(&*ii, &varId); - if (non_ssa_vars_.find(varId) != non_ssa_vars_.end()) - continue; - if (ptrInst->opcode() != SpvOpVariable) { - non_ssa_vars_.insert(varId); - ssa_var2store_.erase(varId); - continue; - } - // Verify target type and function storage class - if (!IsTargetVar(varId)) { - non_ssa_vars_.insert(varId); - continue; - } - if (!HasOnlySupportedRefs(varId)) { - non_ssa_vars_.insert(varId); - continue; - } - // Ignore variables with multiple stores - if (ssa_var2store_.find(varId) != ssa_var2store_.end()) { - non_ssa_vars_.insert(varId); - ssa_var2store_.erase(varId); - continue; - } - // Remember pointer to variable's store and it's - // ordinal position in block - ssa_var2store_[varId] = &*ii; - store2idx_[&*ii] = instIdx; - store2blk_[&*ii] = &*bi; - } break; - default: - break; - } // switch + case SpvOpStore: { + // Verify store variable is target type + uint32_t varId; + ir::Instruction* ptrInst = GetPtr(&*ii, &varId); + if (non_ssa_vars_.find(varId) != non_ssa_vars_.end()) continue; + if (ptrInst->opcode() != SpvOpVariable) { + non_ssa_vars_.insert(varId); + ssa_var2store_.erase(varId); + continue; + } + // Verify target type and function storage class + if (!IsTargetVar(varId)) { + non_ssa_vars_.insert(varId); + continue; + } + if (!HasOnlySupportedRefs(varId)) { + non_ssa_vars_.insert(varId); + continue; + } + // Ignore variables with multiple stores + if (ssa_var2store_.find(varId) != ssa_var2store_.end()) { + non_ssa_vars_.insert(varId); + ssa_var2store_.erase(varId); + continue; + } + // Remember pointer to variable's store and it's + // ordinal position in block + ssa_var2store_[varId] = &*ii; + store2idx_[&*ii] = instIdx; + store2blk_[&*ii] = &*bi; + } break; + default: + break; + } // switch } } } @@ -98,8 +96,7 @@ LocalSingleStoreElimPass::GetBlocksFunction LocalSingleStoreElimPass::AugmentedCFGSuccessorsFunction() const { return [this](const ir::BasicBlock* block) { auto asmi = augmented_successors_map_.find(block); - if (asmi != augmented_successors_map_.end()) - return &(*asmi).second; + if (asmi != augmented_successors_map_.end()) return &(*asmi).second; auto smi = successors_map_.find(block); return &(*smi).second; }; @@ -109,8 +106,7 @@ LocalSingleStoreElimPass::GetBlocksFunction LocalSingleStoreElimPass::AugmentedCFGPredecessorsFunction() const { return [this](const ir::BasicBlock* block) { auto apmi = augmented_predecessors_map_.find(block); - if (apmi != augmented_predecessors_map_.end()) - return &(*apmi).second; + if (apmi != augmented_predecessors_map_.end()) return &(*apmi).second; auto pmi = predecessors_map_.find(block); return &(*pmi).second; }; @@ -134,43 +130,36 @@ void LocalSingleStoreElimPass::CalculateImmediateDominators( augmented_predecessors_map_.clear(); successors_map_[cfg()->pseudo_exit_block()] = {}; predecessors_map_[cfg()->pseudo_entry_block()] = {}; - auto succ_func = [this](const ir::BasicBlock* b) - { return &successors_map_[b]; }; - auto pred_func = [this](const ir::BasicBlock* b) - { return &predecessors_map_[b]; }; + auto succ_func = [this](const ir::BasicBlock* b) { + return &successors_map_[b]; + }; + auto pred_func = [this](const ir::BasicBlock* b) { + return &predecessors_map_[b]; + }; CFA<ir::BasicBlock>::ComputeAugmentedCFG( - ordered_blocks, - cfg()->pseudo_entry_block(), - cfg()->pseudo_exit_block(), - &augmented_successors_map_, - &augmented_predecessors_map_, - succ_func, - pred_func); + ordered_blocks, cfg()->pseudo_entry_block(), cfg()->pseudo_exit_block(), + &augmented_successors_map_, &augmented_predecessors_map_, succ_func, + pred_func); // Compute Dominators vector<const ir::BasicBlock*> postorder; auto ignore_block = [](cbb_ptr) {}; auto ignore_edge = [](cbb_ptr, cbb_ptr) {}; spvtools::CFA<ir::BasicBlock>::DepthFirstTraversal( - ordered_blocks[0], AugmentedCFGSuccessorsFunction(), - ignore_block, [&](cbb_ptr b) { postorder.push_back(b); }, - ignore_edge); + ordered_blocks[0], AugmentedCFGSuccessorsFunction(), ignore_block, + [&](cbb_ptr b) { postorder.push_back(b); }, ignore_edge); auto edges = spvtools::CFA<ir::BasicBlock>::CalculateDominators( - postorder, AugmentedCFGPredecessorsFunction()); + postorder, AugmentedCFGPredecessorsFunction()); idom_.clear(); - for (auto edge : edges) - idom_[edge.first] = edge.second; + for (auto edge : edges) idom_[edge.first] = edge.second; } -bool LocalSingleStoreElimPass::Dominates( - ir::BasicBlock* blk0, uint32_t idx0, - ir::BasicBlock* blk1, uint32_t idx1) { - if (blk0 == blk1) - return idx0 <= idx1; +bool LocalSingleStoreElimPass::Dominates(ir::BasicBlock* blk0, uint32_t idx0, + ir::BasicBlock* blk1, uint32_t idx1) { + if (blk0 == blk1) return idx0 <= idx1; ir::BasicBlock* b = blk1; while (idom_[b] != b) { b = idom_[b]; - if (b == blk0) - return true; + if (b == blk0) return true; } return false; } @@ -181,20 +170,17 @@ bool LocalSingleStoreElimPass::SingleStoreProcess(ir::Function* func) { for (auto bi = func->begin(); bi != func->end(); ++bi) { uint32_t instIdx = 0; for (auto ii = bi->begin(); ii != bi->end(); ++ii, ++instIdx) { - if (ii->opcode() != SpvOpLoad) - continue; + if (ii->opcode() != SpvOpLoad) continue; uint32_t varId; ir::Instruction* ptrInst = GetPtr(&*ii, &varId); // Skip access chain loads - if (ptrInst->opcode() != SpvOpVariable) - continue; + if (ptrInst->opcode() != SpvOpVariable) continue; const auto vsi = ssa_var2store_.find(varId); - if (vsi == ssa_var2store_.end()) - continue; - if (non_ssa_vars_.find(varId) != non_ssa_vars_.end()) - continue; + if (vsi == ssa_var2store_.end()) continue; + if (non_ssa_vars_.find(varId) != non_ssa_vars_.end()) continue; // store must dominate load - if (!Dominates(store2blk_[vsi->second], store2idx_[vsi->second], &*bi, instIdx)) + if (!Dominates(store2blk_[vsi->second], store2idx_[vsi->second], &*bi, + instIdx)) continue; // Use store value as replacement id uint32_t replId = vsi->second->GetSingleWordInOperand(kStoreValIdInIdx); @@ -210,10 +196,8 @@ bool LocalSingleStoreElimPass::SingleStoreDCE() { bool modified = false; for (auto v : ssa_var2store_) { // check that it hasn't already been DCE'd - if (v.second->opcode() != SpvOpStore) - continue; - if (non_ssa_vars_.find(v.first) != non_ssa_vars_.end()) - continue; + if (v.second->opcode() != SpvOpStore) continue; + if (non_ssa_vars_.find(v.first) != non_ssa_vars_.end()) continue; if (!IsLiveStore(v.second)) { DCEInst(v.second); modified = true; @@ -225,8 +209,7 @@ bool LocalSingleStoreElimPass::SingleStoreDCE() { bool LocalSingleStoreElimPass::LocalSingleStoreElim(ir::Function* func) { bool modified = false; SingleStoreAnalyze(func); - if (ssa_var2store_.empty()) - return false; + if (ssa_var2store_.empty()) return false; modified |= SingleStoreProcess(func); modified |= SingleStoreDCE(); return modified; @@ -258,8 +241,8 @@ void LocalSingleStoreElimPass::Initialize(ir::IRContext* irContext) { bool LocalSingleStoreElimPass::AllExtensionsSupported() const { // If any extension not in whitelist, return false for (auto& ei : get_module()->extensions()) { - const char* extName = reinterpret_cast<const char*>( - &ei.GetInOperand(0).words[0]); + const char* extName = + reinterpret_cast<const char*>(&ei.GetInOperand(0).words[0]); if (extensions_whitelist_.find(extName) == extensions_whitelist_.end()) return false; } @@ -274,11 +257,9 @@ Pass::Status LocalSingleStoreElimPass::ProcessImpl() { // support required in KillNamesAndDecorates(). // TODO(greg-lunarg): Add support for OpGroupDecorate for (auto& ai : get_module()->annotations()) - if (ai.opcode() == SpvOpGroupDecorate) - return Status::SuccessWithoutChange; + if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange; // Do not process if any disallowed extensions are enabled - if (!AllExtensionsSupported()) - return Status::SuccessWithoutChange; + if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; // Process all entry point functions ProcessFunction pfn = [this](ir::Function* fp) { return LocalSingleStoreElim(fp); @@ -297,29 +278,20 @@ Pass::Status LocalSingleStoreElimPass::Process(ir::IRContext* irContext) { void LocalSingleStoreElimPass::InitExtensions() { extensions_whitelist_.clear(); extensions_whitelist_.insert({ - "SPV_AMD_shader_explicit_vertex_parameter", - "SPV_AMD_shader_trinary_minmax", - "SPV_AMD_gcn_shader", - "SPV_KHR_shader_ballot", - "SPV_AMD_shader_ballot", - "SPV_AMD_gpu_shader_half_float", - "SPV_KHR_shader_draw_parameters", - "SPV_KHR_subgroup_vote", - "SPV_KHR_16bit_storage", - "SPV_KHR_device_group", - "SPV_KHR_multiview", - "SPV_NVX_multiview_per_view_attributes", - "SPV_NV_viewport_array2", - "SPV_NV_stereo_view_rendering", - "SPV_NV_sample_mask_override_coverage", - "SPV_NV_geometry_shader_passthrough", - "SPV_AMD_texture_gather_bias_lod", - "SPV_KHR_storage_buffer_storage_class", - // SPV_KHR_variable_pointers - // Currently do not support extended pointer expressions - "SPV_AMD_gpu_shader_int16", - "SPV_KHR_post_depth_coverage", - "SPV_KHR_shader_atomic_counter_ops", + "SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", "SPV_KHR_16bit_storage", "SPV_KHR_device_group", + "SPV_KHR_multiview", "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", "SPV_NV_stereo_view_rendering", + "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + // SPV_KHR_variable_pointers + // Currently do not support extended pointer expressions + "SPV_AMD_gpu_shader_int16", "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", }); } diff --git a/source/opt/local_single_store_elim_pass.h b/source/opt/local_single_store_elim_pass.h index e3aff0d1..1d0f1ff9 100644 --- a/source/opt/local_single_store_elim_pass.h +++ b/source/opt/local_single_store_elim_pass.h @@ -17,7 +17,6 @@ #ifndef LIBSPIRV_OPT_LOCAL_SINGLE_STORE_ELIM_PASS_H_ #define LIBSPIRV_OPT_LOCAL_SINGLE_STORE_ELIM_PASS_H_ - #include <algorithm> #include <map> #include <queue> @@ -27,8 +26,8 @@ #include "basic_block.h" #include "def_use_manager.h" -#include "module.h" #include "mem_pass.h" +#include "module.h" namespace spvtools { namespace opt { @@ -58,7 +57,7 @@ class LocalSingleStoreElimPass : public MemPass { void SingleStoreAnalyze(ir::Function* func); using GetBlocksFunction = - std::function<const std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>; + std::function<const std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>; /// Returns the block successors function for the augmented CFG. GetBlocksFunction AugmentedCFGSuccessorsFunction() const; @@ -70,11 +69,11 @@ class LocalSingleStoreElimPass : public MemPass { // in idom_. Entries for augmented CFG (pseudo blocks) are not created. // TODO(dnovillo): Move to new CFG class. void CalculateImmediateDominators(ir::Function* func); - + // Return true if instruction in |blk0| at ordinal position |idx0| // dominates instruction in |blk1| at position |idx1|. - bool Dominates(ir::BasicBlock* blk0, uint32_t idx0, - ir::BasicBlock* blk1, uint32_t idx1); + bool Dominates(ir::BasicBlock* blk0, uint32_t idx0, ir::BasicBlock* blk1, + uint32_t idx1); // For each load of an SSA variable in |func|, replace all uses of // the load with the value stored if the store dominates the load. @@ -123,19 +122,19 @@ class LocalSingleStoreElimPass : public MemPass { // CFG Predecessors std::unordered_map<const ir::BasicBlock*, std::vector<ir::BasicBlock*>> - predecessors_map_; + predecessors_map_; // CFG Successors std::unordered_map<const ir::BasicBlock*, std::vector<ir::BasicBlock*>> - successors_map_; + successors_map_; // CFG Augmented Predecessors std::unordered_map<const ir::BasicBlock*, std::vector<ir::BasicBlock*>> - augmented_predecessors_map_; + augmented_predecessors_map_; // CFG Augmented Successors std::unordered_map<const ir::BasicBlock*, std::vector<ir::BasicBlock*>> - augmented_successors_map_; + augmented_successors_map_; // Immediate Dominator Map // If block has no idom it points to itself. @@ -149,4 +148,3 @@ class LocalSingleStoreElimPass : public MemPass { } // namespace spvtools #endif // LIBSPIRV_OPT_LOCAL_SINGLE_STORE_ELIM_PASS_H_ - diff --git a/source/opt/local_ssa_elim_pass.cpp b/source/opt/local_ssa_elim_pass.cpp index 1ec7db58..f0aaee7d 100644 --- a/source/opt/local_ssa_elim_pass.cpp +++ b/source/opt/local_ssa_elim_pass.cpp @@ -16,27 +16,24 @@ #include "local_ssa_elim_pass.h" -#include "iterator.h" #include "cfa.h" +#include "iterator.h" namespace spvtools { namespace opt { bool LocalMultiStoreElimPass::EliminateMultiStoreLocal(ir::Function* func) { // Add Phi instructions to the function. - if (InsertPhiInstructions(func) == Status::SuccessWithoutChange) - return false; + if (InsertPhiInstructions(func) == Status::SuccessWithoutChange) return false; // Remove all target variable stores. bool modified = false; for (auto bi = func->begin(); bi != func->end(); ++bi) { for (auto ii = bi->begin(); ii != bi->end(); ++ii) { - if (ii->opcode() != SpvOpStore) - continue; + if (ii->opcode() != SpvOpStore) continue; uint32_t varId; - (void) GetPtr(&*ii, &varId); - if (!IsTargetVar(varId)) - continue; + (void)GetPtr(&*ii, &varId); + if (!IsTargetVar(varId)) continue; assert(!HasLoads(varId)); DCEInst(&*ii); modified = true; @@ -56,8 +53,8 @@ void LocalMultiStoreElimPass::Initialize(ir::IRContext* c) { bool LocalMultiStoreElimPass::AllExtensionsSupported() const { // If any extension not in whitelist, return false for (auto& ei : get_module()->extensions()) { - const char* extName = reinterpret_cast<const char*>( - &ei.GetInOperand(0).words[0]); + const char* extName = + reinterpret_cast<const char*>(&ei.GetInOperand(0).words[0]); if (extensions_whitelist_.find(extName) == extensions_whitelist_.end()) return false; } @@ -76,12 +73,10 @@ Pass::Status LocalMultiStoreElimPass::ProcessImpl() { // Do not process if module contains OpGroupDecorate. Additional // support required in KillNamesAndDecorates(). // TODO(greg-lunarg): Add support for OpGroupDecorate - for (auto& ai : get_module()->annotations()) - if (ai.opcode() == SpvOpGroupDecorate) - return Status::SuccessWithoutChange; + for (auto& ai : get_module()->annotations()) + if (ai.opcode() == SpvOpGroupDecorate) return Status::SuccessWithoutChange; // Do not process if any disallowed extensions are enabled - if (!AllExtensionsSupported()) - return Status::SuccessWithoutChange; + if (!AllExtensionsSupported()) return Status::SuccessWithoutChange; // Process functions ProcessFunction pfn = [this](ir::Function* fp) { return EliminateMultiStoreLocal(fp); @@ -100,32 +95,22 @@ Pass::Status LocalMultiStoreElimPass::Process(ir::IRContext* c) { void LocalMultiStoreElimPass::InitExtensions() { extensions_whitelist_.clear(); extensions_whitelist_.insert({ - "SPV_AMD_shader_explicit_vertex_parameter", - "SPV_AMD_shader_trinary_minmax", - "SPV_AMD_gcn_shader", - "SPV_KHR_shader_ballot", - "SPV_AMD_shader_ballot", - "SPV_AMD_gpu_shader_half_float", - "SPV_KHR_shader_draw_parameters", - "SPV_KHR_subgroup_vote", - "SPV_KHR_16bit_storage", - "SPV_KHR_device_group", - "SPV_KHR_multiview", - "SPV_NVX_multiview_per_view_attributes", - "SPV_NV_viewport_array2", - "SPV_NV_stereo_view_rendering", - "SPV_NV_sample_mask_override_coverage", - "SPV_NV_geometry_shader_passthrough", - "SPV_AMD_texture_gather_bias_lod", - "SPV_KHR_storage_buffer_storage_class", - // SPV_KHR_variable_pointers - // Currently do not support extended pointer expressions - "SPV_AMD_gpu_shader_int16", - "SPV_KHR_post_depth_coverage", - "SPV_KHR_shader_atomic_counter_ops", + "SPV_AMD_shader_explicit_vertex_parameter", + "SPV_AMD_shader_trinary_minmax", "SPV_AMD_gcn_shader", + "SPV_KHR_shader_ballot", "SPV_AMD_shader_ballot", + "SPV_AMD_gpu_shader_half_float", "SPV_KHR_shader_draw_parameters", + "SPV_KHR_subgroup_vote", "SPV_KHR_16bit_storage", "SPV_KHR_device_group", + "SPV_KHR_multiview", "SPV_NVX_multiview_per_view_attributes", + "SPV_NV_viewport_array2", "SPV_NV_stereo_view_rendering", + "SPV_NV_sample_mask_override_coverage", + "SPV_NV_geometry_shader_passthrough", "SPV_AMD_texture_gather_bias_lod", + "SPV_KHR_storage_buffer_storage_class", + // SPV_KHR_variable_pointers + // Currently do not support extended pointer expressions + "SPV_AMD_gpu_shader_int16", "SPV_KHR_post_depth_coverage", + "SPV_KHR_shader_atomic_counter_ops", }); } } // namespace opt } // namespace spvtools - diff --git a/source/opt/local_ssa_elim_pass.h b/source/opt/local_ssa_elim_pass.h index 65177bbf..ae293be0 100644 --- a/source/opt/local_ssa_elim_pass.h +++ b/source/opt/local_ssa_elim_pass.h @@ -17,18 +17,17 @@ #ifndef LIBSPIRV_OPT_LOCAL_SSA_ELIM_PASS_H_ #define LIBSPIRV_OPT_LOCAL_SSA_ELIM_PASS_H_ - #include <algorithm> #include <map> #include <queue> -#include <utility> #include <unordered_map> #include <unordered_set> +#include <utility> #include "basic_block.h" #include "def_use_manager.h" -#include "module.h" #include "mem_pass.h" +#include "module.h" namespace spvtools { namespace opt { @@ -38,8 +37,8 @@ class LocalMultiStoreElimPass : public MemPass { using cbb_ptr = const ir::BasicBlock*; public: - using GetBlocksFunction = - std::function<std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>; + using GetBlocksFunction = + std::function<std::vector<ir::BasicBlock*>*(const ir::BasicBlock*)>; LocalMultiStoreElimPass(); const char* name() const override { return "eliminate-local-multi-store"; } @@ -70,4 +69,3 @@ class LocalMultiStoreElimPass : public MemPass { } // namespace spvtools #endif // LIBSPIRV_OPT_LOCAL_SSA_ELIM_PASS_H_ - diff --git a/source/opt/mem_pass.cpp b/source/opt/mem_pass.cpp index c4bfd127..3affc484 100644 --- a/source/opt/mem_pass.cpp +++ b/source/opt/mem_pass.cpp @@ -626,7 +626,8 @@ Pass::Status MemPass::InsertPhiInstructions(ir::Function* func) { } // If variable is not defined, use undef if (replId == 0) { - replId = Type2Undef(GetPointeeTypeId(get_def_use_mgr()->GetDef(varId))); + replId = + Type2Undef(GetPointeeTypeId(get_def_use_mgr()->GetDef(varId))); } // Replace load's id with the last stored value id for variable // and delete load. Kill any names or decorates using id before @@ -720,7 +721,7 @@ void MemPass::RemovePhiOperands( assert(i % 2 == 0 && i < phi->NumOperands() - 1 && "malformed Phi arguments"); - ir::BasicBlock *in_block = cfg()->block(phi->GetSingleWordOperand(i + 1)); + ir::BasicBlock* in_block = cfg()->block(phi->GetSingleWordOperand(i + 1)); if (reachable_blocks.find(in_block) == reachable_blocks.end()) { // If the incoming block is unreachable, remove both operands as this // means that the |phi| has lost an incoming edge. @@ -730,7 +731,7 @@ void MemPass::RemovePhiOperands( // In all other cases, the operand must be kept but may need to be changed. uint32_t arg_id = phi->GetSingleWordOperand(i); - ir::BasicBlock *def_block = def_block_[arg_id]; + ir::BasicBlock* def_block = def_block_[arg_id]; if (def_block && reachable_blocks.find(def_block_[arg_id]) == reachable_blocks.end()) { // If the current |phi| argument was defined in an unreachable block, it @@ -824,10 +825,8 @@ bool MemPass::RemoveUnreachableBlocks(ir::Function* func) { // If the block is reachable and has Phi instructions, remove all // operands from its Phi instructions that reference unreachable blocks. // If the block has no Phi instructions, this is a no-op. - block.ForEachPhiInst( - [&block, &reachable_blocks, this](ir::Instruction* phi) { - RemovePhiOperands(phi, reachable_blocks); - }); + block.ForEachPhiInst([&block, &reachable_blocks, this]( + ir::Instruction* phi) { RemovePhiOperands(phi, reachable_blocks); }); } // Erase unreachable blocks. @@ -869,4 +868,3 @@ void MemPass::InitializeCFGCleanup(ir::IRContext* c) { } // namespace opt } // namespace spvtools - diff --git a/source/opt/mem_pass.h b/source/opt/mem_pass.h index a9fd36fa..29beeccd 100644 --- a/source/opt/mem_pass.h +++ b/source/opt/mem_pass.h @@ -242,4 +242,3 @@ class MemPass : public Pass { } // namespace spvtools #endif // LIBSPIRV_OPT_OPT_PASS_H_ - diff --git a/source/opt/module.h b/source/opt/module.h index 1719832d..e4c03e27 100644 --- a/source/opt/module.h +++ b/source/opt/module.h @@ -323,7 +323,7 @@ inline IteratorRange<Module::inst_iterator> Module::ext_inst_imports() { } inline IteratorRange<Module::const_inst_iterator> Module::ext_inst_imports() -const { + const { return make_range(ext_inst_imports_.begin(), ext_inst_imports_.end()); } @@ -380,7 +380,7 @@ inline IteratorRange<Module::inst_iterator> Module::execution_modes() { } inline IteratorRange<Module::const_inst_iterator> Module::execution_modes() -const { + const { return make_range(execution_modes_.begin(), execution_modes_.end()); } diff --git a/source/opt/null_pass.h b/source/opt/null_pass.h index 4685f66c..54ea06e3 100644 --- a/source/opt/null_pass.h +++ b/source/opt/null_pass.h @@ -25,7 +25,9 @@ namespace opt { class NullPass : public Pass { public: const char* name() const override { return "null"; } - Status Process(ir::IRContext*) override { return Status::SuccessWithoutChange; } + Status Process(ir::IRContext*) override { + return Status::SuccessWithoutChange; + } }; } // namespace opt diff --git a/source/opt/pass.h b/source/opt/pass.h index 9b231d6c..e11d6e43 100644 --- a/source/opt/pass.h +++ b/source/opt/pass.h @@ -87,7 +87,7 @@ class Pass { // Returns a pointer to the CFG for current module. TODO(dnovillo): This // should belong in IRContext. - ir::CFG *cfg() const { return cfg_.get(); } + ir::CFG* cfg() const { return cfg_.get(); } // Add to |todo| all ids of functions called in |func|. void AddCalls(ir::Function* func, std::queue<uint32_t>* todo); @@ -111,8 +111,8 @@ class Pass { const std::unordered_map<uint32_t, ir::Function*>& id2function, std::queue<uint32_t>* roots); - - // Run the pass on the given |module|. Returns Status::Failure if errors occur when + // Run the pass on the given |module|. Returns Status::Failure if errors occur + // when // processing. Returns the corresponding Status::Success if processing is // successful to indicate whether changes are made to the module. If there // were any changes it will also invalidate the analyses in the IRContext diff --git a/source/opt/pass_manager.h b/source/opt/pass_manager.h index 1193f5dd..7b1ef9df 100644 --- a/source/opt/pass_manager.h +++ b/source/opt/pass_manager.h @@ -22,8 +22,8 @@ #include "module.h" #include "pass.h" -#include "spirv-tools/libspirv.hpp" #include "ir_context.h" +#include "spirv-tools/libspirv.hpp" namespace spvtools { namespace opt { diff --git a/source/opt/passes.h b/source/opt/passes.h index 657f4945..ef01b487 100644 --- a/source/opt/passes.h +++ b/source/opt/passes.h @@ -17,6 +17,7 @@ // A single header to include all passes. +#include "aggressive_dead_code_elim_pass.h" #include "block_merge_pass.h" #include "cfg_cleanup_pass.h" #include "common_uniform_elim_pass.h" @@ -24,22 +25,21 @@ #include "dead_branch_elim_pass.h" #include "dead_variable_elimination.h" #include "eliminate_dead_constant_pass.h" +#include "eliminate_dead_functions_pass.h" #include "flatten_decoration_pass.h" #include "fold_spec_constant_op_and_composite_pass.h" +#include "freeze_spec_constant_value_pass.h" #include "inline_exhaustive_pass.h" #include "inline_opaque_pass.h" #include "insert_extract_elim.h" +#include "local_access_chain_convert_pass.h" #include "local_single_block_elim_pass.h" #include "local_single_store_elim_pass.h" #include "local_ssa_elim_pass.h" -#include "freeze_spec_constant_value_pass.h" -#include "local_access_chain_convert_pass.h" -#include "aggressive_dead_code_elim_pass.h" #include "null_pass.h" #include "set_spec_constant_default_value_pass.h" #include "strength_reduction_pass.h" #include "strip_debug_info_pass.h" #include "unify_const_pass.h" -#include "eliminate_dead_functions_pass.h" #endif // LIBSPIRV_OPT_PASSES_H_ diff --git a/source/opt/remove_duplicates_pass.cpp b/source/opt/remove_duplicates_pass.cpp index 3ee78f4d..6bb62120 100644 --- a/source/opt/remove_duplicates_pass.cpp +++ b/source/opt/remove_duplicates_pass.cpp @@ -23,8 +23,8 @@ #include <vector> #include "decoration_manager.h" -#include "opcode.h" #include "ir_context.h" +#include "opcode.h" namespace spvtools { namespace opt { @@ -46,11 +46,13 @@ Pass::Status RemoveDuplicatesPass::Process(ir::IRContext* irContext) { return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; } -bool RemoveDuplicatesPass::RemoveDuplicateCapabilities(ir::IRContext* irContext) const { +bool RemoveDuplicatesPass::RemoveDuplicateCapabilities( + ir::IRContext* irContext) const { bool modified = false; std::unordered_set<uint32_t> capabilities; - for (auto i = irContext->capability_begin(); i != irContext->capability_end();) { + for (auto i = irContext->capability_begin(); + i != irContext->capability_end();) { auto res = capabilities.insert(i->GetSingleWordOperand(0u)); if (res.second) { @@ -66,8 +68,8 @@ bool RemoveDuplicatesPass::RemoveDuplicateCapabilities(ir::IRContext* irContext) return modified; } -bool -RemoveDuplicatesPass::RemoveDuplicatesExtInstImports(ir::IRContext* irContext) const { +bool RemoveDuplicatesPass::RemoveDuplicatesExtInstImports( + ir::IRContext* irContext) const { bool modified = false; std::unordered_map<std::string, SpvId> extInstImports; @@ -90,8 +92,8 @@ RemoveDuplicatesPass::RemoveDuplicatesExtInstImports(ir::IRContext* irContext) c return modified; } -bool RemoveDuplicatesPass::RemoveDuplicateTypes(ir::IRContext* irContext, - DecorationManager& decManager) const { +bool RemoveDuplicatesPass::RemoveDuplicateTypes( + ir::IRContext* irContext, DecorationManager& decManager) const { bool modified = false; std::vector<Instruction> visitedTypes; @@ -142,7 +144,8 @@ bool RemoveDuplicatesPass::RemoveDuplicateDecorations( std::vector<const Instruction*> visitedDecorations; opt::analysis::DecorationManager decorationManager(irContext->module()); - for (auto i = irContext->annotation_begin(); i != irContext->annotation_end();) { + for (auto i = irContext->annotation_begin(); + i != irContext->annotation_end();) { // Is the current decoration equal to one of the decorations we have aready // visited? bool alreadyVisited = false; diff --git a/source/opt/remove_duplicates_pass.h b/source/opt/remove_duplicates_pass.h index 82e5f1db..d61079e9 100644 --- a/source/opt/remove_duplicates_pass.h +++ b/source/opt/remove_duplicates_pass.h @@ -19,9 +19,9 @@ #include "decoration_manager.h" #include "def_use_manager.h" +#include "ir_context.h" #include "module.h" #include "pass.h" -#include "ir_context.h" namespace spvtools { namespace opt { @@ -44,7 +44,7 @@ class RemoveDuplicatesPass : public Pass { bool RemoveDuplicateCapabilities(ir::IRContext* irContext) const; bool RemoveDuplicatesExtInstImports(ir::IRContext* irContext) const; bool RemoveDuplicateTypes(ir::IRContext* irContext, - analysis::DecorationManager& decManager) const; + analysis::DecorationManager& decManager) const; bool RemoveDuplicateDecorations(ir::IRContext* irContext) const; }; diff --git a/source/opt/set_spec_constant_default_value_pass.cpp b/source/opt/set_spec_constant_default_value_pass.cpp index d78a4138..9f2786e7 100644 --- a/source/opt/set_spec_constant_default_value_pass.cpp +++ b/source/opt/set_spec_constant_default_value_pass.cpp @@ -21,12 +21,12 @@ #include <vector> #include "def_use_manager.h" +#include "ir_context.h" #include "make_unique.h" #include "spirv-tools/libspirv.h" #include "type_manager.h" #include "types.h" #include "util/parse_number.h" -#include "ir_context.h" namespace spvtools { namespace opt { @@ -188,7 +188,8 @@ ir::Instruction* GetSpecIdTargetFromDecorationGroup( } }; -Pass::Status SetSpecConstantDefaultValuePass::Process(ir::IRContext* irContext) { +Pass::Status SetSpecConstantDefaultValuePass::Process( + ir::IRContext* irContext) { // The operand index of decoration target in an OpDecorate instruction. const uint32_t kTargetIdOperandIndex = 0; // The operand index of the decoration literal in an OpDecorate instruction. @@ -254,8 +255,8 @@ Pass::Status SetSpecConstantDefaultValuePass::Process(ir::IRContext* irContext) // Gets the string of the default value and parses it to bit pattern // with the type of the spec constant. const std::string& default_value_str = iter->second; - bit_pattern = ParseDefaultValueStr(default_value_str.c_str(), - type_mgr.GetType(spec_inst->type_id())); + bit_pattern = ParseDefaultValueStr( + default_value_str.c_str(), type_mgr.GetType(spec_inst->type_id())); } else { // Search for the new bit-pattern-form default value for this spec id. diff --git a/source/opt/set_spec_constant_default_value_pass.h b/source/opt/set_spec_constant_default_value_pass.h index dc4efca3..95667bb8 100644 --- a/source/opt/set_spec_constant_default_value_pass.h +++ b/source/opt/set_spec_constant_default_value_pass.h @@ -19,9 +19,9 @@ #include <string> #include <unordered_map> +#include "ir_context.h" #include "module.h" #include "pass.h" -#include "ir_context.h" namespace spvtools { namespace opt { @@ -38,17 +38,22 @@ class SetSpecConstantDefaultValuePass : public Pass { // in the form of string. explicit SetSpecConstantDefaultValuePass( const SpecIdToValueStrMap& default_values) - : spec_id_to_value_str_(default_values), spec_id_to_value_bit_pattern_() {} + : spec_id_to_value_str_(default_values), + spec_id_to_value_bit_pattern_() {} explicit SetSpecConstantDefaultValuePass(SpecIdToValueStrMap&& default_values) - : spec_id_to_value_str_(std::move(default_values)), spec_id_to_value_bit_pattern_() {} + : spec_id_to_value_str_(std::move(default_values)), + spec_id_to_value_bit_pattern_() {} // Constructs a pass instance with a map from spec ids to default values in // the form of bit pattern. explicit SetSpecConstantDefaultValuePass( const SpecIdToValueBitPatternMap& default_values) - : spec_id_to_value_str_(), spec_id_to_value_bit_pattern_(default_values) {} - explicit SetSpecConstantDefaultValuePass(SpecIdToValueBitPatternMap&& default_values) - : spec_id_to_value_str_(), spec_id_to_value_bit_pattern_(std::move(default_values)) {} + : spec_id_to_value_str_(), + spec_id_to_value_bit_pattern_(default_values) {} + explicit SetSpecConstantDefaultValuePass( + SpecIdToValueBitPatternMap&& default_values) + : spec_id_to_value_str_(), + spec_id_to_value_bit_pattern_(std::move(default_values)) {} const char* name() const override { return "set-spec-const-default-value"; } Status Process(ir::IRContext*) override; @@ -96,7 +101,8 @@ class SetSpecConstantDefaultValuePass : public Pass { // The mapping from spec ids to their string-form default values to be set. const SpecIdToValueStrMap spec_id_to_value_str_; - // The mapping from spec ids to their bitpattern-form default values to be set. + // The mapping from spec ids to their bitpattern-form default values to be + // set. const SpecIdToValueBitPatternMap spec_id_to_value_bit_pattern_; }; diff --git a/source/opt/strength_reduction_pass.cpp b/source/opt/strength_reduction_pass.cpp index 689034ac..5c08f5e3 100644 --- a/source/opt/strength_reduction_pass.cpp +++ b/source/opt/strength_reduction_pass.cpp @@ -21,9 +21,9 @@ #include <unordered_set> #include "def_use_manager.h" +#include "ir_context.h" #include "log.h" #include "reflect.h" -#include "ir_context.h" namespace { // Count the number of trailing zeros in the binary representation of diff --git a/source/opt/strength_reduction_pass.h b/source/opt/strength_reduction_pass.h index 8981660a..425bb321 100644 --- a/source/opt/strength_reduction_pass.h +++ b/source/opt/strength_reduction_pass.h @@ -16,9 +16,9 @@ #define LIBSPIRV_OPT_STRENGTH_REDUCTION_PASS_H_ #include "def_use_manager.h" +#include "ir_context.h" #include "module.h" #include "pass.h" -#include "ir_context.h" namespace spvtools { namespace opt { @@ -34,8 +34,10 @@ class StrengthReductionPass : public Pass { // Returns true if something changed. bool ReplaceMultiplyByPowerOf2(ir::BasicBlock::iterator*); - // Scan the types and constants in the module looking for the the integer types that we are - // interested in. The shift operation needs a small unsigned integer. We need to find + // Scan the types and constants in the module looking for the the integer + // types that we are + // interested in. The shift operation needs a small unsigned integer. We + // need to find // them or create them. We do not want duplicates. void FindIntTypesAndConstants(); diff --git a/source/opt/strip_debug_info_pass.cpp b/source/opt/strip_debug_info_pass.cpp index 6cbba42d..ae35b109 100644 --- a/source/opt/strip_debug_info_pass.cpp +++ b/source/opt/strip_debug_info_pass.cpp @@ -19,7 +19,8 @@ namespace spvtools { namespace opt { Pass::Status StripDebugInfoPass::Process(ir::IRContext* irContext) { - bool modified = !irContext->debugs1().empty() || !irContext->debugs2().empty() || + bool modified = !irContext->debugs1().empty() || + !irContext->debugs2().empty() || !irContext->debugs3().empty(); irContext->debug_clear(); diff --git a/source/opt/strip_debug_info_pass.h b/source/opt/strip_debug_info_pass.h index 3e88c944..52cbd680 100644 --- a/source/opt/strip_debug_info_pass.h +++ b/source/opt/strip_debug_info_pass.h @@ -15,9 +15,9 @@ #ifndef LIBSPIRV_OPT_STRIP_DEBUG_INFO_PASS_H_ #define LIBSPIRV_OPT_STRIP_DEBUG_INFO_PASS_H_ +#include "ir_context.h" #include "module.h" #include "pass.h" -#include "ir_context.h" namespace spvtools { namespace opt { diff --git a/source/opt/types.cpp b/source/opt/types.cpp index 1d8cad24..39bc9074 100644 --- a/source/opt/types.cpp +++ b/source/opt/types.cpp @@ -42,10 +42,10 @@ bool CompareTwoVectors(const U32VecVec a, const U32VecVec b) { b_ptrs.push_back(&b[i]); } - const auto cmp = - [](const std::vector<uint32_t>* m, const std::vector<uint32_t>* n) { - return m->front() < n->front(); - }; + const auto cmp = [](const std::vector<uint32_t>* m, + const std::vector<uint32_t>* n) { + return m->front() < n->front(); + }; std::sort(a_ptrs.begin(), a_ptrs.end(), cmp); std::sort(b_ptrs.begin(), b_ptrs.end(), cmp); diff --git a/source/opt/unify_const_pass.cpp b/source/opt/unify_const_pass.cpp index 56ed894a..088e1022 100644 --- a/source/opt/unify_const_pass.cpp +++ b/source/opt/unify_const_pass.cpp @@ -18,8 +18,8 @@ #include <utility> #include "def_use_manager.h" -#include "make_unique.h" #include "ir_context.h" +#include "make_unique.h" namespace spvtools { namespace opt { diff --git a/source/opt/unify_const_pass.h b/source/opt/unify_const_pass.h index 913ed49f..64838176 100644 --- a/source/opt/unify_const_pass.h +++ b/source/opt/unify_const_pass.h @@ -15,9 +15,9 @@ #ifndef LIBSPIRV_OPT_UNIFY_CONSTANT_PASS_H_ #define LIBSPIRV_OPT_UNIFY_CONSTANT_PASS_H_ +#include "ir_context.h" #include "module.h" #include "pass.h" -#include "ir_context.h" namespace spvtools { namespace opt { diff --git a/source/print.cpp b/source/print.cpp index fc07b945..5336df63 100644 --- a/source/print.cpp +++ b/source/print.cpp @@ -14,7 +14,8 @@ #include "print.h" -#if defined(SPIRV_ANDROID) || defined(SPIRV_LINUX) || defined(SPIRV_MAC) || defined(SPIRV_FREEBSD) +#if defined(SPIRV_ANDROID) || defined(SPIRV_LINUX) || defined(SPIRV_MAC) || \ + defined(SPIRV_FREEBSD) namespace libspirv { clr::reset::operator const char*() { return "\x1b[0m"; } @@ -35,8 +36,7 @@ clr::blue::operator const char*() { return "\x1b[34m"; } namespace libspirv { -static void SetConsoleForegroundColorPrimary(HANDLE hConsole, WORD color) -{ +static void SetConsoleForegroundColorPrimary(HANDLE hConsole, WORD color) { // Get screen buffer information from console handle CONSOLE_SCREEN_BUFFER_INFO bufInfo; GetConsoleScreenBufferInfo(hConsole, &bufInfo); @@ -48,8 +48,7 @@ static void SetConsoleForegroundColorPrimary(HANDLE hConsole, WORD color) SetConsoleTextAttribute(hConsole, color); } -static void SetConsoleForegroundColor(WORD color) -{ +static void SetConsoleForegroundColor(WORD color) { SetConsoleForegroundColorPrimary(GetStdHandle(STD_OUTPUT_HANDLE), color); SetConsoleForegroundColorPrimary(GetStdHandle(STD_ERROR_HANDLE), color); } diff --git a/source/software_version.cpp b/source/software_version.cpp index 04cf3dfb..f19f67e2 100644 --- a/source/software_version.cpp +++ b/source/software_version.cpp @@ -22,10 +22,6 @@ const char* kBuildVersions[] = { } // anonymous namespace -const char* spvSoftwareVersionString() { - return kBuildVersions[0]; -} +const char* spvSoftwareVersionString() { return kBuildVersions[0]; } -const char* spvSoftwareVersionDetailsString() { - return kBuildVersions[1]; -} +const char* spvSoftwareVersionDetailsString() { return kBuildVersions[1]; } diff --git a/source/spirv_stats.cpp b/source/spirv_stats.cpp index 34cab6d5..ff4b3c67 100644 --- a/source/spirv_stats.cpp +++ b/source/spirv_stats.cpp @@ -25,16 +25,16 @@ #include "diagnostic.h" #include "enum_string_mapping.h" #include "extensions.h" -#include "instruction.h" #include "id_descriptor.h" +#include "instruction.h" #include "opcode.h" #include "operand.h" #include "spirv-tools/libspirv.h" #include "spirv_endian.h" #include "spirv_validator_options.h" -#include "validate.h" #include "val/instruction.h" #include "val/validation_state.h" +#include "validate.h" using libspirv::IdDescriptorCollection; using libspirv::Instruction; @@ -54,10 +54,10 @@ class StatsAggregator { } // Collects header statistics and sets correct id_bound. - spv_result_t ProcessHeader( - spv_endianness_t /* endian */, uint32_t /* magic */, - uint32_t version, uint32_t generator, uint32_t id_bound, - uint32_t /* schema */) { + spv_result_t ProcessHeader(spv_endianness_t /* endian */, + uint32_t /* magic */, uint32_t version, + uint32_t generator, uint32_t id_bound, + uint32_t /* schema */) { vstate_->setIdBound(id_bound); ++stats_->version_hist[version]; ++stats_->generator_hist[generator]; @@ -68,9 +68,9 @@ class StatsAggregator { // then procession the instruction to collect stats. spv_result_t ProcessInstruction(const spv_parsed_instruction_t* inst) { const spv_result_t validation_result = - spvtools::ValidateInstructionAndUpdateValidationState(vstate_.get(), inst); - if (validation_result != SPV_SUCCESS) - return validation_result; + spvtools::ValidateInstructionAndUpdateValidationState(vstate_.get(), + inst); + if (validation_result != SPV_SUCCESS) return validation_result; ProcessOpcode(); ProcessCapability(); @@ -106,8 +106,9 @@ class StatsAggregator { id_descriptors_.GetDescriptor(inst.word(operand.offset)); if (descriptor) { ++stats_->id_descriptor_hist[descriptor]; - ++stats_->operand_slot_id_descriptor_hist[ - std::pair<uint32_t, uint32_t>(inst.opcode(), index)][descriptor]; + ++stats_ + ->operand_slot_id_descriptor_hist[std::pair<uint32_t, uint32_t>( + inst.opcode(), index)][descriptor]; } } ++index; @@ -168,8 +169,8 @@ class StatsAggregator { uint32_t index = 0; for (const auto& operand : inst.operands()) { if (operand.num_words == 1 && !spvIsIdType(operand.type)) { - ++stats_->operand_slot_non_id_words_hist[std::pair<uint32_t, uint32_t>( - inst.opcode(), index)][inst.word(operand.offset)]; + ++stats_->operand_slot_non_id_words_hist[std::pair<uint32_t, uint32_t>( + inst.opcode(), index)][inst.word(operand.offset)]; } ++index; } @@ -205,13 +206,14 @@ class StatsAggregator { if (inst_it != vstate_->ordered_instructions().rend()) { const SpvOp prev_opcode = inst_it->opcode(); - ++stats_->opcode_and_num_operands_markov_hist[prev_opcode][ - opcode_and_num_operands]; + ++stats_->opcode_and_num_operands_markov_hist[prev_opcode] + [opcode_and_num_operands]; } auto step_it = stats_->opcode_markov_hist.begin(); for (; inst_it != vstate_->ordered_instructions().rend() && - step_it != stats_->opcode_markov_hist.end(); ++inst_it, ++step_it) { + step_it != stats_->opcode_markov_hist.end(); + ++inst_it, ++step_it) { auto& hist = (*step_it)[inst_it->opcode()]; ++hist[opcode]; } @@ -260,9 +262,7 @@ class StatsAggregator { } } - SpirvStats* stats() { - return stats_; - } + SpirvStats* stats() { return stats_; } private: // Returns the current instruction (the one last processed by the validator). @@ -276,18 +276,17 @@ class StatsAggregator { IdDescriptorCollection id_descriptors_; }; -spv_result_t ProcessHeader( - void* user_data, spv_endianness_t endian, uint32_t magic, - uint32_t version, uint32_t generator, uint32_t id_bound, - uint32_t schema) { +spv_result_t ProcessHeader(void* user_data, spv_endianness_t endian, + uint32_t magic, uint32_t version, uint32_t generator, + uint32_t id_bound, uint32_t schema) { StatsAggregator* stats_aggregator = reinterpret_cast<StatsAggregator*>(user_data); - return stats_aggregator->ProcessHeader( - endian, magic, version, generator, id_bound, schema); + return stats_aggregator->ProcessHeader(endian, magic, version, generator, + id_bound, schema); } -spv_result_t ProcessInstruction( - void* user_data, const spv_parsed_instruction_t* inst) { +spv_result_t ProcessInstruction(void* user_data, + const spv_parsed_instruction_t* inst) { StatsAggregator* stats_aggregator = reinterpret_cast<StatsAggregator*>(user_data); return stats_aggregator->ProcessInstruction(inst); @@ -297,9 +296,9 @@ spv_result_t ProcessInstruction( namespace libspirv { -spv_result_t AggregateStats( - const spv_context_t& context, const uint32_t* words, const size_t num_words, - spv_diagnostic* pDiagnostic, SpirvStats* stats) { +spv_result_t AggregateStats(const spv_context_t& context, const uint32_t* words, + const size_t num_words, spv_diagnostic* pDiagnostic, + SpirvStats* stats) { spv_const_binary_t binary = {words, num_words}; spv_endianness_t endian; @@ -307,14 +306,14 @@ spv_result_t AggregateStats( if (spvBinaryEndianness(&binary, &endian)) { return libspirv::DiagnosticStream(position, context.consumer, SPV_ERROR_INVALID_BINARY) - << "Invalid SPIR-V magic number."; + << "Invalid SPIR-V magic number."; } spv_header_t header; if (spvBinaryHeaderGet(&binary, endian, &header)) { return libspirv::DiagnosticStream(position, context.consumer, SPV_ERROR_INVALID_BINARY) - << "Invalid SPIR-V header."; + << "Invalid SPIR-V header."; } StatsAggregator stats_aggregator(stats, &context); diff --git a/source/spirv_stats.h b/source/spirv_stats.h index 541dd036..cc6c2391 100644 --- a/source/spirv_stats.h +++ b/source/spirv_stats.h @@ -69,15 +69,15 @@ struct SpirvStats { std::unordered_map<double, uint32_t> f64_constant_hist; // Enum histogram, operand type -> operand value -> count. - std::unordered_map<uint32_t, - std::unordered_map<uint32_t, uint32_t>> enum_hist; + std::unordered_map<uint32_t, std::unordered_map<uint32_t, uint32_t>> + enum_hist; // Histogram of all non-id single words. // pair<opcode, operand index> -> value -> count. // This is a generalization of enum_hist, also includes literal integers and // masks. - std::map<std::pair<uint32_t, uint32_t>, - std::map<uint32_t, uint32_t>> operand_slot_non_id_words_hist; + std::map<std::pair<uint32_t, uint32_t>, std::map<uint32_t, uint32_t>> + operand_slot_non_id_words_hist; // Historgam of descriptors generated by IdDescriptorCollection. // Descriptor -> count. @@ -88,10 +88,11 @@ struct SpirvStats { // Historgam of descriptors generated by IdDescriptorCollection for every // operand slot. pair<opcode, operand index> -> descriptor -> count. - std::map<std::pair<uint32_t, uint32_t>, - std::map<uint32_t, uint32_t>> operand_slot_id_descriptor_hist; + std::map<std::pair<uint32_t, uint32_t>, std::map<uint32_t, uint32_t>> + operand_slot_id_descriptor_hist; - // Histogram of literal strings, sharded by opcodes, opcode -> string -> count. + // Histogram of literal strings, sharded by opcodes, opcode -> string -> + // count. // This is suboptimal if an opcode has multiple literal string operands, // as it wouldn't differentiate between operands. std::unordered_map<uint32_t, std::unordered_map<std::string, uint32_t>> @@ -114,14 +115,15 @@ struct SpirvStats { // The size of the outer std::vector also serves as an input parameter, // determining how many steps will be collected. // I.e. do opcode_markov_hist.resize(1) to collect data for one step only. - std::vector<std::unordered_map<uint32_t, - std::unordered_map<uint32_t, uint32_t>>> opcode_markov_hist; + std::vector< + std::unordered_map<uint32_t, std::unordered_map<uint32_t, uint32_t>>> + opcode_markov_hist; }; // Aggregates existing |stats| with new stats extracted from |binary|. -spv_result_t AggregateStats( - const spv_context_t& context, const uint32_t* words, const size_t num_words, - spv_diagnostic* pDiagnostic, SpirvStats* stats); +spv_result_t AggregateStats(const spv_context_t& context, const uint32_t* words, + const size_t num_words, spv_diagnostic* pDiagnostic, + SpirvStats* stats); } // namespace libspirv diff --git a/source/spirv_validator_options.h b/source/spirv_validator_options.h index b3cc17fb..4a67812a 100644 --- a/source/spirv_validator_options.h +++ b/source/spirv_validator_options.h @@ -37,12 +37,10 @@ struct validator_universal_limits_t { // Manages command line options passed to the SPIR-V Validator. New struct // members may be added for any new option. struct spv_validator_options_t { - spv_validator_options_t() - : universal_limits_(), relax_struct_store(false) {} + spv_validator_options_t() : universal_limits_(), relax_struct_store(false) {} validator_universal_limits_t universal_limits_; bool relax_struct_store; }; #endif // LIBSPIRV_SPIRV_VALIDATOR_OPTIONS_H_ - diff --git a/source/text.cpp b/source/text.cpp index 8c48814b..78a3e587 100644 --- a/source/text.cpp +++ b/source/text.cpp @@ -241,8 +241,8 @@ spv_result_t spvTextEncodeOperand(const libspirv::AssemblyGrammar& grammar, // and emits its corresponding number. spv_ext_inst_desc extInst; if (grammar.lookupExtInst(pInst->extInstType, textValue, &extInst)) { - return context->diagnostic() << "Invalid extended instruction name '" - << textValue << "'."; + return context->diagnostic() + << "Invalid extended instruction name '" << textValue << "'."; } spvInstructionAddWord(pInst, extInst->ext_inst); @@ -522,8 +522,8 @@ spv_result_t spvTextEncodeOpcode(const libspirv::AssemblyGrammar& grammar, error = context->getWord(&opcodeName, &nextPosition); if (error) return context->diagnostic(error) << "Internal Error"; if (!context->startsWithOp()) { - return context->diagnostic() << "Invalid Opcode prefix '" << opcodeName - << "'."; + return context->diagnostic() + << "Invalid Opcode prefix '" << opcodeName << "'."; } } @@ -533,8 +533,8 @@ spv_result_t spvTextEncodeOpcode(const libspirv::AssemblyGrammar& grammar, spv_opcode_desc opcodeEntry; error = grammar.lookupOpcode(pInstName, &opcodeEntry); if (error) { - return context->diagnostic(error) << "Invalid Opcode name '" << opcodeName - << "'"; + return context->diagnostic(error) + << "Invalid Opcode name '" << opcodeName << "'"; } if (opcodeEntry->hasResult && result_id.empty()) { return context->diagnostic() @@ -556,7 +556,8 @@ spv_result_t spvTextEncodeOpcode(const libspirv::AssemblyGrammar& grammar, spv_operand_pattern_t expectedOperands; expectedOperands.reserve(opcodeEntry->numTypes); for (auto i = 0; i < opcodeEntry->numTypes; i++) - expectedOperands.push_back(opcodeEntry->operandTypes[opcodeEntry->numTypes - i - 1]); + expectedOperands.push_back( + opcodeEntry->operandTypes[opcodeEntry->numTypes - i - 1]); while (!expectedOperands.empty()) { const spv_operand_type_t type = expectedOperands.back(); @@ -694,10 +695,11 @@ spv_result_t GetNumericIds(const libspirv::AssemblyGrammar& grammar, // Translates a given assembly language module into binary form. // If a diagnostic is generated, it is not yet marked as being // for a text-based input. -spv_result_t spvTextToBinaryInternal( - const libspirv::AssemblyGrammar& grammar, - const spvtools::MessageConsumer& consumer, const spv_text text, - const uint32_t options, spv_binary* pBinary) { +spv_result_t spvTextToBinaryInternal(const libspirv::AssemblyGrammar& grammar, + const spvtools::MessageConsumer& consumer, + const spv_text text, + const uint32_t options, + spv_binary* pBinary) { // The ids in this set will have the same values both in source and binary. // All other ids will be generated by filling in the gaps. std::set<uint32_t> ids_to_preserve; @@ -770,15 +772,17 @@ spv_result_t spvTextToBinary(const spv_const_context context, const char* input_text, const size_t input_text_size, spv_binary* pBinary, spv_diagnostic* pDiagnostic) { - return spvTextToBinaryWithOptions( - context, input_text, input_text_size, SPV_BINARY_TO_TEXT_OPTION_NONE, - pBinary, pDiagnostic); + return spvTextToBinaryWithOptions(context, input_text, input_text_size, + SPV_BINARY_TO_TEXT_OPTION_NONE, pBinary, + pDiagnostic); } -spv_result_t spvTextToBinaryWithOptions( - const spv_const_context context, const char* input_text, - const size_t input_text_size, const uint32_t options, spv_binary* pBinary, - spv_diagnostic* pDiagnostic) { +spv_result_t spvTextToBinaryWithOptions(const spv_const_context context, + const char* input_text, + const size_t input_text_size, + const uint32_t options, + spv_binary* pBinary, + spv_diagnostic* pDiagnostic) { spv_context_t hijack_context = *context; if (pDiagnostic) { *pDiagnostic = nullptr; diff --git a/source/text_handler.cpp b/source/text_handler.cpp index 1806926e..1a1b48d0 100644 --- a/source/text_handler.cpp +++ b/source/text_handler.cpp @@ -389,8 +389,7 @@ std::set<uint32_t> AssemblyContext::GetNumericIds() const { std::set<uint32_t> ids; for (const auto& kv : named_ids_) { uint32_t id; - if (spvutils::ParseNumber(kv.first.c_str(), &id)) - ids.insert(id); + if (spvutils::ParseNumber(kv.first.c_str(), &id)) ids.insert(id); } return ids; } diff --git a/source/text_handler.h b/source/text_handler.h index 1e17948d..40bfe6c0 100644 --- a/source/text_handler.h +++ b/source/text_handler.h @@ -119,8 +119,12 @@ class AssemblyContext { public: AssemblyContext(spv_text text, const spvtools::MessageConsumer& consumer, std::set<uint32_t>&& ids_to_preserve = std::set<uint32_t>()) - : current_position_({}), consumer_(consumer), text_(text), bound_(1), - next_id_(1), ids_to_preserve_(std::move(ids_to_preserve)) {} + : current_position_({}), + consumer_(consumer), + text_(text), + bound_(1), + next_id_(1), + ids_to_preserve_(std::move(ids_to_preserve)) {} // Assigns a new integer value to the given text ID, or returns the previously // assigned integer value if the ID has been seen before. diff --git a/source/util/bit_stream.cpp b/source/util/bit_stream.cpp index d66f13dc..77e2bc17 100644 --- a/source/util/bit_stream.cpp +++ b/source/util/bit_stream.cpp @@ -121,15 +121,13 @@ bool ReadVariableWidthInternal(BitReaderInterface* reader, uint64_t* val, while (payload_read + chunk_length < max_payload) { uint64_t bits = 0; - if (reader->ReadBits(&bits, chunk_length) != chunk_length) - return false; + if (reader->ReadBits(&bits, chunk_length) != chunk_length) return false; *val |= bits << payload_read; payload_read += chunk_length; uint64_t more_to_come = 0; - if (reader->ReadBits(&more_to_come, 1) != 1) - return false; + if (reader->ReadBits(&more_to_come, 1) != 1) return false; if (!more_to_come) { return true; @@ -139,8 +137,7 @@ bool ReadVariableWidthInternal(BitReaderInterface* reader, uint64_t* val, // Need to read the last chunk which may be truncated. No signal bit follows. uint64_t bits = 0; const size_t left_to_read = max_payload - payload_read; - if (reader->ReadBits(&bits, left_to_read) != left_to_read) - return false; + if (reader->ReadBits(&bits, left_to_read) != left_to_read) return false; *val |= bits << payload_read; return true; @@ -255,26 +252,22 @@ void BitWriterInterface::WriteVariableWidthU8(uint8_t val, WriteVariableWidthUnsigned(this, val, chunk_length); } -void BitWriterInterface::WriteVariableWidthS64(int64_t val, - size_t chunk_length, +void BitWriterInterface::WriteVariableWidthS64(int64_t val, size_t chunk_length, size_t zigzag_exponent) { WriteVariableWidthSigned(this, val, chunk_length, zigzag_exponent); } -void BitWriterInterface::WriteVariableWidthS32(int32_t val, - size_t chunk_length, +void BitWriterInterface::WriteVariableWidthS32(int32_t val, size_t chunk_length, size_t zigzag_exponent) { WriteVariableWidthSigned(this, val, chunk_length, zigzag_exponent); } -void BitWriterInterface::WriteVariableWidthS16(int16_t val, - size_t chunk_length, +void BitWriterInterface::WriteVariableWidthS16(int16_t val, size_t chunk_length, size_t zigzag_exponent) { WriteVariableWidthSigned(this, val, chunk_length, zigzag_exponent); } -void BitWriterInterface::WriteVariableWidthS8(int8_t val, - size_t chunk_length, +void BitWriterInterface::WriteVariableWidthS8(int8_t val, size_t chunk_length, size_t zigzag_exponent) { WriteVariableWidthSigned(this, val, chunk_length, zigzag_exponent); } @@ -352,26 +345,22 @@ bool BitReaderInterface::ReadVariableWidthU8(uint8_t* val, return ReadVariableWidthUnsigned(this, val, chunk_length); } -bool BitReaderInterface::ReadVariableWidthS64(int64_t* val, - size_t chunk_length, +bool BitReaderInterface::ReadVariableWidthS64(int64_t* val, size_t chunk_length, size_t zigzag_exponent) { return ReadVariableWidthSigned(this, val, chunk_length, zigzag_exponent); } -bool BitReaderInterface::ReadVariableWidthS32(int32_t* val, - size_t chunk_length, +bool BitReaderInterface::ReadVariableWidthS32(int32_t* val, size_t chunk_length, size_t zigzag_exponent) { return ReadVariableWidthSigned(this, val, chunk_length, zigzag_exponent); } -bool BitReaderInterface::ReadVariableWidthS16(int16_t* val, - size_t chunk_length, +bool BitReaderInterface::ReadVariableWidthS16(int16_t* val, size_t chunk_length, size_t zigzag_exponent) { return ReadVariableWidthSigned(this, val, chunk_length, zigzag_exponent); } -bool BitReaderInterface::ReadVariableWidthS8(int8_t* val, - size_t chunk_length, +bool BitReaderInterface::ReadVariableWidthS8(int8_t* val, size_t chunk_length, size_t zigzag_exponent) { return ReadVariableWidthSigned(this, val, chunk_length, zigzag_exponent); } @@ -396,8 +385,7 @@ size_t BitReaderWord64::ReadBits(uint64_t* bits, size_t num_bits) { assert(is_little_endian && "Big-endian architecture support not implemented"); if (!is_little_endian) return 0; - if (ReachedEnd()) - return 0; + if (ReachedEnd()) return 0; // Index of the current word. const size_t index = pos_ / 64; @@ -431,17 +419,13 @@ size_t BitReaderWord64::ReadBits(uint64_t* bits, size_t num_bits) { return num_bits; } -bool BitReaderWord64::ReachedEnd() const { - return pos_ >= buffer_.size() * 64; -} +bool BitReaderWord64::ReachedEnd() const { return pos_ >= buffer_.size() * 64; } bool BitReaderWord64::OnlyZeroesLeft() const { - if (ReachedEnd()) - return true; + if (ReachedEnd()) return true; const size_t index = pos_ / 64; - if (index < buffer_.size() - 1) - return false; + if (index < buffer_.size() - 1) return false; assert(index == buffer_.size() - 1); diff --git a/source/util/bit_stream.h b/source/util/bit_stream.h index f98b74bf..247ae354 100644 --- a/source/util/bit_stream.h +++ b/source/util/bit_stream.h @@ -21,8 +21,8 @@ #include <bitset> #include <cstdint> #include <functional> -#include <string> #include <sstream> +#include <string> #include <vector> namespace spvutils { @@ -60,9 +60,7 @@ inline T GetLowerBits(T in, size_t num_bits) { // 2 -> 4 // Motivation: -1 is 0xFF...FF what doesn't work very well with // WriteVariableWidth which prefers to have as many 0 bits as possible. -inline uint64_t EncodeZigZag(int64_t val) { - return (val << 1) ^ (val >> 63); -} +inline uint64_t EncodeZigZag(int64_t val) { return (val << 1) ^ (val >> 63); } // Decodes signed integer encoded with EncodeZigZag. inline int64_t DecodeZigZag(uint64_t val) { @@ -92,7 +90,8 @@ inline int64_t DecodeZigZag(uint64_t val) { inline uint64_t EncodeZigZag(int64_t val, size_t block_exponent) { assert(block_exponent < 64); const uint64_t uval = static_cast<uint64_t>(val >= 0 ? val : -val - 1); - const uint64_t block_num = ((uval >> block_exponent) << 1) + (val >= 0 ? 0 : 1); + const uint64_t block_num = + ((uval >> block_exponent) << 1) + (val >= 0 ? 0 : 1); const uint64_t pos = GetLowerBits(uval, block_exponent); return (block_num << block_exponent) + pos; } @@ -139,13 +138,13 @@ std::vector<T> StreamToBuffer(std::string str) { std::vector<T> buffer; buffer.reserve(NumBitsToNumWords<sizeof(T)>(str.length())); for (int index = str_length - word_size; index >= 0; index -= word_size) { - buffer.push_back(static_cast<T>(std::bitset<sizeof(T) * 8>( - str, index, word_size).to_ullong())); + buffer.push_back(static_cast<T>( + std::bitset<sizeof(T) * 8>(str, index, word_size).to_ullong())); } const size_t suffix_length = str.length() % word_size; if (suffix_length != 0) { - buffer.push_back(static_cast<T>(std::bitset<sizeof(T) * 8>( - str, 0, suffix_length).to_ullong())); + buffer.push_back(static_cast<T>( + std::bitset<sizeof(T) * 8>(str, 0, suffix_length).to_ullong())); } return buffer; } @@ -154,8 +153,7 @@ std::vector<T> StreamToBuffer(std::string str) { template <size_t N> inline std::string PadToWord(std::string&& str) { const size_t tail_length = str.size() % N; - if (tail_length != 0) - str += std::string(N - tail_length, '0'); + if (tail_length != 0) str += std::string(N - tail_length, '0'); return str; } @@ -174,7 +172,8 @@ inline std::bitset<N> StreamToBitset(std::string str) { // Converts first |num_bits| of std::bitset to a left-to-right stream of bits. template <size_t N> -inline std::string BitsetToStream(const std::bitset<N>& bits, size_t num_bits = N) { +inline std::string BitsetToStream(const std::bitset<N>& bits, + size_t num_bits = N) { std::string str = bits.to_string().substr(N - num_bits); std::reverse(str.begin(), str.end()); return str; @@ -237,14 +236,14 @@ class BitWriterInterface { void WriteVariableWidthU32(uint32_t val, size_t chunk_length); void WriteVariableWidthU16(uint16_t val, size_t chunk_length); void WriteVariableWidthU8(uint8_t val, size_t chunk_length); - void WriteVariableWidthS64( - int64_t val, size_t chunk_length, size_t zigzag_exponent); - void WriteVariableWidthS32( - int32_t val, size_t chunk_length, size_t zigzag_exponent); - void WriteVariableWidthS16( - int16_t val, size_t chunk_length, size_t zigzag_exponent); - void WriteVariableWidthS8( - int8_t val, size_t chunk_length, size_t zigzag_exponent); + void WriteVariableWidthS64(int64_t val, size_t chunk_length, + size_t zigzag_exponent); + void WriteVariableWidthS32(int32_t val, size_t chunk_length, + size_t zigzag_exponent); + void WriteVariableWidthS16(int16_t val, size_t chunk_length, + size_t zigzag_exponent); + void WriteVariableWidthS8(int8_t val, size_t chunk_length, + size_t zigzag_exponent); // Writes |val| using fixed bit width. Bit width is determined by |max_val|: // max_val 0 -> bit width 1 @@ -262,14 +261,10 @@ class BitWriterInterface { virtual size_t GetNumBits() const = 0; // Provides direct access to the buffer data if implemented. - virtual const uint8_t* GetData() const { - return nullptr; - } + virtual const uint8_t* GetData() const { return nullptr; } // Returns buffer size in bytes. - size_t GetDataSizeBytes() const { - return NumBitsToNumWords<8>(GetNumBits()); - } + size_t GetDataSizeBytes() const { return NumBitsToNumWords<8>(GetNumBits()); } // Generates and returns byte array containing written bits. virtual std::vector<uint8_t> GetDataCopy() const = 0; @@ -286,9 +281,7 @@ class BitWriterWord64 : public BitWriterInterface { void WriteBits(uint64_t bits, size_t num_bits) override; - size_t GetNumBits() const override { - return end_; - } + size_t GetNumBits() const override { return end_; } const uint8_t* GetData() const override { return reinterpret_cast<const uint8_t*>(buffer_.data()); @@ -300,9 +293,7 @@ class BitWriterWord64 : public BitWriterInterface { // Returns written stream as std::string, padded with zeroes so that the // length is a multiple of 64. - std::string GetStreamPadded64() const { - return BufferToStream(buffer_); - } + std::string GetStreamPadded64() const { return BufferToStream(buffer_); } // Sets callback to emit bit sequences after every write. void SetCallback(std::function<void(const std::string&)> callback) { @@ -312,8 +303,7 @@ class BitWriterWord64 : public BitWriterInterface { protected: // Sends string generated from arguments to callback_ if defined. void EmitSequence(uint64_t bits, size_t num_bits) const { - if (callback_) - callback_(BitsToStream(bits, num_bits)); + if (callback_) callback_(BitsToStream(bits, num_bits)); } private: @@ -363,8 +353,7 @@ class BitReaderInterface { static_assert(sizeof(T) <= 64, "Type size too large"); uint64_t bits = 0; const size_t num_read = ReadBits(&bits, sizeof(T) * 8); - if (num_read != sizeof(T) * 8) - return false; + if (num_read != sizeof(T) * 8) return false; memcpy(val, &bits, sizeof(T)); return true; } @@ -384,9 +373,7 @@ class BitReaderInterface { // the buffer stream ends with padding zeroes, and would accept this as a // 'soft' EOF. Implementations of this class do not necessarily need to // implement this, default behavior can simply delegate to ReachedEnd(). - virtual bool OnlyZeroesLeft() const { - return ReachedEnd(); - } + virtual bool OnlyZeroesLeft() const { return ReachedEnd(); } // Reads value encoded with WriteVariableWidthXXX (see BitWriterInterface). // Reader and writer must use the same |chunk_length| and variable type. @@ -395,14 +382,14 @@ class BitReaderInterface { bool ReadVariableWidthU32(uint32_t* val, size_t chunk_length); bool ReadVariableWidthU16(uint16_t* val, size_t chunk_length); bool ReadVariableWidthU8(uint8_t* val, size_t chunk_length); - bool ReadVariableWidthS64( - int64_t* val, size_t chunk_length, size_t zigzag_exponent); - bool ReadVariableWidthS32( - int32_t* val, size_t chunk_length, size_t zigzag_exponent); - bool ReadVariableWidthS16( - int16_t* val, size_t chunk_length, size_t zigzag_exponent); - bool ReadVariableWidthS8( - int8_t* val, size_t chunk_length, size_t zigzag_exponent); + bool ReadVariableWidthS64(int64_t* val, size_t chunk_length, + size_t zigzag_exponent); + bool ReadVariableWidthS32(int32_t* val, size_t chunk_length, + size_t zigzag_exponent); + bool ReadVariableWidthS16(int16_t* val, size_t chunk_length, + size_t zigzag_exponent); + bool ReadVariableWidthS8(int8_t* val, size_t chunk_length, + size_t zigzag_exponent); // Reads value written by WriteFixedWidth (|max_val| needs to be the same). // Returns true on success, false if the bit stream ends prematurely. @@ -428,9 +415,7 @@ class BitReaderWord64 : public BitReaderInterface { size_t ReadBits(uint64_t* bits, size_t num_bits) override; - size_t GetNumReadBits() const override { - return pos_; - } + size_t GetNumReadBits() const override { return pos_; } bool ReachedEnd() const override; bool OnlyZeroesLeft() const override; @@ -445,8 +430,7 @@ class BitReaderWord64 : public BitReaderInterface { protected: // Sends string generated from arguments to callback_ if defined. void EmitSequence(uint64_t bits, size_t num_bits) const { - if (callback_) - callback_(BitsToStream(bits, num_bits)); + if (callback_) callback_(BitsToStream(bits, num_bits)); } private: diff --git a/source/util/huffman_codec.h b/source/util/huffman_codec.h index 2ccc3c98..c2f7b1a9 100644 --- a/source/util/huffman_codec.h +++ b/source/util/huffman_codec.h @@ -20,11 +20,11 @@ #include <algorithm> #include <cassert> #include <functional> -#include <queue> #include <iomanip> #include <map> #include <memory> #include <ostream> +#include <queue> #include <sstream> #include <stack> #include <tuple> @@ -74,10 +74,10 @@ class HuffmanCodec { std::vector<uint32_t> queue_vector; queue_vector.reserve(hist.size()); std::priority_queue<uint32_t, std::vector<uint32_t>, - std::function<bool(uint32_t, uint32_t)>> - queue(std::bind(&HuffmanCodec::LeftIsBigger, this, - std::placeholders::_1, std::placeholders::_2), - std::move(queue_vector)); + std::function<bool(uint32_t, uint32_t)>> + queue(std::bind(&HuffmanCodec::LeftIsBigger, this, + std::placeholders::_1, std::placeholders::_2), + std::move(queue_vector)); // Put all leaves in the queue. for (const auto& pair : hist) { @@ -153,11 +153,9 @@ class HuffmanCodec { for (const Node& node : nodes_) { code << indent2 << "{"; - if (value_is_text) - code << "\""; + if (value_is_text) code << "\""; code << node.value; - if (value_is_text) - code << "\""; + if (value_is_text) code << "\""; code << ", " << node.left << ", " << node.right << "},\n"; } @@ -172,9 +170,7 @@ class HuffmanCodec { // Where w stands for the weight of the node. // Right tree branches appear above left branches. Taking the right path // adds 1 to the code, taking the left adds 0. - void PrintTree(std::ostream& out) const { - PrintTreeInternal(out, root_, 0); - } + void PrintTree(std::ostream& out) const { PrintTreeInternal(out, root_, 0); } // Traverses the tree and prints the Huffman table: value, code // and optionally node weight for every leaf. @@ -188,23 +184,20 @@ class HuffmanCodec { queue.pop(); if (!RightOf(node) && !LeftOf(node)) { out << ValueOf(node); - if (print_weights) - out << " " << WeightOf(node); + if (print_weights) out << " " << WeightOf(node); out << " " << code << std::endl; } else { - if (LeftOf(node)) - queue.emplace(LeftOf(node), code + "0"); + if (LeftOf(node)) queue.emplace(LeftOf(node), code + "0"); - if (RightOf(node)) - queue.emplace(RightOf(node), code + "1"); + if (RightOf(node)) queue.emplace(RightOf(node), code + "1"); } } } // Returns the Huffman table. The table was built at at construction time, // this function just returns a const reference. - const std::unordered_map<Val, std::pair<uint64_t, size_t>>& - GetEncodingTable() const { + const std::unordered_map<Val, std::pair<uint64_t, size_t>>& GetEncodingTable() + const { return encoding_table_; } @@ -212,8 +205,7 @@ class HuffmanCodec { // |bits|. Returns false of |val| is not in the Huffman table. bool Encode(const Val& val, uint64_t* bits, size_t* num_bits) const { auto it = encoding_table_.find(val); - if (it == encoding_table_.end()) - return false; + if (it == encoding_table_.end()) return false; *bits = it->second.first; *num_bits = it->second.second; return true; @@ -225,8 +217,8 @@ class HuffmanCodec { // |read_bit| has type bool func(bool* bit). When called, the next bit is // stored in |bit|. |read_bit| returns false if the stream terminates // prematurely. - bool DecodeFromStream( - const std::function<bool(bool*)>& read_bit, Val* val) const { + bool DecodeFromStream(const std::function<bool(bool*)>& read_bit, + Val* val) const { uint32_t node = root_; while (true) { assert(node); @@ -237,8 +229,7 @@ class HuffmanCodec { } bool go_right; - if (!read_bit(&go_right)) - return false; + if (!read_bit(&go_right)) return false; if (go_right) node = RightOf(node); @@ -246,35 +237,25 @@ class HuffmanCodec { node = LeftOf(node); } - assert (0); + assert(0); return false; } private: // Returns value of the node referenced by |handle|. - Val ValueOf(uint32_t node) const { - return nodes_.at(node).value; - } + Val ValueOf(uint32_t node) const { return nodes_.at(node).value; } // Returns left child of |node|. - uint32_t LeftOf(uint32_t node) const { - return nodes_.at(node).left; - } + uint32_t LeftOf(uint32_t node) const { return nodes_.at(node).left; } // Returns right child of |node|. - uint32_t RightOf(uint32_t node) const { - return nodes_.at(node).right; - } + uint32_t RightOf(uint32_t node) const { return nodes_.at(node).right; } // Returns weight of |node|. - uint32_t WeightOf(uint32_t node) const { - return nodes_.at(node).weight; - } + uint32_t WeightOf(uint32_t node) const { return nodes_.at(node).weight; } // Returns id of |node|. - uint32_t IdOf(uint32_t node) const { - return nodes_.at(node).id; - } + uint32_t IdOf(uint32_t node) const { return nodes_.at(node).id; } // Returns mutable reference to value of |node|. Val& MutableValueOf(uint32_t node) { @@ -295,20 +276,16 @@ class HuffmanCodec { } // Returns mutable reference to weight of |node|. - uint32_t& MutableWeightOf(uint32_t node) { - return nodes_.at(node).weight; - } + uint32_t& MutableWeightOf(uint32_t node) { return nodes_.at(node).weight; } // Returns mutable reference to id of |node|. - uint32_t& MutableIdOf(uint32_t node) { - return nodes_.at(node).id; - } + uint32_t& MutableIdOf(uint32_t node) { return nodes_.at(node).id; } // Returns true if |left| has bigger weight than |right|. Node ids are // used as tie-breaker. bool LeftIsBigger(uint32_t left, uint32_t right) const { if (WeightOf(left) == WeightOf(right)) { - assert (IdOf(left) != IdOf(right)); + assert(IdOf(left) != IdOf(right)); return IdOf(left) > IdOf(right); } return WeightOf(left) > WeightOf(right); @@ -316,8 +293,7 @@ class HuffmanCodec { // Prints subtree (helper function used by PrintTree). void PrintTreeInternal(std::ostream& out, uint32_t node, size_t depth) const { - if (!node) - return; + if (!node) return; const size_t kTextFieldWidth = 7; @@ -348,7 +324,7 @@ class HuffmanCodec { void CreateEncodingTable() { struct Context { Context(uint32_t in_node, uint64_t in_bits, size_t in_depth) - : node(in_node), bits(in_bits), depth(in_depth) {} + : node(in_node), bits(in_bits), depth(in_depth) {} uint32_t node; // Huffman tree depth cannot exceed 64 as histogramm counts are expected // to be positive and limited by numeric_limits<uint32_t>::max(). @@ -373,8 +349,7 @@ class HuffmanCodec { assert(insertion_result.second); (void)insertion_result; } else { - if (LeftOf(node)) - queue.emplace(LeftOf(node), bits, depth + 1); + if (LeftOf(node)) queue.emplace(LeftOf(node), bits, depth + 1); if (RightOf(node)) queue.emplace(RightOf(node), bits | (1ULL << depth), depth + 1); diff --git a/source/util/ilist.h b/source/util/ilist.h index 6be01fd3..ebd5def4 100644 --- a/source/util/ilist.h +++ b/source/util/ilist.h @@ -272,7 +272,7 @@ bool IntrusiveList<NodeType>::empty() const { return sentinel_.NextNode() == nullptr; } -template<class NodeType> +template <class NodeType> void IntrusiveList<NodeType>::clear() { while (!empty()) { front().RemoveFromList(); diff --git a/source/util/ilist_node.h b/source/util/ilist_node.h index 342fb1dc..76ea302d 100644 --- a/source/util/ilist_node.h +++ b/source/util/ilist_node.h @@ -110,7 +110,7 @@ template <class NodeType> inline IntrusiveNodeBase<NodeType>::IntrusiveNodeBase() : next_node_(nullptr), previous_node_(nullptr), is_sentinel_(false) {} -template<class NodeType> +template <class NodeType> inline IntrusiveNodeBase<NodeType>::IntrusiveNodeBase( const IntrusiveNodeBase&) { next_node_ = nullptr; @@ -118,7 +118,7 @@ inline IntrusiveNodeBase<NodeType>::IntrusiveNodeBase( is_sentinel_ = false; } -template<class NodeType> +template <class NodeType> inline IntrusiveNodeBase<NodeType>& IntrusiveNodeBase<NodeType>::operator=( const IntrusiveNodeBase&) { assert(!is_sentinel_); @@ -128,7 +128,7 @@ inline IntrusiveNodeBase<NodeType>& IntrusiveNodeBase<NodeType>::operator=( return *this; } -template<class NodeType> +template <class NodeType> inline IntrusiveNodeBase<NodeType>::IntrusiveNodeBase(IntrusiveNodeBase&& that) : next_node_(nullptr), previous_node_(nullptr), @@ -140,19 +140,19 @@ inline IntrusiveNodeBase<NodeType>::IntrusiveNodeBase(IntrusiveNodeBase&& that) that.ReplaceWith(this); } -template<class NodeType> +template <class NodeType> IntrusiveNodeBase<NodeType>::~IntrusiveNodeBase() { assert(is_sentinel_ || !IsInAList()); } -template<class NodeType> +template <class NodeType> IntrusiveNodeBase<NodeType>& IntrusiveNodeBase<NodeType>::operator=( IntrusiveNodeBase&& that) { that.ReplaceWith(this); return *this; } -template<class NodeType> +template <class NodeType> inline bool IntrusiveNodeBase<NodeType>::IsInAList() const { return next_node_ != nullptr; } @@ -199,7 +199,7 @@ template <class NodeType> inline void IntrusiveNodeBase<NodeType>::RemoveFromList() { assert(!this->is_sentinel_ && "Sentinel nodes cannot be moved around."); assert(this->IsInAList() && - "Cannot remove a node from a list if it is not in a list."); + "Cannot remove a node from a list if it is not in a list."); this->next_node_->previous_node_ = this->previous_node_; this->previous_node_->next_node_ = this->next_node_; @@ -207,16 +207,16 @@ inline void IntrusiveNodeBase<NodeType>::RemoveFromList() { this->previous_node_ = nullptr; } -template<class NodeType> +template <class NodeType> void IntrusiveNodeBase<NodeType>::ReplaceWith(NodeType* target) { if (this->is_sentinel_) { assert(target->IsEmptyList() && - "If target is not an empty list, the nodes in that list would not " - "be linked to a sentinel."); + "If target is not an empty list, the nodes in that list would not " + "be linked to a sentinel."); } else { assert(IsInAList() && "The node being replaced must be in a list."); assert(!target->is_sentinel_ && - "Cannot turn a sentinel node into one that is not."); + "Cannot turn a sentinel node into one that is not."); } if (!this->IsEmptyList()) { @@ -245,13 +245,13 @@ void IntrusiveNodeBase<NodeType>::ReplaceWith(NodeType* target) { } } -template<class NodeType> +template <class NodeType> bool IntrusiveNodeBase<NodeType>::IsEmptyList() { if (next_node_ == this) { assert(is_sentinel_ && - "None sentinel nodes should never point to themselves."); + "None sentinel nodes should never point to themselves."); assert(previous_node_ == this && - "Inconsistency with the previous and next nodes."); + "Inconsistency with the previous and next nodes."); return true; } return false; diff --git a/source/util/move_to_front.h b/source/util/move_to_front.h index 3c5ce6a3..0cfd7c18 100644 --- a/source/util/move_to_front.h +++ b/source/util/move_to_front.h @@ -94,16 +94,16 @@ class MoveToFront { bool HasValue(const Val& value) const; // Returns the number of elements in the move-to-front sequence. - uint32_t GetSize() const { - return SizeOf(root_); - } + uint32_t GetSize() const { return SizeOf(root_); } protected: // Internal tree data structure uses handles instead of pointers. Leaves and // root parent reference a singleton under handle 0. Although dereferencing // a null pointer is not possible, inappropriate access to handle 0 would - // cause an assertion. Handles are not garbage collected if value was deprecated - // with DeprecateValue(). But handles are recycled when a node is repositioned. + // cause an assertion. Handles are not garbage collected if value was + // deprecated + // with DeprecateValue(). But handles are recycled when a node is + // repositioned. // Internal tree data structure node. struct Node { @@ -125,7 +125,8 @@ class MoveToFront { }; // Creates node and sets correct values. Non-NIL nodes should be created only - // through this function. If the node with this value has been created previously + // through this function. If the node with this value has been created + // previously // and since orphaned, reuses the old node instead of creating a new one. uint32_t CreateNode(uint32_t timestamp, const Val& value) { uint32_t handle = static_cast<uint32_t>(nodes_.size()); @@ -137,7 +138,8 @@ class MoveToFront { node.timestamp = timestamp; node.value = value; node.size = 1; - // Non-NIL nodes start with height 1 because their NIL children are leaves. + // Non-NIL nodes start with height 1 because their NIL children are + // leaves. node.height = 1; } else { // Reuse old node. @@ -157,24 +159,16 @@ class MoveToFront { // ParentOf(LeftestDescendentOf(RightOf(node))) // Returns value of the node referenced by |handle|. - Val ValueOf(uint32_t node) const { - return nodes_.at(node).value; - } + Val ValueOf(uint32_t node) const { return nodes_.at(node).value; } // Returns left child of |node|. - uint32_t LeftOf(uint32_t node) const { - return nodes_.at(node).left; - } + uint32_t LeftOf(uint32_t node) const { return nodes_.at(node).left; } // Returns right child of |node|. - uint32_t RightOf(uint32_t node) const { - return nodes_.at(node).right; - } + uint32_t RightOf(uint32_t node) const { return nodes_.at(node).right; } // Returns parent of |node|. - uint32_t ParentOf(uint32_t node) const { - return nodes_.at(node).parent; - } + uint32_t ParentOf(uint32_t node) const { return nodes_.at(node).parent; } // Returns timestamp of |node|. uint32_t TimestampOf(uint32_t node) const { @@ -183,14 +177,10 @@ class MoveToFront { } // Returns size of |node|. - uint32_t SizeOf(uint32_t node) const { - return nodes_.at(node).size; - } + uint32_t SizeOf(uint32_t node) const { return nodes_.at(node).size; } // Returns height of |node|. - uint32_t HeightOf(uint32_t node) const { - return nodes_.at(node).height; - } + uint32_t HeightOf(uint32_t node) const { return nodes_.at(node).height; } // Returns mutable reference to value of |node|. Val& MutableValueOf(uint32_t node) { @@ -347,8 +337,7 @@ class MultiMoveToFront { // Removes |value| from all sequences which have it. void RemoveFromAll(const Val& value) { auto it = val_to_mtfs_.find(value); - if (it == val_to_mtfs_.end()) - return; + if (it == val_to_mtfs_.end()) return; auto& mtfs_containing_value = it->second; for (uint64_t mtf : mtfs_containing_value) { @@ -371,15 +360,12 @@ class MultiMoveToFront { } // Returns size of |mtf| sequence. - uint32_t GetSize(uint64_t mtf) { - return GetMtf(mtf).GetSize(); - } + uint32_t GetSize(uint64_t mtf) { return GetMtf(mtf).GetSize(); } // Promotes |value| in all sequences which have it. void Promote(const Val& value) { const auto it = val_to_mtfs_.find(value); - if (it == val_to_mtfs_.end()) - return; + if (it == val_to_mtfs_.end()) return; const auto& mtfs_containing_value = it->second; for (uint64_t mtf : mtfs_containing_value) { @@ -426,8 +412,7 @@ class MultiMoveToFront { template <typename Val> bool MoveToFront<Val>::Insert(const Val& value) { auto it = value_to_node_.find(value); - if (it != value_to_node_.end() && IsInTree(it->second)) - return false; + if (it != value_to_node_.end() && IsInTree(it->second)) return false; const uint32_t old_size = GetSize(); (void)old_size; @@ -445,14 +430,11 @@ bool MoveToFront<Val>::Insert(const Val& value) { template <typename Val> bool MoveToFront<Val>::Remove(const Val& value) { auto it = value_to_node_.find(value); - if (it == value_to_node_.end()) - return false; + if (it == value_to_node_.end()) return false; - if (!IsInTree(it->second)) - return false; + if (!IsInTree(it->second)) return false; - if (last_accessed_value_ == value) - last_accessed_value_valid_ = false; + if (last_accessed_value_ == value) last_accessed_value_valid_ = false; const uint32_t orphan = RemoveNode(it->second); (void)orphan; @@ -494,8 +476,7 @@ bool MoveToFront<Val>::RankFromValue(const Val& value, uint32_t* rank) { uint32_t node = target; *rank = 1 + SizeOf(LeftOf(node)); while (node) { - if (IsRightChild(node)) - *rank += 1 + SizeOf(LeftOf(ParentOf(node))); + if (IsRightChild(node)) *rank += 1 + SizeOf(LeftOf(ParentOf(node))); node = ParentOf(node); } @@ -532,8 +513,7 @@ bool MoveToFront<Val>::Promote(const Val& value) { } const uint32_t old_size = GetSize(); - if (old_size == 1) - return ValueOf(root_) == value; + if (old_size == 1) return ValueOf(root_) == value; const auto it = value_to_node_.find(value); if (it == value_to_node_.end()) { @@ -663,8 +643,7 @@ void MoveToFront<Val>::InsertNode(uint32_t node) { // Added node to the right subtree. if (parent_balance > 1) { // Parent is right heavy, rotate left. - if (BalanceOf(node) < 0) - RotateRight(node); + if (BalanceOf(node) < 0) RotateRight(node); parent = RotateLeft(parent); } else if (parent_balance == 0 || parent_balance == -1) { // Parent is balanced or left heavy, no need to balance further. @@ -674,8 +653,7 @@ void MoveToFront<Val>::InsertNode(uint32_t node) { // Added node to the left subtree. if (parent_balance < -1) { // Parent is left heavy, rotate right. - if (BalanceOf(node) > 0) - RotateLeft(node); + if (BalanceOf(node) > 0) RotateLeft(node); parent = RotateRight(parent); } else if (parent_balance == 0 || parent_balance == 1) { // Parent is balanced or right heavy, no need to balance further. @@ -695,9 +673,11 @@ template <typename Val> uint32_t MoveToFront<Val>::RemoveNode(uint32_t node) { if (LeftOf(node) && RightOf(node)) { // If |node| has two children, then use another node as scapegoat and swap - // their contents. We pick the scapegoat on the side of the tree which has more nodes. - const uint32_t scapegoat = SizeOf(LeftOf(node)) >= SizeOf(RightOf(node)) ? - RightestDescendantOf(LeftOf(node)) : LeftestDescendantOf(RightOf(node)); + // their contents. We pick the scapegoat on the side of the tree which has + // more nodes. + const uint32_t scapegoat = SizeOf(LeftOf(node)) >= SizeOf(RightOf(node)) + ? RightestDescendantOf(LeftOf(node)) + : LeftestDescendantOf(RightOf(node)); assert(scapegoat); std::swap(MutableValueOf(node), MutableValueOf(scapegoat)); std::swap(MutableTimestampOf(node), MutableTimestampOf(scapegoat)); @@ -713,8 +693,7 @@ uint32_t MoveToFront<Val>::RemoveNode(uint32_t node) { uint32_t child = RightOf(node) ? RightOf(node) : LeftOf(node); // Orphan |node| and reconnect parent and child. - if (child) - MutableParentOf(child) = parent; + if (child) MutableParentOf(child) = parent; if (parent) { if (LeftOf(parent) == node) @@ -729,8 +708,7 @@ uint32_t MoveToFront<Val>::RemoveNode(uint32_t node) { UpdateNode(node); const uint32_t orphan = node; - if (root_ == node) - root_ = child; + if (root_ == node) root_ = child; // Removal is finished. Start the balancing process. bool needs_rebalancing = true; @@ -751,8 +729,7 @@ uint32_t MoveToFront<Val>::RemoveNode(uint32_t node) { if (parent_balance < -1) { // Parent is left heavy, rotate right. const uint32_t sibling = LeftOf(parent); - if (BalanceOf(sibling) > 0) - RotateLeft(sibling); + if (BalanceOf(sibling) > 0) RotateLeft(sibling); parent = RotateRight(parent); } } else { @@ -760,8 +737,7 @@ uint32_t MoveToFront<Val>::RemoveNode(uint32_t node) { if (parent_balance > 1) { // Parent is right heavy, rotate left. const uint32_t sibling = RightOf(parent); - if (BalanceOf(sibling) < 0) - RotateRight(sibling); + if (BalanceOf(sibling) < 0) RotateRight(sibling); parent = RotateLeft(parent); } } @@ -784,8 +760,7 @@ uint32_t MoveToFront<Val>::RotateLeft(const uint32_t node) { // LeftOf(pivot) gets attached to node in place of pivot. MutableRightOf(node) = LeftOf(pivot); - if (RightOf(node)) - MutableParentOf(RightOf(node)) = node; + if (RightOf(node)) MutableParentOf(RightOf(node)) = node; // Pivot gets attached to ParentOf(node) in place of node. MutableParentOf(pivot) = ParentOf(node); @@ -815,8 +790,7 @@ uint32_t MoveToFront<Val>::RotateRight(const uint32_t node) { // RightOf(pivot) gets attached to node in place of pivot. MutableLeftOf(node) = RightOf(pivot); - if (LeftOf(node)) - MutableParentOf(LeftOf(node)) = node; + if (LeftOf(node)) MutableParentOf(LeftOf(node)) = node; // Pivot gets attached to ParentOf(node) in place of node. MutableParentOf(pivot) = ParentOf(node); diff --git a/source/util/parse_number.cpp b/source/util/parse_number.cpp index c71b3115..5ec905d1 100644 --- a/source/util/parse_number.cpp +++ b/source/util/parse_number.cpp @@ -68,8 +68,8 @@ EncodeNumberStatus ParseAndEncodeIntegerNumber( const uint32_t bit_width = AssumedBitWidth(type); if (bit_width > 64) { - ErrorMsgStream(error_msg) << "Unsupported " << bit_width - << "-bit integer literals"; + ErrorMsgStream(error_msg) + << "Unsupported " << bit_width << "-bit integer literals"; return EncodeNumberStatus::kUnsupported; } @@ -182,8 +182,8 @@ EncodeNumberStatus ParseAndEncodeFloatingPointNumber( default: break; } - ErrorMsgStream(error_msg) << "Unsupported " << bit_width - << "-bit float literals"; + ErrorMsgStream(error_msg) + << "Unsupported " << bit_width << "-bit float literals"; return EncodeNumberStatus::kUnsupported; } diff --git a/source/util/parse_number.h b/source/util/parse_number.h index 5b7922b8..2a9bd6d4 100644 --- a/source/util/parse_number.h +++ b/source/util/parse_number.h @@ -171,7 +171,7 @@ bool ParseNumber(const char* text, T* value_pointer) { static_assert(sizeof(T) > 1, "Single-byte types are not supported in this parse method"); - if (!text) return false; + if (!text) return false; std::istringstream text_stream(text); // Allow both decimal and hex input for integers. // It also allows octal input, but we don't care about that case. diff --git a/source/val/basic_block.cpp b/source/val/basic_block.cpp index 0bfc4f12..a0b10fa7 100644 --- a/source/val/basic_block.cpp +++ b/source/val/basic_block.cpp @@ -118,7 +118,7 @@ const BasicBlock::DominatorIterator BasicBlock::pdom_begin() const { BasicBlock::DominatorIterator BasicBlock::pdom_begin() { return DominatorIterator( - this, [](const BasicBlock* b) { return b->immediate_post_dominator(); }); + this, [](const BasicBlock* b) { return b->immediate_post_dominator(); }); } const BasicBlock::DominatorIterator BasicBlock::pdom_end() const { diff --git a/source/val/basic_block.h b/source/val/basic_block.h index 81f0f666..70b2eec3 100644 --- a/source/val/basic_block.h +++ b/source/val/basic_block.h @@ -108,7 +108,8 @@ class BasicBlock { void RegisterBranchInstruction(SpvOp branch_instruction); /// Adds @p next BasicBlocks as successors of this BasicBlock - void RegisterSuccessors(const std::vector<BasicBlock*>& next = std::vector<BasicBlock*>()); + void RegisterSuccessors( + const std::vector<BasicBlock*>& next = std::vector<BasicBlock*>()); /// Returns true if the id of the BasicBlock matches bool operator==(const BasicBlock& other) const { return other.id_ == id_; } diff --git a/source/val/construct.cpp b/source/val/construct.cpp index 4270063f..e3ad7f06 100644 --- a/source/val/construct.cpp +++ b/source/val/construct.cpp @@ -19,9 +19,8 @@ namespace libspirv { -Construct::Construct(ConstructType construct_type, - BasicBlock* entry, BasicBlock* exit, - std::vector<Construct*> constructs) +Construct::Construct(ConstructType construct_type, BasicBlock* entry, + BasicBlock* exit, std::vector<Construct*> constructs) : type_(construct_type), corresponding_constructs_(constructs), entry_block_(entry), @@ -38,11 +37,16 @@ std::vector<Construct*>& Construct::corresponding_constructs() { bool ValidateConstructSize(ConstructType type, size_t size) { switch (type) { - case ConstructType::kSelection: return size == 0; - case ConstructType::kContinue: return size == 1; - case ConstructType::kLoop: return size == 1; - case ConstructType::kCase: return size >= 1; - default: assert(1 == 0 && "Type not defined"); + case ConstructType::kSelection: + return size == 0; + case ConstructType::kContinue: + return size == 1; + case ConstructType::kLoop: + return size == 1; + case ConstructType::kCase: + return size >= 1; + default: + assert(1 == 0 && "Type not defined"); } return false; } diff --git a/source/val/decoration.h b/source/val/decoration.h index a6d7ff95..d77b0684 100644 --- a/source/val/decoration.h +++ b/source/val/decoration.h @@ -84,4 +84,3 @@ class Decoration { } // namespace libspirv #endif /// LIBSPIRV_VAL_DECORATION_H_ - diff --git a/source/val/function.cpp b/source/val/function.cpp index 42f7ec15..91352b2e 100644 --- a/source/val/function.cpp +++ b/source/val/function.cpp @@ -17,14 +17,14 @@ #include <cassert> #include <algorithm> -#include <unordered_set> #include <unordered_map> +#include <unordered_set> #include <utility> +#include "cfa.h" #include "val/basic_block.h" #include "val/construct.h" #include "validate.h" -#include "cfa.h" using std::ignore; using std::list; @@ -275,13 +275,9 @@ void Function::ComputeAugmentedCFG() { auto succ_func = [](const BasicBlock* b) { return b->successors(); }; auto pred_func = [](const BasicBlock* b) { return b->predecessors(); }; spvtools::CFA<BasicBlock>::ComputeAugmentedCFG( - ordered_blocks_, - &pseudo_entry_block_, - &pseudo_exit_block_, - &augmented_successors_map_, - &augmented_predecessors_map_, - succ_func, - pred_func); + ordered_blocks_, &pseudo_entry_block_, &pseudo_exit_block_, + &augmented_successors_map_, &augmented_predecessors_map_, succ_func, + pred_func); }; Construct& Function::AddConstruct(const Construct& new_construct) { diff --git a/source/val/function.h b/source/val/function.h index 8baeb33f..f7856b3b 100644 --- a/source/val/function.h +++ b/source/val/function.h @@ -183,7 +183,8 @@ class Function { GetBlocksFunction AugmentedCFGSuccessorsFunction() const; /// Like AugmentedCFGSuccessorsFunction, but also includes a forward edge from /// a loop header block to its continue target, if they are different blocks. - GetBlocksFunction AugmentedCFGSuccessorsFunctionIncludingHeaderToContinueEdge() const; + GetBlocksFunction + AugmentedCFGSuccessorsFunctionIncludingHeaderToContinueEdge() const; /// Returns the block predecessors function for the augmented CFG. GetBlocksFunction AugmentedCFGPredecessorsFunction() const; diff --git a/source/val/instruction.h b/source/val/instruction.h index 31b463a6..5ae89e2c 100644 --- a/source/val/instruction.h +++ b/source/val/instruction.h @@ -72,9 +72,7 @@ class Instruction { } /// Provides direct access to the stored C instruction object. - const spv_parsed_instruction_t& c_inst() const { - return inst_; - } + const spv_parsed_instruction_t& c_inst() const { return inst_; } // Casts the words belonging to the operand under |index| to |T| and returns. template <typename T> diff --git a/source/val/validation_state.h b/source/val/validation_state.h index db39dae5..b60e48df 100644 --- a/source/val/validation_state.h +++ b/source/val/validation_state.h @@ -358,15 +358,14 @@ class ValidationState_t { // Provides detailed information on matrix type. // Returns false iff |id| is not matrix type. - bool GetMatrixTypeInfo( - uint32_t id, uint32_t* num_rows, uint32_t* num_cols, - uint32_t* column_type, uint32_t* component_type) const; + bool GetMatrixTypeInfo(uint32_t id, uint32_t* num_rows, uint32_t* num_cols, + uint32_t* column_type, uint32_t* component_type) const; // Collects struct member types into |member_types|. // Returns false iff not struct type or has no members. // Deletes prior contents of |member_types|. - bool GetStructMemberTypes( - uint32_t struct_type_id, std::vector<uint32_t>* member_types) const; + bool GetStructMemberTypes(uint32_t struct_type_id, + std::vector<uint32_t>* member_types) const; // Returns true iff |id| is a type corresponding to the name of the function. // Only works for types not for objects. @@ -393,8 +392,8 @@ class ValidationState_t { size_t operand_index) const; // Provides information on pointer type. Returns false iff not pointer type. - bool GetPointerTypeInfo( - uint32_t id, uint32_t* data_type, uint32_t* storage_class) const; + bool GetPointerTypeInfo(uint32_t id, uint32_t* data_type, + uint32_t* storage_class) const; private: ValidationState_t(const ValidationState_t&); diff --git a/source/validate.cpp b/source/validate.cpp index 536f798a..ca73bd09 100644 --- a/source/validate.cpp +++ b/source/validate.cpp @@ -139,11 +139,10 @@ void RegisterExtension(ValidationState_t& _, // once an instruction which is not SpvOpCapability and SpvOpExtension is // encountered. According to the SPIR-V spec extensions are declared after // capabilities and before everything else. -spv_result_t ProcessExtensions( - void* user_data, const spv_parsed_instruction_t* inst) { +spv_result_t ProcessExtensions(void* user_data, + const spv_parsed_instruction_t* inst) { const SpvOp opcode = static_cast<SpvOp>(inst->opcode); - if (opcode == SpvOpCapability) - return SPV_SUCCESS; + if (opcode == SpvOpCapability) return SPV_SUCCESS; if (opcode == SpvOpExtension) { ValidationState_t& _ = *(reinterpret_cast<ValidationState_t*>(user_data)); @@ -242,7 +241,7 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( const spv_context_t& context, const uint32_t* words, const size_t num_words, spv_diagnostic* pDiagnostic, ValidationState_t* vstate) { auto binary = std::unique_ptr<spv_const_binary_t>( - new spv_const_binary_t{words, num_words}); + new spv_const_binary_t{words, num_words}); spv_endianness_t endian; spv_position_t position = {}; @@ -267,8 +266,8 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( // NOTE: Parse the module and perform inline validation checks. These // checks do not require the the knowledge of the whole module. - if (auto error = spvBinaryParse(&context, vstate, words, num_words, - setHeader, ProcessInstruction, pDiagnostic)) + if (auto error = spvBinaryParse(&context, vstate, words, num_words, setHeader, + ProcessInstruction, pDiagnostic)) return error; if (vstate->in_function_body()) @@ -296,7 +295,7 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( if (auto error = PerformCfgChecks(*vstate)) return error; if (auto error = UpdateIdUse(*vstate)) return error; if (auto error = CheckIdDefinitionDominateUse(*vstate)) return error; - if (auto error = ValidateDecorations(*vstate)) return error; + if (auto error = ValidateDecorations(*vstate)) return error; // Entry point validation. Based on 2.16.1 (Universal Validation Rules) of the // SPIRV spec: @@ -338,8 +337,7 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( position.index = SPV_INDEX_INSTRUCTION; return spvValidateIDs(instructions.data(), instructions.size(), - context.opcode_table, - context.operand_table, + context.opcode_table, context.operand_table, context.ext_inst_table, *vstate, &position); } diff --git a/source/validate.h b/source/validate.h index 2e088d94..3c3bcb2f 100644 --- a/source/validate.h +++ b/source/validate.h @@ -113,7 +113,7 @@ spv_result_t TypeUniquePass(ValidationState_t& _, /// Validates correctness of arithmetic instructions. spv_result_t ArithmeticsPass(ValidationState_t& _, - const spv_parsed_instruction_t* inst); + const spv_parsed_instruction_t* inst); /// Validates correctness of conversion instructions. spv_result_t ConversionPass(ValidationState_t& _, diff --git a/source/validate_arithmetics.cpp b/source/validate_arithmetics.cpp index a2d3fbce..42399fcc 100644 --- a/source/validate_arithmetics.cpp +++ b/source/validate_arithmetics.cpp @@ -38,16 +38,15 @@ inline uint32_t GetOperandWord(const spv_parsed_instruction_t* inst, // Returns the type id of instruction operand at |operand_index|. // The operand is expected to be an id. inline uint32_t GetOperandTypeId(ValidationState_t& _, - const spv_parsed_instruction_t* inst, - size_t operand_index) { + const spv_parsed_instruction_t* inst, + size_t operand_index) { return _.GetTypeId(GetOperandWord(inst, operand_index)); } - } // Validates correctness of arithmetic instructions. spv_result_t ArithmeticsPass(ValidationState_t& _, - const spv_parsed_instruction_t* inst) { + const spv_parsed_instruction_t* inst) { const SpvOp opcode = static_cast<SpvOp>(inst->opcode); const uint32_t result_type = inst->type_id; @@ -62,15 +61,16 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, if (!_.IsFloatScalarType(result_type) && !_.IsFloatVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected floating scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected floating scalar or vector type as Result Type: " + << spvOpcodeString(opcode); for (size_t operand_index = 2; operand_index < inst->num_operands; ++operand_index) { if (GetOperandTypeId(_, inst, operand_index) != result_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected arithmetic operands to be of Result Type: " - << spvOpcodeString(opcode) << " operand index " << operand_index; + << "Expected arithmetic operands to be of Result Type: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; } break; } @@ -80,15 +80,16 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, if (!_.IsUnsignedIntScalarType(result_type) && !_.IsUnsignedIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected unsigned int scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected unsigned int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); for (size_t operand_index = 2; operand_index < inst->num_operands; ++operand_index) { if (GetOperandTypeId(_, inst, operand_index) != result_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected arithmetic operands to be of Result Type: " - << spvOpcodeString(opcode) << " operand index " << operand_index; + << "Expected arithmetic operands to be of Result Type: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; } break; } @@ -100,36 +101,35 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, case SpvOpSMod: case SpvOpSRem: case SpvOpSNegate: { - if (!_.IsIntScalarType(result_type) && - !_.IsIntVectorType(result_type)) + if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected int scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t dimension = _.GetDimension(result_type); const uint32_t bit_width = _.GetBitWidth(result_type); for (size_t operand_index = 2; operand_index < inst->num_operands; ++operand_index) { - const uint32_t type_id = GetOperandTypeId(_, inst, operand_index); if (!type_id || (!_.IsIntScalarType(type_id) && !_.IsIntVectorType(type_id))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected int scalar or vector type as operand: " - << spvOpcodeString(opcode) << " operand index " << operand_index; + << "Expected int scalar or vector type as operand: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; if (_.GetDimension(type_id) != dimension) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected arithmetic operands to have the same dimension " - << "as Result Type: " - << spvOpcodeString(opcode) << " operand index " << operand_index; + << "Expected arithmetic operands to have the same dimension " + << "as Result Type: " << spvOpcodeString(opcode) + << " operand index " << operand_index; if (_.GetBitWidth(type_id) != bit_width) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected arithmetic operands to have the same bit width " - << "as Result Type: " - << spvOpcodeString(opcode) << " operand index " << operand_index; + << "Expected arithmetic operands to have the same bit width " + << "as Result Type: " << spvOpcodeString(opcode) + << " operand index " << operand_index; } break; } @@ -137,8 +137,8 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, case SpvOpDot: { if (!_.IsFloatScalarType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float scalar type as Result Type: " - << spvOpcodeString(opcode); + << "Expected float scalar type as Result Type: " + << spvOpcodeString(opcode); uint32_t first_vector_num_components = 0; @@ -148,23 +148,24 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, if (!type_id || !_.IsFloatVectorType(type_id)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float vector as operand: " - << spvOpcodeString(opcode) << " operand index " << operand_index; - + << "Expected float vector as operand: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; const uint32_t component_type = _.GetComponentType(type_id); if (component_type != result_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected component type to be equal to Result Type: " - << spvOpcodeString(opcode) << " operand index " << operand_index; + << "Expected component type to be equal to Result Type: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; const uint32_t num_components = _.GetDimension(type_id); if (operand_index == 2) { first_vector_num_components = num_components; } else if (num_components != first_vector_num_components) { return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected operands to have the same number of componenets: " - << spvOpcodeString(opcode); + << "Expected operands to have the same number of componenets: " + << spvOpcodeString(opcode); } } break; @@ -173,23 +174,22 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, case SpvOpVectorTimesScalar: { if (!_.IsFloatVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected float vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t vector_type_id = GetOperandTypeId(_, inst, 2); if (result_type != vector_type_id) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected vector operand type to be equal to Result Type: " - << spvOpcodeString(opcode); + << "Expected vector operand type to be equal to Result Type: " + << spvOpcodeString(opcode); const uint32_t component_type = _.GetComponentType(vector_type_id); const uint32_t scalar_type_id = GetOperandTypeId(_, inst, 3); if (component_type != scalar_type_id) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected scalar operand type to be equal to the component " - << "type of the vector operand: " - << spvOpcodeString(opcode); + << "Expected scalar operand type to be equal to the component " + << "type of the vector operand: " << spvOpcodeString(opcode); break; } @@ -197,23 +197,22 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, case SpvOpMatrixTimesScalar: { if (!_.IsFloatMatrixType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float matrix type as Result Type: " - << spvOpcodeString(opcode); + << "Expected float matrix type as Result Type: " + << spvOpcodeString(opcode); const uint32_t matrix_type_id = GetOperandTypeId(_, inst, 2); if (result_type != matrix_type_id) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected matrix operand type to be equal to Result Type: " - << spvOpcodeString(opcode); + << "Expected matrix operand type to be equal to Result Type: " + << spvOpcodeString(opcode); const uint32_t component_type = _.GetComponentType(matrix_type_id); const uint32_t scalar_type_id = GetOperandTypeId(_, inst, 3); if (component_type != scalar_type_id) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected scalar operand type to be equal to the component " - << "type of the matrix operand: " - << spvOpcodeString(opcode); + << "Expected scalar operand type to be equal to the component " + << "type of the matrix operand: " << spvOpcodeString(opcode); break; } @@ -224,20 +223,20 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, if (!_.IsFloatVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected float vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t res_component_type = _.GetComponentType(result_type); if (!vector_type_id || !_.IsFloatVectorType(vector_type_id)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float vector type as left operand: " - << spvOpcodeString(opcode); + << "Expected float vector type as left operand: " + << spvOpcodeString(opcode); if (res_component_type != _.GetComponentType(vector_type_id)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected component types of Result Type and vector to be " - << "equal: " << spvOpcodeString(opcode); + << "Expected component types of Result Type and vector to be " + << "equal: " << spvOpcodeString(opcode); uint32_t matrix_num_rows = 0; uint32_t matrix_num_cols = 0; @@ -247,23 +246,23 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, &matrix_num_cols, &matrix_col_type, &matrix_component_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float matrix type as right operand: " - << spvOpcodeString(opcode); + << "Expected float matrix type as right operand: " + << spvOpcodeString(opcode); if (res_component_type != matrix_component_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected component types of Result Type and matrix to be " - << "equal: " << spvOpcodeString(opcode); + << "Expected component types of Result Type and matrix to be " + << "equal: " << spvOpcodeString(opcode); if (matrix_num_cols != _.GetDimension(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected number of columns of the matrix to be equal to " - << "Result Type vector size: " << spvOpcodeString(opcode); + << "Expected number of columns of the matrix to be equal to " + << "Result Type vector size: " << spvOpcodeString(opcode); if (matrix_num_rows != _.GetDimension(vector_type_id)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected number of rows of the matrix to be equal to the " - << "vector operand size: " << spvOpcodeString(opcode); + << "Expected number of rows of the matrix to be equal to the " + << "vector operand size: " << spvOpcodeString(opcode); break; } @@ -274,8 +273,8 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, if (!_.IsFloatVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected float vector type as Result Type: " + << spvOpcodeString(opcode); uint32_t matrix_num_rows = 0; uint32_t matrix_num_cols = 0; @@ -285,28 +284,29 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, &matrix_num_cols, &matrix_col_type, &matrix_component_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float matrix type as left operand: " - << spvOpcodeString(opcode); + << "Expected float matrix type as left operand: " + << spvOpcodeString(opcode); if (result_type != matrix_col_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected column type of the matrix to be equal to Result Type: " - << spvOpcodeString(opcode); + << "Expected column type of the matrix to be equal to Result " + "Type: " + << spvOpcodeString(opcode); if (!vector_type_id || !_.IsFloatVectorType(vector_type_id)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float vector type as right operand: " - << spvOpcodeString(opcode); + << "Expected float vector type as right operand: " + << spvOpcodeString(opcode); if (matrix_component_type != _.GetComponentType(vector_type_id)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected component types of the operands to be equal: " - << spvOpcodeString(opcode); + << "Expected component types of the operands to be equal: " + << spvOpcodeString(opcode); if (matrix_num_cols != _.GetDimension(vector_type_id)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected number of columns of the matrix to be equal to the " - << "vector size: " << spvOpcodeString(opcode); + << "Expected number of columns of the matrix to be equal to the " + << "vector size: " << spvOpcodeString(opcode); break; } @@ -322,8 +322,8 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, if (!_.GetMatrixTypeInfo(result_type, &res_num_rows, &res_num_cols, &res_col_type, &res_component_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float matrix type as Result Type: " - << spvOpcodeString(opcode); + << "Expected float matrix type as Result Type: " + << spvOpcodeString(opcode); uint32_t left_num_rows = 0; uint32_t left_num_cols = 0; @@ -332,8 +332,8 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, if (!_.GetMatrixTypeInfo(left_type_id, &left_num_rows, &left_num_cols, &left_col_type, &left_component_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float matrix type as left operand: " - << spvOpcodeString(opcode); + << "Expected float matrix type as left operand: " + << spvOpcodeString(opcode); uint32_t right_num_rows = 0; uint32_t right_num_cols = 0; @@ -342,33 +342,36 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, if (!_.GetMatrixTypeInfo(right_type_id, &right_num_rows, &right_num_cols, &right_col_type, &right_component_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float matrix type as right operand: " - << spvOpcodeString(opcode); + << "Expected float matrix type as right operand: " + << spvOpcodeString(opcode); if (!_.IsFloatScalarType(res_component_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float matrix type as Result Type: " - << spvOpcodeString(opcode); + << "Expected float matrix type as Result Type: " + << spvOpcodeString(opcode); if (res_col_type != left_col_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected column types of Result Type and left matrix to be " - << "equal: " << spvOpcodeString(opcode); + << "Expected column types of Result Type and left matrix to be " + << "equal: " << spvOpcodeString(opcode); if (res_component_type != right_component_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected component types of Result Type and right matrix to be " - << "equal: " << spvOpcodeString(opcode); + << "Expected component types of Result Type and right matrix to " + "be " + << "equal: " << spvOpcodeString(opcode); if (res_num_cols != right_num_cols) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected number of columns of Result Type and right matrix to " - << "be equal: " << spvOpcodeString(opcode); + << "Expected number of columns of Result Type and right matrix " + "to " + << "be equal: " << spvOpcodeString(opcode); if (left_num_cols != right_num_rows) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected number of columns of left matrix and number of rows " - << "of right matrix to be equal: " << spvOpcodeString(opcode); + << "Expected number of columns of left matrix and number of " + "rows " + << "of right matrix to be equal: " << spvOpcodeString(opcode); assert(left_num_rows == res_num_rows); break; @@ -385,29 +388,29 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, if (!_.GetMatrixTypeInfo(result_type, &res_num_rows, &res_num_cols, &res_col_type, &res_component_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float matrix type as Result Type: " - << spvOpcodeString(opcode); + << "Expected float matrix type as Result Type: " + << spvOpcodeString(opcode); if (left_type_id != res_col_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected column type of Result Type to be equal to the type " - << "of the left operand: " - << spvOpcodeString(opcode); + << "Expected column type of Result Type to be equal to the type " + << "of the left operand: " << spvOpcodeString(opcode); if (!right_type_id || !_.IsFloatVectorType(right_type_id)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float vector type as right operand: " - << spvOpcodeString(opcode); + << "Expected float vector type as right operand: " + << spvOpcodeString(opcode); if (res_component_type != _.GetComponentType(right_type_id)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected component types of the operands to be equal: " - << spvOpcodeString(opcode); + << "Expected component types of the operands to be equal: " + << spvOpcodeString(opcode); if (res_num_cols != _.GetDimension(right_type_id)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected number of columns of the matrix to be equal to the " - << "vector size of the right operand: " << spvOpcodeString(opcode); + << "Expected number of columns of the matrix to be equal to the " + << "vector size of the right operand: " + << spvOpcodeString(opcode); break; } @@ -419,40 +422,41 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, std::vector<uint32_t> result_types; if (!_.GetStructMemberTypes(result_type, &result_types)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected a struct as Result Type: " - << spvOpcodeString(opcode); + << "Expected a struct as Result Type: " + << spvOpcodeString(opcode); if (result_types.size() != 2) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Result Type struct to have two members: " - << spvOpcodeString(opcode); + << "Expected Result Type struct to have two members: " + << spvOpcodeString(opcode); if (opcode == SpvOpSMulExtended) { if (!_.IsIntScalarType(result_types[0]) && !_.IsIntVectorType(result_types[0])) - return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Result Type struct member types to be integer scalar " - << "or vector: " << spvOpcodeString(opcode); + return _.diag(SPV_ERROR_INVALID_DATA) + << "Expected Result Type struct member types to be integer " + "scalar " + << "or vector: " << spvOpcodeString(opcode); } else { if (!_.IsUnsignedIntScalarType(result_types[0]) && !_.IsUnsignedIntVectorType(result_types[0])) - return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Result Type struct member types to be unsigned " - << "integer scalar or vector: " << spvOpcodeString(opcode); + return _.diag(SPV_ERROR_INVALID_DATA) + << "Expected Result Type struct member types to be unsigned " + << "integer scalar or vector: " << spvOpcodeString(opcode); } if (result_types[0] != result_types[1]) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Result Type struct member types to be identical: " - << spvOpcodeString(opcode); + << "Expected Result Type struct member types to be identical: " + << spvOpcodeString(opcode); const uint32_t left_type_id = GetOperandTypeId(_, inst, 2); const uint32_t right_type_id = GetOperandTypeId(_, inst, 3); if (left_type_id != result_types[0] || right_type_id != result_types[0]) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected both operands to be of Result Type member type: " - << spvOpcodeString(opcode); + << "Expected both operands to be of Result Type member type: " + << spvOpcodeString(opcode); break; } diff --git a/source/validate_bitwise.cpp b/source/validate_bitwise.cpp index c175ea64..e7171386 100644 --- a/source/validate_bitwise.cpp +++ b/source/validate_bitwise.cpp @@ -38,11 +38,10 @@ inline uint32_t GetOperandWord(const spv_parsed_instruction_t* inst, // Returns the type id of instruction operand at |operand_index|. // The operand is expected to be an id. inline uint32_t GetOperandTypeId(ValidationState_t& _, - const spv_parsed_instruction_t* inst, - size_t operand_index) { + const spv_parsed_instruction_t* inst, + size_t operand_index) { return _.GetTypeId(GetOperandWord(inst, operand_index)); } - } // Validates correctness of bitwise instructions. @@ -55,11 +54,10 @@ spv_result_t BitwisePass(ValidationState_t& _, case SpvOpShiftRightLogical: case SpvOpShiftRightArithmetic: case SpvOpShiftLeftLogical: { - if (!_.IsIntScalarType(result_type) && - !_.IsIntVectorType(result_type)) + if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected int scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t result_dimension = _.GetDimension(result_type); const uint32_t base_type = GetOperandTypeId(_, inst, 2); @@ -68,32 +66,29 @@ spv_result_t BitwisePass(ValidationState_t& _, if (!base_type || (!_.IsIntScalarType(base_type) && !_.IsIntVectorType(base_type))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Base to be int scalar or vector: " - << spvOpcodeString(opcode); + << "Expected Base to be int scalar or vector: " + << spvOpcodeString(opcode); if (_.GetDimension(base_type) != result_dimension) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Base to have the same dimension " - << "as Result Type: " - << spvOpcodeString(opcode); + << "Expected Base to have the same dimension " + << "as Result Type: " << spvOpcodeString(opcode); if (_.GetBitWidth(base_type) != _.GetBitWidth(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Base to have the same bit width " - << "as Result Type: " - << spvOpcodeString(opcode); + << "Expected Base to have the same bit width " + << "as Result Type: " << spvOpcodeString(opcode); if (!shift_type || (!_.IsIntScalarType(shift_type) && !_.IsIntVectorType(shift_type))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Shift to be int scalar or vector: " - << spvOpcodeString(opcode); + << "Expected Shift to be int scalar or vector: " + << spvOpcodeString(opcode); if (_.GetDimension(shift_type) != result_dimension) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Shift to have the same dimension " - << "as Result Type: " - << spvOpcodeString(opcode); + << "Expected Shift to have the same dimension " + << "as Result Type: " << spvOpcodeString(opcode); break; } @@ -101,46 +96,44 @@ spv_result_t BitwisePass(ValidationState_t& _, case SpvOpBitwiseXor: case SpvOpBitwiseAnd: case SpvOpNot: { - if (!_.IsIntScalarType(result_type) && - !_.IsIntVectorType(result_type)) + if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected int scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t result_dimension = _.GetDimension(result_type); const uint32_t result_bit_width = _.GetBitWidth(result_type); for (size_t operand_index = 2; operand_index < inst->num_operands; ++operand_index) { - const uint32_t type_id = GetOperandTypeId(_, inst, operand_index); if (!type_id || (!_.IsIntScalarType(type_id) && !_.IsIntVectorType(type_id))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected int scalar or vector as operand: " - << spvOpcodeString(opcode) << " operand index " << operand_index; + << "Expected int scalar or vector as operand: " + << spvOpcodeString(opcode) << " operand index " + << operand_index; if (_.GetDimension(type_id) != result_dimension) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected operands to have the same dimension " - << "as Result Type: " - << spvOpcodeString(opcode) << " operand index " << operand_index; + << "Expected operands to have the same dimension " + << "as Result Type: " << spvOpcodeString(opcode) + << " operand index " << operand_index; if (_.GetBitWidth(type_id) != result_bit_width) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected operands to have the same bit width " - << "as Result Type: " - << spvOpcodeString(opcode) << " operand index " << operand_index; + << "Expected operands to have the same bit width " + << "as Result Type: " << spvOpcodeString(opcode) + << " operand index " << operand_index; } break; } case SpvOpBitFieldInsert: { - if (!_.IsIntScalarType(result_type) && - !_.IsIntVectorType(result_type)) + if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected int scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t base_type = GetOperandTypeId(_, inst, 2); const uint32_t insert_type = GetOperandTypeId(_, inst, 3); @@ -149,33 +142,32 @@ spv_result_t BitwisePass(ValidationState_t& _, if (base_type != result_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Base Type to be equal to Result Type: " - << spvOpcodeString(opcode); + << "Expected Base Type to be equal to Result Type: " + << spvOpcodeString(opcode); if (insert_type != result_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Insert Type to be equal to Result Type: " - << spvOpcodeString(opcode); + << "Expected Insert Type to be equal to Result Type: " + << spvOpcodeString(opcode); if (!offset_type || !_.IsIntScalarType(offset_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Offset Type to be int scalar: " - << spvOpcodeString(opcode); + << "Expected Offset Type to be int scalar: " + << spvOpcodeString(opcode); if (!count_type || !_.IsIntScalarType(count_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Count Type to be int scalar: " - << spvOpcodeString(opcode); + << "Expected Count Type to be int scalar: " + << spvOpcodeString(opcode); break; } case SpvOpBitFieldSExtract: case SpvOpBitFieldUExtract: { - if (!_.IsIntScalarType(result_type) && - !_.IsIntVectorType(result_type)) + if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected int scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t base_type = GetOperandTypeId(_, inst, 2); const uint32_t offset_type = GetOperandTypeId(_, inst, 3); @@ -183,43 +175,41 @@ spv_result_t BitwisePass(ValidationState_t& _, if (base_type != result_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Base Type to be equal to Result Type: " - << spvOpcodeString(opcode); + << "Expected Base Type to be equal to Result Type: " + << spvOpcodeString(opcode); if (!offset_type || !_.IsIntScalarType(offset_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Offset Type to be int scalar: " - << spvOpcodeString(opcode); + << "Expected Offset Type to be int scalar: " + << spvOpcodeString(opcode); if (!count_type || !_.IsIntScalarType(count_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Count Type to be int scalar: " - << spvOpcodeString(opcode); + << "Expected Count Type to be int scalar: " + << spvOpcodeString(opcode); break; } case SpvOpBitReverse: { - if (!_.IsIntScalarType(result_type) && - !_.IsIntVectorType(result_type)) + if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected int scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t base_type = GetOperandTypeId(_, inst, 2); if (base_type != result_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Base Type to be equal to Result Type: " - << spvOpcodeString(opcode); + << "Expected Base Type to be equal to Result Type: " + << spvOpcodeString(opcode); break; } case SpvOpBitCount: { - if (!_.IsIntScalarType(result_type) && - !_.IsIntVectorType(result_type)) + if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected int scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t base_type = GetOperandTypeId(_, inst, 2); if (!base_type || @@ -233,8 +223,9 @@ spv_result_t BitwisePass(ValidationState_t& _, if (base_dimension != result_dimension) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Base dimension to be equal to Result Type dimension: " - << spvOpcodeString(opcode); + << "Expected Base dimension to be equal to Result Type " + "dimension: " + << spvOpcodeString(opcode); break; } diff --git a/source/validate_cfg.cpp b/source/validate_cfg.cpp index f237a0fd..45a6c956 100644 --- a/source/validate_cfg.cpp +++ b/source/validate_cfg.cpp @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "validate.h" #include "cfa.h" +#include "validate.h" #include <algorithm> #include <cassert> @@ -298,8 +298,9 @@ spv_result_t PerformCfgChecks(ValidationState_t& _) { function.pseudo_exit_block(), function.AugmentedCFGPredecessorsFunction(), ignore_block, [&](cbb_ptr b) { postdom_postorder.push_back(b); }, ignore_edge); - auto postdom_edges = spvtools::CFA<libspirv::BasicBlock>::CalculateDominators( - postdom_postorder, function.AugmentedCFGSuccessorsFunction()); + auto postdom_edges = + spvtools::CFA<libspirv::BasicBlock>::CalculateDominators( + postdom_postorder, function.AugmentedCFGSuccessorsFunction()); for (auto edge : postdom_edges) { edge.first->SetImmediatePostDominator(edge.second); } @@ -407,8 +408,8 @@ spv_result_t CfgPass(ValidationState_t& _, assert(return_type_inst); if (return_type_inst->opcode() != SpvOpTypeVoid) return _.diag(SPV_ERROR_INVALID_CFG) - << "OpReturn can only be called from a function with void " - << "return type."; + << "OpReturn can only be called from a function with void " + << "return type."; } // Fallthrough. case SpvOpKill: diff --git a/source/validate_conversion.cpp b/source/validate_conversion.cpp index 222796e7..a885d1b5 100644 --- a/source/validate_conversion.cpp +++ b/source/validate_conversion.cpp @@ -34,20 +34,20 @@ spv_result_t ConversionPass(ValidationState_t& _, if (!_.IsUnsignedIntScalarType(result_type) && !_.IsUnsignedIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected unsigned int scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected unsigned int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); if (!input_type || (!_.IsFloatScalarType(input_type) && !_.IsFloatVectorType(input_type))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to be float scalar or vector: " - << spvOpcodeString(opcode); + << "Expected input to be float scalar or vector: " + << spvOpcodeString(opcode); if (_.GetDimension(result_type) != _.GetDimension(input_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to have the same dimension as Result Type: " - << spvOpcodeString(opcode); + << "Expected input to have the same dimension as Result Type: " + << spvOpcodeString(opcode); break; } @@ -55,20 +55,20 @@ spv_result_t ConversionPass(ValidationState_t& _, case SpvOpConvertFToS: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected int scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); if (!input_type || (!_.IsFloatScalarType(input_type) && !_.IsFloatVectorType(input_type))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to be float scalar or vector: " - << spvOpcodeString(opcode); + << "Expected input to be float scalar or vector: " + << spvOpcodeString(opcode); if (_.GetDimension(result_type) != _.GetDimension(input_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to have the same dimension as Result Type: " - << spvOpcodeString(opcode); + << "Expected input to have the same dimension as Result Type: " + << spvOpcodeString(opcode); break; } @@ -78,20 +78,20 @@ spv_result_t ConversionPass(ValidationState_t& _, if (!_.IsFloatScalarType(result_type) && !_.IsFloatVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected float scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); - if (!input_type || (!_.IsIntScalarType(input_type) && - !_.IsIntVectorType(input_type))) + if (!input_type || + (!_.IsIntScalarType(input_type) && !_.IsIntVectorType(input_type))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to be int scalar or vector: " - << spvOpcodeString(opcode); + << "Expected input to be int scalar or vector: " + << spvOpcodeString(opcode); if (_.GetDimension(result_type) != _.GetDimension(input_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to have the same dimension as Result Type: " - << spvOpcodeString(opcode); + << "Expected input to have the same dimension as Result Type: " + << spvOpcodeString(opcode); break; } @@ -128,25 +128,26 @@ spv_result_t ConversionPass(ValidationState_t& _, case SpvOpSConvert: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected int scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); - if (!input_type || (!_.IsIntScalarType(input_type) && - !_.IsIntVectorType(input_type))) + if (!input_type || + (!_.IsIntScalarType(input_type) && !_.IsIntVectorType(input_type))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to be int scalar or vector: " - << spvOpcodeString(opcode); + << "Expected input to be int scalar or vector: " + << spvOpcodeString(opcode); if (_.GetDimension(result_type) != _.GetDimension(input_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to have the same dimension as Result Type: " - << spvOpcodeString(opcode); + << "Expected input to have the same dimension as Result Type: " + << spvOpcodeString(opcode); if (_.GetBitWidth(result_type) == _.GetBitWidth(input_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to have different bit width from Result Type: " - << spvOpcodeString(opcode); + << "Expected input to have different bit width from Result " + "Type: " + << spvOpcodeString(opcode); break; } @@ -154,54 +155,55 @@ spv_result_t ConversionPass(ValidationState_t& _, if (!_.IsFloatScalarType(result_type) && !_.IsFloatVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected float scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected float scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); if (!input_type || (!_.IsFloatScalarType(input_type) && !_.IsFloatVectorType(input_type))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to be float scalar or vector: " - << spvOpcodeString(opcode); + << "Expected input to be float scalar or vector: " + << spvOpcodeString(opcode); if (_.GetDimension(result_type) != _.GetDimension(input_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to have the same dimension as Result Type: " - << spvOpcodeString(opcode); + << "Expected input to have the same dimension as Result Type: " + << spvOpcodeString(opcode); if (_.GetBitWidth(result_type) == _.GetBitWidth(input_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to have different bit width from Result Type: " - << spvOpcodeString(opcode); + << "Expected input to have different bit width from Result " + "Type: " + << spvOpcodeString(opcode); break; } case SpvOpQuantizeToF16: { if ((!_.IsFloatScalarType(result_type) && - !_.IsFloatVectorType(result_type)) || + !_.IsFloatVectorType(result_type)) || _.GetBitWidth(result_type) != 32) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected 32-bit float scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected 32-bit float scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); if (input_type != result_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input type to be equal to Result Type: " - << spvOpcodeString(opcode); + << "Expected input type to be equal to Result Type: " + << spvOpcodeString(opcode); break; } case SpvOpConvertPtrToU: { if (!_.IsUnsignedIntScalarType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected unsigned int scalar type as Result Type: " - << spvOpcodeString(opcode); + << "Expected unsigned int scalar type as Result Type: " + << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); if (!_.IsPointerType(input_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to be a pointer: " << spvOpcodeString(opcode); + << "Expected input to be a pointer: " << spvOpcodeString(opcode); break; } @@ -209,33 +211,33 @@ spv_result_t ConversionPass(ValidationState_t& _, case SpvOpSatConvertUToS: { if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected int scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected int scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); - if (!input_type || (!_.IsIntScalarType(input_type) && - !_.IsIntVectorType(input_type))) + if (!input_type || + (!_.IsIntScalarType(input_type) && !_.IsIntVectorType(input_type))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected int scalar or vector as input: " - << spvOpcodeString(opcode); + << "Expected int scalar or vector as input: " + << spvOpcodeString(opcode); if (_.GetDimension(result_type) != _.GetDimension(input_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to have the same dimension as Result Type: " - << spvOpcodeString(opcode); + << "Expected input to have the same dimension as Result Type: " + << spvOpcodeString(opcode); break; } case SpvOpConvertUToPtr: { if (!_.IsPointerType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Result Type to be a pointer: " - << spvOpcodeString(opcode); + << "Expected Result Type to be a pointer: " + << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); if (!_.IsIntScalarType(input_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected int scalar as input: " << spvOpcodeString(opcode); + << "Expected int scalar as input: " << spvOpcodeString(opcode); break; } @@ -245,13 +247,13 @@ spv_result_t ConversionPass(ValidationState_t& _, if (!_.GetPointerTypeInfo(result_type, &result_data_type, &result_storage_class)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Result Type to be a pointer: " - << spvOpcodeString(opcode); + << "Expected Result Type to be a pointer: " + << spvOpcodeString(opcode); if (result_storage_class != SpvStorageClassGeneric) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Result Type to have storage class Generic: " - << spvOpcodeString(opcode); + << "Expected Result Type to have storage class Generic: " + << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); uint32_t input_storage_class = 0; @@ -259,21 +261,19 @@ spv_result_t ConversionPass(ValidationState_t& _, if (!_.GetPointerTypeInfo(input_type, &input_data_type, &input_storage_class)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to be a pointer: " - << spvOpcodeString(opcode); + << "Expected input to be a pointer: " << spvOpcodeString(opcode); if (input_storage_class != SpvStorageClassWorkgroup && input_storage_class != SpvStorageClassCrossWorkgroup && input_storage_class != SpvStorageClassFunction) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to have storage class Workgroup, " - << "CrossWorkgroup or Function: " - << spvOpcodeString(opcode); + << "Expected input to have storage class Workgroup, " + << "CrossWorkgroup or Function: " << spvOpcodeString(opcode); if (result_data_type != input_data_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input and Result Type to point to the same type: " - << spvOpcodeString(opcode); + << "Expected input and Result Type to point to the same type: " + << spvOpcodeString(opcode); break; } @@ -283,16 +283,15 @@ spv_result_t ConversionPass(ValidationState_t& _, if (!_.GetPointerTypeInfo(result_type, &result_data_type, &result_storage_class)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Result Type to be a pointer: " - << spvOpcodeString(opcode); + << "Expected Result Type to be a pointer: " + << spvOpcodeString(opcode); if (result_storage_class != SpvStorageClassWorkgroup && result_storage_class != SpvStorageClassCrossWorkgroup && result_storage_class != SpvStorageClassFunction) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Result Type to have storage class Workgroup, " - << "CrossWorkgroup or Function: " - << spvOpcodeString(opcode); + << "Expected Result Type to have storage class Workgroup, " + << "CrossWorkgroup or Function: " << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); uint32_t input_storage_class = 0; @@ -300,18 +299,17 @@ spv_result_t ConversionPass(ValidationState_t& _, if (!_.GetPointerTypeInfo(input_type, &input_data_type, &input_storage_class)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to be a pointer: " - << spvOpcodeString(opcode); + << "Expected input to be a pointer: " << spvOpcodeString(opcode); if (input_storage_class != SpvStorageClassGeneric) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to have storage class Generic: " - << spvOpcodeString(opcode); + << "Expected input to have storage class Generic: " + << spvOpcodeString(opcode); if (result_data_type != input_data_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input and Result Type to point to the same type: " - << spvOpcodeString(opcode); + << "Expected input and Result Type to point to the same type: " + << spvOpcodeString(opcode); break; } @@ -321,14 +319,14 @@ spv_result_t ConversionPass(ValidationState_t& _, if (!_.GetPointerTypeInfo(result_type, &result_data_type, &result_storage_class)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Result Type to be a pointer: " - << spvOpcodeString(opcode); + << "Expected Result Type to be a pointer: " + << spvOpcodeString(opcode); const uint32_t target_storage_class = inst->words[4]; if (result_storage_class != target_storage_class) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Result Type to be of target storage class: " - << spvOpcodeString(opcode); + << "Expected Result Type to be of target storage class: " + << spvOpcodeString(opcode); const uint32_t input_type = _.GetOperandTypeId(inst, 2); uint32_t input_storage_class = 0; @@ -336,26 +334,24 @@ spv_result_t ConversionPass(ValidationState_t& _, if (!_.GetPointerTypeInfo(input_type, &input_data_type, &input_storage_class)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to be a pointer: " - << spvOpcodeString(opcode); + << "Expected input to be a pointer: " << spvOpcodeString(opcode); if (input_storage_class != SpvStorageClassGeneric) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to have storage class Generic: " - << spvOpcodeString(opcode); + << "Expected input to have storage class Generic: " + << spvOpcodeString(opcode); if (result_data_type != input_data_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input and Result Type to point to the same type: " - << spvOpcodeString(opcode); + << "Expected input and Result Type to point to the same type: " + << spvOpcodeString(opcode); if (target_storage_class != SpvStorageClassWorkgroup && target_storage_class != SpvStorageClassCrossWorkgroup && target_storage_class != SpvStorageClassFunction) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected target storage class to be Workgroup, " - << "CrossWorkgroup or Function: " - << spvOpcodeString(opcode); + << "Expected target storage class to be Workgroup, " + << "CrossWorkgroup or Function: " << spvOpcodeString(opcode); break; } @@ -363,7 +359,7 @@ spv_result_t ConversionPass(ValidationState_t& _, const uint32_t input_type = _.GetOperandTypeId(inst, 2); if (!input_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to have a type: " << spvOpcodeString(opcode); + << "Expected input to have a type: " << spvOpcodeString(opcode); const bool result_is_pointer = _.IsPointerType(result_type); const bool result_is_int_scalar = _.IsIntScalarType(result_type); @@ -375,26 +371,25 @@ spv_result_t ConversionPass(ValidationState_t& _, !_.IsFloatScalarType(result_type) && !_.IsFloatVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected Result Type to be a pointer or int or float vector " - << "or scalar type: " << spvOpcodeString(opcode); + << "Expected Result Type to be a pointer or int or float vector " + << "or scalar type: " << spvOpcodeString(opcode); if (!input_is_pointer && !input_is_int_scalar && - !_.IsIntVectorType(input_type) && - !_.IsFloatScalarType(input_type) && + !_.IsIntVectorType(input_type) && !_.IsFloatScalarType(input_type) && !_.IsFloatVectorType(input_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to be a pointer or int or float vector " - << "or scalar: " << spvOpcodeString(opcode); + << "Expected input to be a pointer or int or float vector " + << "or scalar: " << spvOpcodeString(opcode); if (result_is_pointer && !input_is_pointer && !input_is_int_scalar) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to be a pointer or int scalar if Result Type " - << "is pointer: " << spvOpcodeString(opcode); + << "Expected input to be a pointer or int scalar if Result Type " + << "is pointer: " << spvOpcodeString(opcode); if (input_is_pointer && !result_is_pointer && !result_is_int_scalar) return _.diag(SPV_ERROR_INVALID_DATA) - << "Pointer can only be converted to another pointer or int " - << "scalar: " << spvOpcodeString(opcode); + << "Pointer can only be converted to another pointer or int " + << "scalar: " << spvOpcodeString(opcode); if (!result_is_pointer && !input_is_pointer) { const uint32_t result_size = @@ -403,8 +398,8 @@ spv_result_t ConversionPass(ValidationState_t& _, _.GetBitWidth(input_type) * _.GetDimension(input_type); if (result_size != input_size) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected input to have the same total bit width as " - << "Result Type: " << spvOpcodeString(opcode); + << "Expected input to have the same total bit width as " + << "Result Type: " << spvOpcodeString(opcode); } break; } diff --git a/source/validate_datarules.cpp b/source/validate_datarules.cpp index 5a11e686..7d51ecab 100644 --- a/source/validate_datarules.cpp +++ b/source/validate_datarules.cpp @@ -122,8 +122,8 @@ spv_result_t ValidateIntSize(ValidationState_t& _, return _.diag(SPV_ERROR_INVALID_DATA) << "Using a 64-bit integer type requires the Int64 capability."; } - return _.diag(SPV_ERROR_INVALID_DATA) << "Invalid number of bits (" - << num_bits << ") used for OpTypeInt."; + return _.diag(SPV_ERROR_INVALID_DATA) + << "Invalid number of bits (" << num_bits << ") used for OpTypeInt."; } // Validates that the matrix is parameterized with floating-point types. diff --git a/source/validate_decorations.cpp b/source/validate_decorations.cpp index e2b7dfba..6fd3eeb6 100644 --- a/source/validate_decorations.cpp +++ b/source/validate_decorations.cpp @@ -165,4 +165,3 @@ spv_result_t ValidateDecorations(ValidationState_t& vstate) { } } // namespace libspirv - diff --git a/source/validate_id.cpp b/source/validate_id.cpp index 87d47282..6ee2f11d 100644 --- a/source/validate_id.cpp +++ b/source/validate_id.cpp @@ -202,22 +202,21 @@ bool idUsage::isValid<SpvOpMemberDecorate>(const spv_instruction_t* inst, template <> bool idUsage::isValid<SpvOpDecorationGroup>(const spv_instruction_t* inst, - const spv_opcode_desc) { + const spv_opcode_desc) { auto decorationGroupIndex = 1; auto decorationGroup = module_.FindDef(inst->words[decorationGroupIndex]); for (auto pair : decorationGroup->uses()) { auto use = pair.first; - if (use->opcode() != SpvOpDecorate && - use->opcode() != SpvOpGroupDecorate && + if (use->opcode() != SpvOpDecorate && use->opcode() != SpvOpGroupDecorate && use->opcode() != SpvOpGroupMemberDecorate && - use->opcode() != SpvOpName ) { + use->opcode() != SpvOpName) { DIAG(decorationGroupIndex) << "Result id of OpDecorationGroup can only " << "be targeted by OpName, OpGroupDecorate, " << "OpDecorate, and OpGroupMemberDecorate"; return false; } - } + } return true; } @@ -228,8 +227,8 @@ bool idUsage::isValid<SpvOpGroupDecorate>(const spv_instruction_t* inst, auto decorationGroup = module_.FindDef(inst->words[decorationGroupIndex]); if (!decorationGroup || SpvOpDecorationGroup != decorationGroup->opcode()) { DIAG(decorationGroupIndex) - << "OpGroupDecorate Decoration group <id> '" - << inst->words[decorationGroupIndex] << "' is not a decoration group."; + << "OpGroupDecorate Decoration group <id> '" + << inst->words[decorationGroupIndex] << "' is not a decoration group."; return false; } return true; @@ -296,8 +295,8 @@ bool idUsage::isValid<SpvOpEntryPoint>(const spv_instruction_t* inst, auto entryPointType = module_.FindDef(entryPoint->words()[4]); if (!entryPointType || 3 != entryPointType->words().size()) { DIAG(entryPointIndex) - << "OpEntryPoint Entry Point <id> '" << inst->words[entryPointIndex] - << "'s function parameter count is not zero."; + << "OpEntryPoint Entry Point <id> '" << inst->words[entryPointIndex] + << "'s function parameter count is not zero."; return false; } } @@ -457,8 +456,8 @@ bool idUsage::isValid<SpvOpTypeStruct>(const spv_instruction_t* inst, auto memberType = module_.FindDef(memberTypeId); if (!memberType || !spvOpcodeGeneratesType(memberType->opcode())) { DIAG(memberTypeIndex) - << "OpTypeStruct Member Type <id> '" << inst->words[memberTypeIndex] - << "' is not a type."; + << "OpTypeStruct Member Type <id> '" << inst->words[memberTypeIndex] + << "' is not a type."; return false; } if (SpvOpTypeStruct == memberType->opcode() && @@ -638,10 +637,10 @@ bool idUsage::isValid<SpvOpConstantComposite>(const spv_instruction_t* inst, if (!constituentResultType || componentType->opcode() != constituentResultType->opcode()) { DIAG(constituentIndex) - << "OpConstantComposite Constituent <id> '" - << inst->words[constituentIndex] - << "'s type does not match Result Type <id> '" << resultType->id() - << "'s vector element type."; + << "OpConstantComposite Constituent <id> '" + << inst->words[constituentIndex] + << "'s type does not match Result Type <id> '" << resultType->id() + << "'s vector element type."; return false; } } @@ -666,8 +665,9 @@ bool idUsage::isValid<SpvOpConstantComposite>(const spv_instruction_t* inst, for (size_t constituentIndex = 3; constituentIndex < inst->words.size(); constituentIndex++) { auto constituent = module_.FindDef(inst->words[constituentIndex]); - if (!constituent || !(SpvOpConstantComposite == constituent->opcode() || - SpvOpUndef == constituent->opcode())) { + if (!constituent || + !(SpvOpConstantComposite == constituent->opcode() || + SpvOpUndef == constituent->opcode())) { // The message says "... or undef" because the spec does not say // undef is a constant. DIAG(constituentIndex) << "OpConstantComposite Constituent <id> '" @@ -679,10 +679,10 @@ bool idUsage::isValid<SpvOpConstantComposite>(const spv_instruction_t* inst, assert(vector); if (columnType->opcode() != vector->opcode()) { DIAG(constituentIndex) - << "OpConstantComposite Constituent <id> '" - << inst->words[constituentIndex] - << "' type does not match Result Type <id> '" << resultType->id() - << "'s matrix column type."; + << "OpConstantComposite Constituent <id> '" + << inst->words[constituentIndex] + << "' type does not match Result Type <id> '" << resultType->id() + << "'s matrix column type."; return false; } auto vectorComponentType = module_.FindDef(vector->words()[2]); @@ -731,10 +731,10 @@ bool idUsage::isValid<SpvOpConstantComposite>(const spv_instruction_t* inst, assert(constituentType); if (elementType->id() != constituentType->id()) { DIAG(constituentIndex) - << "OpConstantComposite Constituent <id> '" - << inst->words[constituentIndex] - << "'s type does not match Result Type <id> '" << resultType->id() - << "'s array element type."; + << "OpConstantComposite Constituent <id> '" + << inst->words[constituentIndex] + << "'s type does not match Result Type <id> '" << resultType->id() + << "'s array element type."; return false; } } @@ -892,13 +892,12 @@ bool idUsage::isValid<SpvOpSampledImage>(const spv_instruction_t* inst, auto consumer_opcode = consumer_instr->opcode(); if (consumer_instr->block() != sampledImageInstr->block()) { DIAG(resultTypeIndex) - << "All OpSampledImage instructions must be in the same block in " + << "All OpSampledImage instructions must be in the same block in " "which their Result <id> are consumed. OpSampledImage Result " "Type <id> '" - << resultID - << "' has a consumer in a different basic " - "block. The consumer instruction <id> is '" - << consumer_id << "'."; + << resultID << "' has a consumer in a different basic " + "block. The consumer instruction <id> is '" + << consumer_id << "'."; return false; } // TODO: The following check is incomplete. We should also check that the @@ -966,10 +965,10 @@ bool idUsage::isValid<SpvOpSpecConstantComposite>(const spv_instruction_t* inst, if (!constituentResultType || componentType->opcode() != constituentResultType->opcode()) { DIAG(constituentIndex) - << "OpSpecConstantComposite Constituent <id> '" - << inst->words[constituentIndex] - << "'s type does not match Result Type <id> '" << resultType->id() - << "'s vector element type."; + << "OpSpecConstantComposite Constituent <id> '" + << inst->words[constituentIndex] + << "'s type does not match Result Type <id> '" << resultType->id() + << "'s vector element type."; return false; } } @@ -995,9 +994,10 @@ bool idUsage::isValid<SpvOpSpecConstantComposite>(const spv_instruction_t* inst, constituentIndex++) { auto constituent = module_.FindDef(inst->words[constituentIndex]); auto constituentOpCode = constituent->opcode(); - if (!constituent || !(SpvOpSpecConstantComposite == constituentOpCode || - SpvOpConstantComposite == constituentOpCode || - SpvOpUndef == constituentOpCode)) { + if (!constituent || + !(SpvOpSpecConstantComposite == constituentOpCode || + SpvOpConstantComposite == constituentOpCode || + SpvOpUndef == constituentOpCode)) { // The message says "... or undef" because the spec does not say // undef is a constant. DIAG(constituentIndex) << "OpSpecConstantComposite Constituent <id> '" @@ -1009,10 +1009,10 @@ bool idUsage::isValid<SpvOpSpecConstantComposite>(const spv_instruction_t* inst, assert(vector); if (columnType->opcode() != vector->opcode()) { DIAG(constituentIndex) - << "OpSpecConstantComposite Constituent <id> '" - << inst->words[constituentIndex] - << "' type does not match Result Type <id> '" << resultType->id() - << "'s matrix column type."; + << "OpSpecConstantComposite Constituent <id> '" + << inst->words[constituentIndex] + << "' type does not match Result Type <id> '" << resultType->id() + << "'s matrix column type."; return false; } auto vectorComponentType = module_.FindDef(vector->words()[2]); @@ -1062,10 +1062,10 @@ bool idUsage::isValid<SpvOpSpecConstantComposite>(const spv_instruction_t* inst, assert(constituentType); if (elementType->id() != constituentType->id()) { DIAG(constituentIndex) - << "OpSpecConstantComposite Constituent <id> '" - << inst->words[constituentIndex] - << "'s type does not match Result Type <id> '" << resultType->id() - << "'s array element type."; + << "OpSpecConstantComposite Constituent <id> '" + << inst->words[constituentIndex] + << "'s type does not match Result Type <id> '" << resultType->id() + << "'s array element type."; return false; } } @@ -1139,8 +1139,8 @@ bool idUsage::isValid<SpvOpVariable>(const spv_instruction_t* inst, initialiser && spvOpcodeIsConstant(initialiser->opcode()); if (!initialiser || !(is_constant || is_module_scope_var)) { DIAG(initialiserIndex) - << "OpVariable Initializer <id> '" << inst->words[initialiserIndex] - << "' is not a constant or module-scope variable."; + << "OpVariable Initializer <id> '" << inst->words[initialiserIndex] + << "' is not a constant or module-scope variable."; return false; } } @@ -1227,15 +1227,20 @@ bool idUsage::isValid<SpvOpStore>(const spv_instruction_t* inst, { uint32_t dataType; uint32_t storageClass; - if (!module_.GetPointerTypeInfo(pointerType->id(), &dataType, &storageClass)) { - DIAG(pointerIndex) << "OpStore Pointer <id> '"<< inst->words[pointerIndex] << "' is not pointer type"; + if (!module_.GetPointerTypeInfo(pointerType->id(), &dataType, + &storageClass)) { + DIAG(pointerIndex) << "OpStore Pointer <id> '" + << inst->words[pointerIndex] + << "' is not pointer type"; return false; } if (storageClass == SpvStorageClassUniformConstant || storageClass == SpvStorageClassInput || storageClass == SpvStorageClassPushConstant) { - DIAG(pointerIndex) << "OpStore Pointer <id> '" << inst->words[pointerIndex] << "' storage class is read-only"; + DIAG(pointerIndex) << "OpStore Pointer <id> '" + << inst->words[pointerIndex] + << "' storage class is read-only"; return false; } } @@ -1256,9 +1261,9 @@ bool idUsage::isValid<SpvOpStore>(const spv_instruction_t* inst, } if (type->id() != objectType->id()) { - if (!module_.options()->relax_struct_store - || type->opcode() != SpvOpTypeStruct - || objectType->opcode() != SpvOpTypeStruct) { + if (!module_.options()->relax_struct_store || + type->opcode() != SpvOpTypeStruct || + objectType->opcode() != SpvOpTypeStruct) { DIAG(pointerIndex) << "OpStore Pointer <id> '" << inst->words[pointerIndex] << "'s type does not match Object <id> '" @@ -1490,9 +1495,8 @@ bool idUsage::isValid<SpvOpAccessChain>(const spv_instruction_t* inst, } default: { // Give an error. reached non-composite type while indexes still remain. - DIAG(i) << instr_name - << " reached non-composite type while indexes " - "still remain to be traversed."; + DIAG(i) << instr_name << " reached non-composite type while indexes " + "still remain to be traversed."; return false; } } @@ -1568,8 +1572,8 @@ bool idUsage::isValid<SpvOpFunction>(const spv_instruction_t* inst, auto functionType = module_.FindDef(inst->words[functionTypeIndex]); if (!functionType || SpvOpTypeFunction != functionType->opcode()) { DIAG(functionTypeIndex) - << "OpFunction Function Type <id> '" << inst->words[functionTypeIndex] - << "' is not a function type."; + << "OpFunction Function Type <id> '" << inst->words[functionTypeIndex] + << "' is not a function type."; return false; } auto returnType = module_.FindDef(functionType->words()[2]); @@ -1825,9 +1829,8 @@ bool walkCompositeTypeHierarchy( } default: { // Give an error. reached non-composite type while indexes still remain. - *error << instr_name() - << " reached non-composite type while indexes " - "still remain to be traversed."; + *error << instr_name() << " reached non-composite type while indexes " + "still remain to be traversed."; return false; } } @@ -1952,13 +1955,12 @@ bool idUsage::isValid<SpvOpCompositeInsert>(const spv_instruction_t* inst, auto objectTypeInstr = module_.FindDef(objectInstr->type_id()); if (indexedTypeInstr->id() != objectTypeInstr->id()) { DIAG(objectIdIndex) - << "The Object type (Op" - << spvOpcodeString(static_cast<SpvOp>(objectTypeInstr->opcode())) - << ") in " << instr_name() - << " does not match the type that results " - "from indexing into the Composite (Op" - << spvOpcodeString(static_cast<SpvOp>(indexedTypeInstr->opcode())) - << ")."; + << "The Object type (Op" + << spvOpcodeString(static_cast<SpvOp>(objectTypeInstr->opcode())) + << ") in " << instr_name() << " does not match the type that results " + "from indexing into the Composite (Op" + << spvOpcodeString(static_cast<SpvOp>(indexedTypeInstr->opcode())) + << ")."; return false; } @@ -2056,16 +2058,16 @@ bool idUsage::isValid<OpBranch>(const spv_instruction_t *inst, #endif template <> -bool idUsage::isValid<SpvOpBranchConditional>( - const spv_instruction_t *inst, const spv_opcode_desc) { +bool idUsage::isValid<SpvOpBranchConditional>(const spv_instruction_t* inst, + const spv_opcode_desc) { const size_t numOperands = inst->words.size() - 1; const size_t condOperandIndex = 1; const size_t targetTrueIndex = 2; const size_t targetFalseIndex = 3; - // num_operands is either 3 or 5 --- if 5, the last two need to be literal integers - if (numOperands != 3 && - numOperands != 5) { + // num_operands is either 3 or 5 --- if 5, the last two need to be literal + // integers + if (numOperands != 3 && numOperands != 5) { DIAG(0) << "OpBranchConditional requires either 3 or 5 parameters"; return false; } @@ -2075,22 +2077,26 @@ bool idUsage::isValid<SpvOpBranchConditional>( // grab the condition operand and check that it is a bool const auto condOp = module_.FindDef(inst->words[condOperandIndex]); if (!condOp || !module_.IsBoolScalarType(condOp->type_id())) { - DIAG(0) << "Condition operand for OpBranchConditional must be of boolean type"; + DIAG(0) + << "Condition operand for OpBranchConditional must be of boolean type"; ret = false; } // target operands must be OpLabel - // note that we don't need to check that the target labels are in the same function, + // note that we don't need to check that the target labels are in the same + // function, // PerformCfgChecks already checks for that const auto targetOpTrue = module_.FindDef(inst->words[targetTrueIndex]); if (!targetOpTrue || SpvOpLabel != targetOpTrue->opcode()) { - DIAG(0) << "The 'True Label' operand for OpBranchConditional must be the ID of an OpLabel instruction"; + DIAG(0) << "The 'True Label' operand for OpBranchConditional must be the " + "ID of an OpLabel instruction"; ret = false; } const auto targetOpFalse = module_.FindDef(inst->words[targetFalseIndex]); if (!targetOpFalse || SpvOpLabel != targetOpFalse->opcode()) { - DIAG(0) << "The 'False Label' operand for OpBranchConditional must be the ID of an OpLabel instruction"; + DIAG(0) << "The 'False Label' operand for OpBranchConditional must be the " + "ID of an OpLabel instruction"; ret = false; } @@ -2723,9 +2729,9 @@ bool idUsage::HaveLayoutCompatibleMembers(const libspirv::Instruction* type1, bool idUsage::HaveSameLayoutDecorations(const libspirv::Instruction* type1, const libspirv::Instruction* type2) { assert(type1->opcode() == SpvOpTypeStruct && - "type1 must be and OpTypeStruct instruction."); + "type1 must be and OpTypeStruct instruction."); assert(type2->opcode() == SpvOpTypeStruct && - "type2 must be and OpTypeStruct instruction."); + "type2 must be and OpTypeStruct instruction."); const std::vector<Decoration>& type1_decorations = module_.id_decorations(type1->id()); const std::vector<Decoration>& type2_decorations = @@ -2915,8 +2921,8 @@ spv_result_t IdPass(ValidationState_t& _, ret = _.ForwardDeclareId(operand_word); } else { ret = _.diag(SPV_ERROR_INVALID_ID) - << "ID " << _.getIdName(operand_word) - << " has not been defined"; + << "ID " << _.getIdName(operand_word) + << " has not been defined"; } break; default: diff --git a/source/validate_logicals.cpp b/source/validate_logicals.cpp index 1a3fb148..766fd26a 100644 --- a/source/validate_logicals.cpp +++ b/source/validate_logicals.cpp @@ -38,11 +38,10 @@ inline uint32_t GetOperandWord(const spv_parsed_instruction_t* inst, // Returns the type id of instruction operand at |operand_index|. // The operand is expected to be an id. inline uint32_t GetOperandTypeId(ValidationState_t& _, - const spv_parsed_instruction_t* inst, - size_t operand_index) { + const spv_parsed_instruction_t* inst, + size_t operand_index) { return _.GetTypeId(GetOperandWord(inst, operand_index)); } - } // Validates correctness of logical instructions. @@ -56,14 +55,14 @@ spv_result_t LogicalsPass(ValidationState_t& _, case SpvOpAll: { if (!_.IsBoolScalarType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected bool scalar type as Result Type: " - << spvOpcodeString(opcode); + << "Expected bool scalar type as Result Type: " + << spvOpcodeString(opcode); const uint32_t vector_type = GetOperandTypeId(_, inst, 2); if (!vector_type || !_.IsBoolVectorType(vector_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected operand to be vector bool: " - << spvOpcodeString(opcode); + << "Expected operand to be vector bool: " + << spvOpcodeString(opcode); break; } @@ -73,28 +72,27 @@ spv_result_t LogicalsPass(ValidationState_t& _, case SpvOpIsFinite: case SpvOpIsNormal: case SpvOpSignBitSet: { - if (!_.IsBoolScalarType(result_type) && - !_.IsBoolVectorType(result_type)) + if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected bool scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected bool scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t operand_type = GetOperandTypeId(_, inst, 2); if (!operand_type || (!_.IsFloatScalarType(operand_type) && - !_.IsFloatVectorType(operand_type))) + !_.IsFloatVectorType(operand_type))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected operand to be scalar or vector float: " - << spvOpcodeString(opcode); + << "Expected operand to be scalar or vector float: " + << spvOpcodeString(opcode); if (_.GetDimension(result_type) != _.GetDimension(operand_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected vector sizes of Result Type and the operand to be equal: " - << spvOpcodeString(opcode); + << "Expected vector sizes of Result Type and the operand to be " + "equal: " + << spvOpcodeString(opcode); break; } - case SpvOpFOrdEqual: case SpvOpFUnordEqual: case SpvOpFOrdNotEqual: @@ -110,28 +108,28 @@ spv_result_t LogicalsPass(ValidationState_t& _, case SpvOpLessOrGreater: case SpvOpOrdered: case SpvOpUnordered: { - if (!_.IsBoolScalarType(result_type) && - !_.IsBoolVectorType(result_type)) + if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected bool scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected bool scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t left_operand_type = GetOperandTypeId(_, inst, 2); if (!left_operand_type || (!_.IsFloatScalarType(left_operand_type) && !_.IsFloatVectorType(left_operand_type))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected operands to be scalar or vector float: " - << spvOpcodeString(opcode); + << "Expected operands to be scalar or vector float: " + << spvOpcodeString(opcode); if (_.GetDimension(result_type) != _.GetDimension(left_operand_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected vector sizes of Result Type and the operands to be equal: " - << spvOpcodeString(opcode); + << "Expected vector sizes of Result Type and the operands to be " + "equal: " + << spvOpcodeString(opcode); if (left_operand_type != GetOperandTypeId(_, inst, 3)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected left and right operands to have the same type: " - << spvOpcodeString(opcode); + << "Expected left and right operands to have the same type: " + << spvOpcodeString(opcode); break; } @@ -140,32 +138,30 @@ spv_result_t LogicalsPass(ValidationState_t& _, case SpvOpLogicalNotEqual: case SpvOpLogicalOr: case SpvOpLogicalAnd: { - if (!_.IsBoolScalarType(result_type) && - !_.IsBoolVectorType(result_type)) + if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected bool scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected bool scalar or vector type as Result Type: " + << spvOpcodeString(opcode); if (result_type != GetOperandTypeId(_, inst, 2) || result_type != GetOperandTypeId(_, inst, 3)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected both operands to be of Result Type: " - << spvOpcodeString(opcode); + << "Expected both operands to be of Result Type: " + << spvOpcodeString(opcode); break; } case SpvOpLogicalNot: { - if (!_.IsBoolScalarType(result_type) && - !_.IsBoolVectorType(result_type)) + if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected bool scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected bool scalar or vector type as Result Type: " + << spvOpcodeString(opcode); if (result_type != GetOperandTypeId(_, inst, 2)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected operand to be of Result Type: " - << spvOpcodeString(opcode); + << "Expected operand to be of Result Type: " + << spvOpcodeString(opcode); break; } @@ -182,8 +178,8 @@ spv_result_t LogicalsPass(ValidationState_t& _, if (!_.features().variable_pointers && !_.features().variable_pointers_storage_buffer) return _.diag(SPV_ERROR_INVALID_DATA) - << "Using pointers with OpSelect requires capability " - << "VariablePointers or VariablePointersStorageBuffer"; + << "Using pointers with OpSelect requires capability " + << "VariablePointers or VariablePointersStorageBuffer"; break; } @@ -200,8 +196,8 @@ spv_result_t LogicalsPass(ValidationState_t& _, default: { return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected scalar or vector type as Result Type: " + << spvOpcodeString(opcode); } } } @@ -213,18 +209,18 @@ spv_result_t LogicalsPass(ValidationState_t& _, if (!condition_type || (!_.IsBoolScalarType(condition_type) && !_.IsBoolVectorType(condition_type))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected bool scalar or vector type as condition: " - << spvOpcodeString(opcode); + << "Expected bool scalar or vector type as condition: " + << spvOpcodeString(opcode); if (_.GetDimension(condition_type) != dimension) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected vector sizes of Result Type and the condition to be" - << " equal: " << spvOpcodeString(opcode); + << "Expected vector sizes of Result Type and the condition to be" + << " equal: " << spvOpcodeString(opcode); if (result_type != left_type || result_type != right_type) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected both objects to be of Result Type: " - << spvOpcodeString(opcode); + << "Expected both objects to be of Result Type: " + << spvOpcodeString(opcode); break; } @@ -239,41 +235,41 @@ spv_result_t LogicalsPass(ValidationState_t& _, case SpvOpSGreaterThanEqual: case SpvOpSLessThan: case SpvOpSLessThanEqual: { - if (!_.IsBoolScalarType(result_type) && - !_.IsBoolVectorType(result_type)) + if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected bool scalar or vector type as Result Type: " - << spvOpcodeString(opcode); + << "Expected bool scalar or vector type as Result Type: " + << spvOpcodeString(opcode); const uint32_t left_type = GetOperandTypeId(_, inst, 2); const uint32_t right_type = GetOperandTypeId(_, inst, 3); - if (!left_type || (!_.IsIntScalarType(left_type) && - !_.IsIntVectorType(left_type))) + if (!left_type || + (!_.IsIntScalarType(left_type) && !_.IsIntVectorType(left_type))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected operands to be scalar or vector int: " - << spvOpcodeString(opcode); + << "Expected operands to be scalar or vector int: " + << spvOpcodeString(opcode); if (_.GetDimension(result_type) != _.GetDimension(left_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected vector sizes of Result Type and the operands to be" - << " equal: " << spvOpcodeString(opcode); + << "Expected vector sizes of Result Type and the operands to be" + << " equal: " << spvOpcodeString(opcode); - if (!right_type || (!_.IsIntScalarType(right_type) && - !_.IsIntVectorType(right_type))) + if (!right_type || + (!_.IsIntScalarType(right_type) && !_.IsIntVectorType(right_type))) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected operands to be scalar or vector int: " - << spvOpcodeString(opcode); + << "Expected operands to be scalar or vector int: " + << spvOpcodeString(opcode); if (_.GetDimension(result_type) != _.GetDimension(right_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected vector sizes of Result Type and the operands to be" - << " equal: " << spvOpcodeString(opcode); + << "Expected vector sizes of Result Type and the operands to be" + << " equal: " << spvOpcodeString(opcode); if (_.GetBitWidth(left_type) != _.GetBitWidth(right_type)) return _.diag(SPV_ERROR_INVALID_DATA) - << "Expected both operands to have the same component bit width: " - << spvOpcodeString(opcode); + << "Expected both operands to have the same component bit " + "width: " + << spvOpcodeString(opcode); break; } diff --git a/source/validate_type_unique.cpp b/source/validate_type_unique.cpp index 7b54200c..b7f77ed6 100644 --- a/source/validate_type_unique.cpp +++ b/source/validate_type_unique.cpp @@ -50,9 +50,9 @@ spv_result_t TypeUniquePass(ValidationState_t& _, if (!_.RegisterUniqueTypeDeclaration(*inst)) { return _.diag(SPV_ERROR_INVALID_DATA) - << "Duplicate non-aggregate type declarations are not allowed." - << " Opcode: " << spvOpcodeString(SpvOp(inst->opcode)) - << " id: " << inst->result_id; + << "Duplicate non-aggregate type declarations are not allowed." + << " Opcode: " << spvOpcodeString(SpvOp(inst->opcode)) + << " id: " << inst->result_id; } } diff --git a/tools/cfg/bin_to_dot.cpp b/tools/cfg/bin_to_dot.cpp index 06db6572..a7a2a203 100644 --- a/tools/cfg/bin_to_dot.cpp +++ b/tools/cfg/bin_to_dot.cpp @@ -81,7 +81,7 @@ class DotConverter { spv_result_t DotConverter::HandleInstruction( const spv_parsed_instruction_t& inst) { - switch(inst.opcode) { + switch (inst.opcode) { case SpvOpFunction: current_function_id_ = inst.result_id; seen_function_entry_block_ = false; diff --git a/tools/cfg/bin_to_dot.h b/tools/cfg/bin_to_dot.h index 69e24f4b..1181b252 100644 --- a/tools/cfg/bin_to_dot.h +++ b/tools/cfg/bin_to_dot.h @@ -24,4 +24,4 @@ spv_result_t BinaryToDot(const spv_const_context context, const uint32_t* words, size_t num_words, std::iostream* out, spv_diagnostic* diagnostic); -#endif // BIN_TO_DOT_H_ +#endif // BIN_TO_DOT_H_ diff --git a/tools/cfg/cfg.cpp b/tools/cfg/cfg.cpp index f609ddef..2d0bcfae 100644 --- a/tools/cfg/cfg.cpp +++ b/tools/cfg/cfg.cpp @@ -49,7 +49,7 @@ static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_2; int main(int argc, char** argv) { const char* inFile = nullptr; - const char* outFile = nullptr; // Stays nullptr if printing to stdout. + const char* outFile = nullptr; // Stays nullptr if printing to stdout. for (int argi = 1; argi < argc; ++argi) { if ('-' == argv[argi][0]) { @@ -110,7 +110,8 @@ int main(int argc, char** argv) { spv_diagnostic diagnostic = nullptr; std::stringstream ss; - auto error = BinaryToDot(context, contents.data(), contents.size(), &ss, &diagnostic); + auto error = + BinaryToDot(context, contents.data(), contents.size(), &ss, &diagnostic); if (error) { spvDiagnosticPrint(diagnostic); spvDiagnosticDestroy(diagnostic); diff --git a/tools/comp/markv.cpp b/tools/comp/markv.cpp index 23585e5b..d2d8ad4d 100644 --- a/tools/comp/markv.cpp +++ b/tools/comp/markv.cpp @@ -88,8 +88,7 @@ void DiagnosticsMessageHandler(spv_message_level_t level, const char*, case SPV_MSG_FATAL: case SPV_MSG_INTERNAL_ERROR: case SPV_MSG_ERROR: - std::cerr << "error: " << position.index << ": " << message - << std::endl; + std::cerr << "error: " << position.index << ": " << message << std::endl; break; case SPV_MSG_WARNING: std::cerr << "warning: " << position.index << ": " << message @@ -207,32 +206,34 @@ int main(int argc, char** argv) { if (!ReadFile<uint32_t>(input_filename, "rb", &spirv)) return 1; assert(!spirv.empty()); - if (SPV_SUCCESS != spvtools::SpirvToMarkv( - ctx.context, spirv, options, *model, DiagnosticsMessageHandler, - want_comments ? output_to_stderr : no_comments, - spvtools::MarkvDebugConsumer(), &markv)) { + if (SPV_SUCCESS != + spvtools::SpirvToMarkv(ctx.context, spirv, options, *model, + DiagnosticsMessageHandler, + want_comments ? output_to_stderr : no_comments, + spvtools::MarkvDebugConsumer(), &markv)) { std::cerr << "error: Failed to encode " << input_filename << " to MARK-V " << std::endl; return 1; } - if (!WriteFile<uint8_t>(output_filename, "wb", markv.data(), - markv.size())) return 1; + if (!WriteFile<uint8_t>(output_filename, "wb", markv.data(), markv.size())) + return 1; } else if (task == kDecode) { if (!ReadFile<uint8_t>(input_filename, "rb", &markv)) return 1; assert(!markv.empty()); - if (SPV_SUCCESS != spvtools::MarkvToSpirv( - ctx.context, markv, options, *model, DiagnosticsMessageHandler, - want_comments ? output_to_stderr : no_comments, - spvtools::MarkvDebugConsumer(), &spirv)) { + if (SPV_SUCCESS != + spvtools::MarkvToSpirv(ctx.context, markv, options, *model, + DiagnosticsMessageHandler, + want_comments ? output_to_stderr : no_comments, + spvtools::MarkvDebugConsumer(), &spirv)) { std::cerr << "error: Failed to decode " << input_filename << " to SPIR-V " << std::endl; return 1; } - if (!WriteFile<uint32_t>(output_filename, "wb", spirv.data(), - spirv.size())) return 1; + if (!WriteFile<uint32_t>(output_filename, "wb", spirv.data(), spirv.size())) + return 1; } else if (task == kTest) { if (!ReadFile<uint32_t>(input_filename, "rb", &spirv)) return 1; assert(!spirv.empty()); @@ -241,8 +242,8 @@ int main(int argc, char** argv) { spvtools::Optimizer optimizer(kSpvEnv); optimizer.RegisterPass(spvtools::CreateCompactIdsPass()); if (!optimizer.Run(spirv.data(), spirv.size(), &spirv_before)) { - std::cerr << "error: Optimizer failure on: " - << input_filename << std::endl; + std::cerr << "error: Optimizer failure on: " << input_filename + << std::endl; } std::vector<std::string> encoder_instruction_bits; @@ -252,19 +253,20 @@ int main(int argc, char** argv) { std::vector<std::string> decoder_instruction_comments; std::vector<std::vector<uint32_t>> decoder_instruction_words; - const auto encoder_debug_consumer = [&]( - const std::vector<uint32_t>& words, const std::string& bits, - const std::string& comment) { + const auto encoder_debug_consumer = [&](const std::vector<uint32_t>& words, + const std::string& bits, + const std::string& comment) { encoder_instruction_words.push_back(words); encoder_instruction_bits.push_back(bits); encoder_instruction_comments.push_back(comment); return true; }; - if (SPV_SUCCESS != spvtools::SpirvToMarkv( - ctx.context, spirv_before, options, *model, DiagnosticsMessageHandler, - want_comments ? output_to_stderr : no_comments, - encoder_debug_consumer, &markv)) { + if (SPV_SUCCESS != + spvtools::SpirvToMarkv(ctx.context, spirv_before, options, *model, + DiagnosticsMessageHandler, + want_comments ? output_to_stderr : no_comments, + encoder_debug_consumer, &markv)) { std::cerr << "error: Failed to encode " << input_filename << " to MARK-V " << std::endl; return 1; @@ -294,9 +296,9 @@ int main(int argc, char** argv) { } }; - const auto decoder_debug_consumer = [&]( - const std::vector<uint32_t>& words, const std::string& bits, - const std::string& comment) { + const auto decoder_debug_consumer = [&](const std::vector<uint32_t>& words, + const std::string& bits, + const std::string& comment) { const size_t inst_index = decoder_instruction_words.size(); if (inst_index >= encoder_instruction_words.size()) { write_bug_report(); @@ -313,7 +315,8 @@ int main(int argc, char** argv) { decoder_instruction_words[inst_index]) { write_bug_report(); std::cerr << "error: Words of the last decoded instruction differ from " - "reference: " << input_filename << std::endl; + "reference: " + << input_filename << std::endl; return false; } @@ -321,7 +324,8 @@ int main(int argc, char** argv) { decoder_instruction_bits[inst_index]) { write_bug_report(); std::cerr << "error: Bits of the last decoded instruction differ from " - "reference: " << input_filename << std::endl; + "reference: " + << input_filename << std::endl; return false; } return true; @@ -330,8 +334,8 @@ int main(int argc, char** argv) { std::vector<uint32_t> spirv_after; const spv_result_t decoding_result = spvtools::MarkvToSpirv( ctx.context, markv, options, *model, DiagnosticsMessageHandler, - want_comments ? output_to_stderr : no_comments, - decoder_debug_consumer, &spirv_after); + want_comments ? output_to_stderr : no_comments, decoder_debug_consumer, + &spirv_after); if (decoding_result == SPV_REQUESTED_TERMINATION) { std::cerr << "error: Decoding interrupted by the debugger: " diff --git a/tools/comp/markv_model_shader_default.cpp b/tools/comp/markv_model_shader_default.cpp index a58c103f..2021894d 100644 --- a/tools/comp/markv_model_shader_default.cpp +++ b/tools/comp/markv_model_shader_default.cpp @@ -17,9 +17,9 @@ #include <algorithm> #include <map> #include <memory> -#include <vector> #include <unordered_map> #include <unordered_set> +#include <vector> using spvutils::HuffmanCodec; diff --git a/tools/dis/dis.cpp b/tools/dis/dis.cpp index 9c14b07a..51ee4a05 100644 --- a/tools/dis/dis.cpp +++ b/tools/dis/dis.cpp @@ -13,7 +13,7 @@ // limitations under the License. #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) -#include <stdio.h> // Need fileno +#include <stdio.h> // Need fileno #include <unistd.h> #endif diff --git a/tools/stats/stats.cpp b/tools/stats/stats.cpp index 3eea9821..1e586d90 100644 --- a/tools/stats/stats.cpp +++ b/tools/stats/stats.cpp @@ -89,8 +89,7 @@ void DiagnosticsMessageHandler(spv_message_level_t level, const char*, case SPV_MSG_FATAL: case SPV_MSG_INTERNAL_ERROR: case SPV_MSG_ERROR: - std::cerr << "error: " << position.index << ": " << message - << std::endl; + std::cerr << "error: " << position.index << ": " << message << std::endl; break; case SPV_MSG_WARNING: std::cout << "warning: " << position.index << ": " << message @@ -133,25 +132,24 @@ int main(int argc, char** argv) { } else if (0 == strcmp(cur_arg, "--codegen_opcode_hist")) { codegen_opcode_hist = true; export_text = false; - } else if (0 == strcmp(cur_arg, - "--codegen_opcode_and_num_operands_hist")) { + } else if (0 == + strcmp(cur_arg, "--codegen_opcode_and_num_operands_hist")) { codegen_opcode_and_num_operands_hist = true; export_text = false; } else if (strcmp( - "--codegen_opcode_and_num_operands_markov_huffman_codecs", - cur_arg) == 0) { + "--codegen_opcode_and_num_operands_markov_huffman_codecs", + cur_arg) == 0) { codegen_opcode_and_num_operands_markov_huffman_codecs = true; export_text = false; - } else if (0 == strcmp(cur_arg, - "--codegen_literal_string_huffman_codecs")) { + } else if (0 == + strcmp(cur_arg, "--codegen_literal_string_huffman_codecs")) { codegen_literal_string_huffman_codecs = true; export_text = false; - } else if (0 == strcmp(cur_arg, - "--codegen_non_id_word_huffman_codecs")) { + } else if (0 == strcmp(cur_arg, "--codegen_non_id_word_huffman_codecs")) { codegen_non_id_word_huffman_codecs = true; export_text = false; - } else if (0 == strcmp(cur_arg, - "--codegen_id_descriptor_huffman_codecs")) { + } else if (0 == + strcmp(cur_arg, "--codegen_id_descriptor_huffman_codecs")) { codegen_id_descriptor_huffman_codecs = true; export_text = false; } else if (0 == strcmp(cur_arg, "--verbose") || @@ -199,8 +197,9 @@ int main(int argc, char** argv) { std::vector<uint32_t> contents; if (!ReadFile<uint32_t>(path, "rb", &contents)) return 1; - if (SPV_SUCCESS != libspirv::AggregateStats( - *ctx.context, contents.data(), contents.size(), nullptr, &stats)) { + if (SPV_SUCCESS != libspirv::AggregateStats(*ctx.context, contents.data(), + contents.size(), nullptr, + &stats)) { std::cerr << "error: Failed to aggregate stats for " << path << std::endl; return 1; } diff --git a/tools/stats/stats_analyzer.cpp b/tools/stats/stats_analyzer.cpp index b9d2c66c..da0b9e3c 100644 --- a/tools/stats/stats_analyzer.cpp +++ b/tools/stats/stats_analyzer.cpp @@ -23,13 +23,13 @@ #include <unordered_set> #include <vector> -#include "spirv/1.2/spirv.h" -#include "source/enum_string_mapping.h" #include "source/comp/markv_model.h" +#include "source/enum_string_mapping.h" #include "source/opcode.h" #include "source/operand.h" #include "source/spirv_constant.h" #include "source/util/huffman_codec.h" +#include "spirv/1.2/spirv.h" using libspirv::SpirvStats; using spvutils::HuffmanCodec; @@ -49,325 +49,325 @@ inline uint32_t CombineOpcodeAndNumOperands(uint32_t opcode, // Returns all SPIR-V v1.2 opcodes. std::vector<uint32_t> GetAllOpcodes() { return std::vector<uint32_t>({ - SpvOpNop, - SpvOpUndef, - SpvOpSourceContinued, - SpvOpSource, - SpvOpSourceExtension, - SpvOpName, - SpvOpMemberName, - SpvOpString, - SpvOpLine, - SpvOpExtension, - SpvOpExtInstImport, - SpvOpExtInst, - SpvOpMemoryModel, - SpvOpEntryPoint, - SpvOpExecutionMode, - SpvOpCapability, - SpvOpTypeVoid, - SpvOpTypeBool, - SpvOpTypeInt, - SpvOpTypeFloat, - SpvOpTypeVector, - SpvOpTypeMatrix, - SpvOpTypeImage, - SpvOpTypeSampler, - SpvOpTypeSampledImage, - SpvOpTypeArray, - SpvOpTypeRuntimeArray, - SpvOpTypeStruct, - SpvOpTypeOpaque, - SpvOpTypePointer, - SpvOpTypeFunction, - SpvOpTypeEvent, - SpvOpTypeDeviceEvent, - SpvOpTypeReserveId, - SpvOpTypeQueue, - SpvOpTypePipe, - SpvOpTypeForwardPointer, - SpvOpConstantTrue, - SpvOpConstantFalse, - SpvOpConstant, - SpvOpConstantComposite, - SpvOpConstantSampler, - SpvOpConstantNull, - SpvOpSpecConstantTrue, - SpvOpSpecConstantFalse, - SpvOpSpecConstant, - SpvOpSpecConstantComposite, - SpvOpSpecConstantOp, - SpvOpFunction, - SpvOpFunctionParameter, - SpvOpFunctionEnd, - SpvOpFunctionCall, - SpvOpVariable, - SpvOpImageTexelPointer, - SpvOpLoad, - SpvOpStore, - SpvOpCopyMemory, - SpvOpCopyMemorySized, - SpvOpAccessChain, - SpvOpInBoundsAccessChain, - SpvOpPtrAccessChain, - SpvOpArrayLength, - SpvOpGenericPtrMemSemantics, - SpvOpInBoundsPtrAccessChain, - SpvOpDecorate, - SpvOpMemberDecorate, - SpvOpDecorationGroup, - SpvOpGroupDecorate, - SpvOpGroupMemberDecorate, - SpvOpVectorExtractDynamic, - SpvOpVectorInsertDynamic, - SpvOpVectorShuffle, - SpvOpCompositeConstruct, - SpvOpCompositeExtract, - SpvOpCompositeInsert, - SpvOpCopyObject, - SpvOpTranspose, - SpvOpSampledImage, - SpvOpImageSampleImplicitLod, - SpvOpImageSampleExplicitLod, - SpvOpImageSampleDrefImplicitLod, - SpvOpImageSampleDrefExplicitLod, - SpvOpImageSampleProjImplicitLod, - SpvOpImageSampleProjExplicitLod, - SpvOpImageSampleProjDrefImplicitLod, - SpvOpImageSampleProjDrefExplicitLod, - SpvOpImageFetch, - SpvOpImageGather, - SpvOpImageDrefGather, - SpvOpImageRead, - SpvOpImageWrite, - SpvOpImage, - SpvOpImageQueryFormat, - SpvOpImageQueryOrder, - SpvOpImageQuerySizeLod, - SpvOpImageQuerySize, - SpvOpImageQueryLod, - SpvOpImageQueryLevels, - SpvOpImageQuerySamples, - SpvOpConvertFToU, - SpvOpConvertFToS, - SpvOpConvertSToF, - SpvOpConvertUToF, - SpvOpUConvert, - SpvOpSConvert, - SpvOpFConvert, - SpvOpQuantizeToF16, - SpvOpConvertPtrToU, - SpvOpSatConvertSToU, - SpvOpSatConvertUToS, - SpvOpConvertUToPtr, - SpvOpPtrCastToGeneric, - SpvOpGenericCastToPtr, - SpvOpGenericCastToPtrExplicit, - SpvOpBitcast, - SpvOpSNegate, - SpvOpFNegate, - SpvOpIAdd, - SpvOpFAdd, - SpvOpISub, - SpvOpFSub, - SpvOpIMul, - SpvOpFMul, - SpvOpUDiv, - SpvOpSDiv, - SpvOpFDiv, - SpvOpUMod, - SpvOpSRem, - SpvOpSMod, - SpvOpFRem, - SpvOpFMod, - SpvOpVectorTimesScalar, - SpvOpMatrixTimesScalar, - SpvOpVectorTimesMatrix, - SpvOpMatrixTimesVector, - SpvOpMatrixTimesMatrix, - SpvOpOuterProduct, - SpvOpDot, - SpvOpIAddCarry, - SpvOpISubBorrow, - SpvOpUMulExtended, - SpvOpSMulExtended, - SpvOpAny, - SpvOpAll, - SpvOpIsNan, - SpvOpIsInf, - SpvOpIsFinite, - SpvOpIsNormal, - SpvOpSignBitSet, - SpvOpLessOrGreater, - SpvOpOrdered, - SpvOpUnordered, - SpvOpLogicalEqual, - SpvOpLogicalNotEqual, - SpvOpLogicalOr, - SpvOpLogicalAnd, - SpvOpLogicalNot, - SpvOpSelect, - SpvOpIEqual, - SpvOpINotEqual, - SpvOpUGreaterThan, - SpvOpSGreaterThan, - SpvOpUGreaterThanEqual, - SpvOpSGreaterThanEqual, - SpvOpULessThan, - SpvOpSLessThan, - SpvOpULessThanEqual, - SpvOpSLessThanEqual, - SpvOpFOrdEqual, - SpvOpFUnordEqual, - SpvOpFOrdNotEqual, - SpvOpFUnordNotEqual, - SpvOpFOrdLessThan, - SpvOpFUnordLessThan, - SpvOpFOrdGreaterThan, - SpvOpFUnordGreaterThan, - SpvOpFOrdLessThanEqual, - SpvOpFUnordLessThanEqual, - SpvOpFOrdGreaterThanEqual, - SpvOpFUnordGreaterThanEqual, - SpvOpShiftRightLogical, - SpvOpShiftRightArithmetic, - SpvOpShiftLeftLogical, - SpvOpBitwiseOr, - SpvOpBitwiseXor, - SpvOpBitwiseAnd, - SpvOpNot, - SpvOpBitFieldInsert, - SpvOpBitFieldSExtract, - SpvOpBitFieldUExtract, - SpvOpBitReverse, - SpvOpBitCount, - SpvOpDPdx, - SpvOpDPdy, - SpvOpFwidth, - SpvOpDPdxFine, - SpvOpDPdyFine, - SpvOpFwidthFine, - SpvOpDPdxCoarse, - SpvOpDPdyCoarse, - SpvOpFwidthCoarse, - SpvOpEmitVertex, - SpvOpEndPrimitive, - SpvOpEmitStreamVertex, - SpvOpEndStreamPrimitive, - SpvOpControlBarrier, - SpvOpMemoryBarrier, - SpvOpAtomicLoad, - SpvOpAtomicStore, - SpvOpAtomicExchange, - SpvOpAtomicCompareExchange, - SpvOpAtomicCompareExchangeWeak, - SpvOpAtomicIIncrement, - SpvOpAtomicIDecrement, - SpvOpAtomicIAdd, - SpvOpAtomicISub, - SpvOpAtomicSMin, - SpvOpAtomicUMin, - SpvOpAtomicSMax, - SpvOpAtomicUMax, - SpvOpAtomicAnd, - SpvOpAtomicOr, - SpvOpAtomicXor, - SpvOpPhi, - SpvOpLoopMerge, - SpvOpSelectionMerge, - SpvOpLabel, - SpvOpBranch, - SpvOpBranchConditional, - SpvOpSwitch, - SpvOpKill, - SpvOpReturn, - SpvOpReturnValue, - SpvOpUnreachable, - SpvOpLifetimeStart, - SpvOpLifetimeStop, - SpvOpGroupAsyncCopy, - SpvOpGroupWaitEvents, - SpvOpGroupAll, - SpvOpGroupAny, - SpvOpGroupBroadcast, - SpvOpGroupIAdd, - SpvOpGroupFAdd, - SpvOpGroupFMin, - SpvOpGroupUMin, - SpvOpGroupSMin, - SpvOpGroupFMax, - SpvOpGroupUMax, - SpvOpGroupSMax, - SpvOpReadPipe, - SpvOpWritePipe, - SpvOpReservedReadPipe, - SpvOpReservedWritePipe, - SpvOpReserveReadPipePackets, - SpvOpReserveWritePipePackets, - SpvOpCommitReadPipe, - SpvOpCommitWritePipe, - SpvOpIsValidReserveId, - SpvOpGetNumPipePackets, - SpvOpGetMaxPipePackets, - SpvOpGroupReserveReadPipePackets, - SpvOpGroupReserveWritePipePackets, - SpvOpGroupCommitReadPipe, - SpvOpGroupCommitWritePipe, - SpvOpEnqueueMarker, - SpvOpEnqueueKernel, - SpvOpGetKernelNDrangeSubGroupCount, - SpvOpGetKernelNDrangeMaxSubGroupSize, - SpvOpGetKernelWorkGroupSize, - SpvOpGetKernelPreferredWorkGroupSizeMultiple, - SpvOpRetainEvent, - SpvOpReleaseEvent, - SpvOpCreateUserEvent, - SpvOpIsValidEvent, - SpvOpSetUserEventStatus, - SpvOpCaptureEventProfilingInfo, - SpvOpGetDefaultQueue, - SpvOpBuildNDRange, - SpvOpImageSparseSampleImplicitLod, - SpvOpImageSparseSampleExplicitLod, - SpvOpImageSparseSampleDrefImplicitLod, - SpvOpImageSparseSampleDrefExplicitLod, - SpvOpImageSparseSampleProjImplicitLod, - SpvOpImageSparseSampleProjExplicitLod, - SpvOpImageSparseSampleProjDrefImplicitLod, - SpvOpImageSparseSampleProjDrefExplicitLod, - SpvOpImageSparseFetch, - SpvOpImageSparseGather, - SpvOpImageSparseDrefGather, - SpvOpImageSparseTexelsResident, - SpvOpNoLine, - SpvOpAtomicFlagTestAndSet, - SpvOpAtomicFlagClear, - SpvOpImageSparseRead, - SpvOpSizeOf, - SpvOpTypePipeStorage, - SpvOpConstantPipeStorage, - SpvOpCreatePipeFromPipeStorage, - SpvOpGetKernelLocalSizeForSubgroupCount, - SpvOpGetKernelMaxNumSubgroups, - SpvOpTypeNamedBarrier, - SpvOpNamedBarrierInitialize, - SpvOpMemoryNamedBarrier, - SpvOpModuleProcessed, - SpvOpExecutionModeId, - SpvOpDecorateId, - SpvOpSubgroupBallotKHR, - SpvOpSubgroupFirstInvocationKHR, - SpvOpSubgroupAllKHR, - SpvOpSubgroupAnyKHR, - SpvOpSubgroupAllEqualKHR, - SpvOpSubgroupReadInvocationKHR, + SpvOpNop, + SpvOpUndef, + SpvOpSourceContinued, + SpvOpSource, + SpvOpSourceExtension, + SpvOpName, + SpvOpMemberName, + SpvOpString, + SpvOpLine, + SpvOpExtension, + SpvOpExtInstImport, + SpvOpExtInst, + SpvOpMemoryModel, + SpvOpEntryPoint, + SpvOpExecutionMode, + SpvOpCapability, + SpvOpTypeVoid, + SpvOpTypeBool, + SpvOpTypeInt, + SpvOpTypeFloat, + SpvOpTypeVector, + SpvOpTypeMatrix, + SpvOpTypeImage, + SpvOpTypeSampler, + SpvOpTypeSampledImage, + SpvOpTypeArray, + SpvOpTypeRuntimeArray, + SpvOpTypeStruct, + SpvOpTypeOpaque, + SpvOpTypePointer, + SpvOpTypeFunction, + SpvOpTypeEvent, + SpvOpTypeDeviceEvent, + SpvOpTypeReserveId, + SpvOpTypeQueue, + SpvOpTypePipe, + SpvOpTypeForwardPointer, + SpvOpConstantTrue, + SpvOpConstantFalse, + SpvOpConstant, + SpvOpConstantComposite, + SpvOpConstantSampler, + SpvOpConstantNull, + SpvOpSpecConstantTrue, + SpvOpSpecConstantFalse, + SpvOpSpecConstant, + SpvOpSpecConstantComposite, + SpvOpSpecConstantOp, + SpvOpFunction, + SpvOpFunctionParameter, + SpvOpFunctionEnd, + SpvOpFunctionCall, + SpvOpVariable, + SpvOpImageTexelPointer, + SpvOpLoad, + SpvOpStore, + SpvOpCopyMemory, + SpvOpCopyMemorySized, + SpvOpAccessChain, + SpvOpInBoundsAccessChain, + SpvOpPtrAccessChain, + SpvOpArrayLength, + SpvOpGenericPtrMemSemantics, + SpvOpInBoundsPtrAccessChain, + SpvOpDecorate, + SpvOpMemberDecorate, + SpvOpDecorationGroup, + SpvOpGroupDecorate, + SpvOpGroupMemberDecorate, + SpvOpVectorExtractDynamic, + SpvOpVectorInsertDynamic, + SpvOpVectorShuffle, + SpvOpCompositeConstruct, + SpvOpCompositeExtract, + SpvOpCompositeInsert, + SpvOpCopyObject, + SpvOpTranspose, + SpvOpSampledImage, + SpvOpImageSampleImplicitLod, + SpvOpImageSampleExplicitLod, + SpvOpImageSampleDrefImplicitLod, + SpvOpImageSampleDrefExplicitLod, + SpvOpImageSampleProjImplicitLod, + SpvOpImageSampleProjExplicitLod, + SpvOpImageSampleProjDrefImplicitLod, + SpvOpImageSampleProjDrefExplicitLod, + SpvOpImageFetch, + SpvOpImageGather, + SpvOpImageDrefGather, + SpvOpImageRead, + SpvOpImageWrite, + SpvOpImage, + SpvOpImageQueryFormat, + SpvOpImageQueryOrder, + SpvOpImageQuerySizeLod, + SpvOpImageQuerySize, + SpvOpImageQueryLod, + SpvOpImageQueryLevels, + SpvOpImageQuerySamples, + SpvOpConvertFToU, + SpvOpConvertFToS, + SpvOpConvertSToF, + SpvOpConvertUToF, + SpvOpUConvert, + SpvOpSConvert, + SpvOpFConvert, + SpvOpQuantizeToF16, + SpvOpConvertPtrToU, + SpvOpSatConvertSToU, + SpvOpSatConvertUToS, + SpvOpConvertUToPtr, + SpvOpPtrCastToGeneric, + SpvOpGenericCastToPtr, + SpvOpGenericCastToPtrExplicit, + SpvOpBitcast, + SpvOpSNegate, + SpvOpFNegate, + SpvOpIAdd, + SpvOpFAdd, + SpvOpISub, + SpvOpFSub, + SpvOpIMul, + SpvOpFMul, + SpvOpUDiv, + SpvOpSDiv, + SpvOpFDiv, + SpvOpUMod, + SpvOpSRem, + SpvOpSMod, + SpvOpFRem, + SpvOpFMod, + SpvOpVectorTimesScalar, + SpvOpMatrixTimesScalar, + SpvOpVectorTimesMatrix, + SpvOpMatrixTimesVector, + SpvOpMatrixTimesMatrix, + SpvOpOuterProduct, + SpvOpDot, + SpvOpIAddCarry, + SpvOpISubBorrow, + SpvOpUMulExtended, + SpvOpSMulExtended, + SpvOpAny, + SpvOpAll, + SpvOpIsNan, + SpvOpIsInf, + SpvOpIsFinite, + SpvOpIsNormal, + SpvOpSignBitSet, + SpvOpLessOrGreater, + SpvOpOrdered, + SpvOpUnordered, + SpvOpLogicalEqual, + SpvOpLogicalNotEqual, + SpvOpLogicalOr, + SpvOpLogicalAnd, + SpvOpLogicalNot, + SpvOpSelect, + SpvOpIEqual, + SpvOpINotEqual, + SpvOpUGreaterThan, + SpvOpSGreaterThan, + SpvOpUGreaterThanEqual, + SpvOpSGreaterThanEqual, + SpvOpULessThan, + SpvOpSLessThan, + SpvOpULessThanEqual, + SpvOpSLessThanEqual, + SpvOpFOrdEqual, + SpvOpFUnordEqual, + SpvOpFOrdNotEqual, + SpvOpFUnordNotEqual, + SpvOpFOrdLessThan, + SpvOpFUnordLessThan, + SpvOpFOrdGreaterThan, + SpvOpFUnordGreaterThan, + SpvOpFOrdLessThanEqual, + SpvOpFUnordLessThanEqual, + SpvOpFOrdGreaterThanEqual, + SpvOpFUnordGreaterThanEqual, + SpvOpShiftRightLogical, + SpvOpShiftRightArithmetic, + SpvOpShiftLeftLogical, + SpvOpBitwiseOr, + SpvOpBitwiseXor, + SpvOpBitwiseAnd, + SpvOpNot, + SpvOpBitFieldInsert, + SpvOpBitFieldSExtract, + SpvOpBitFieldUExtract, + SpvOpBitReverse, + SpvOpBitCount, + SpvOpDPdx, + SpvOpDPdy, + SpvOpFwidth, + SpvOpDPdxFine, + SpvOpDPdyFine, + SpvOpFwidthFine, + SpvOpDPdxCoarse, + SpvOpDPdyCoarse, + SpvOpFwidthCoarse, + SpvOpEmitVertex, + SpvOpEndPrimitive, + SpvOpEmitStreamVertex, + SpvOpEndStreamPrimitive, + SpvOpControlBarrier, + SpvOpMemoryBarrier, + SpvOpAtomicLoad, + SpvOpAtomicStore, + SpvOpAtomicExchange, + SpvOpAtomicCompareExchange, + SpvOpAtomicCompareExchangeWeak, + SpvOpAtomicIIncrement, + SpvOpAtomicIDecrement, + SpvOpAtomicIAdd, + SpvOpAtomicISub, + SpvOpAtomicSMin, + SpvOpAtomicUMin, + SpvOpAtomicSMax, + SpvOpAtomicUMax, + SpvOpAtomicAnd, + SpvOpAtomicOr, + SpvOpAtomicXor, + SpvOpPhi, + SpvOpLoopMerge, + SpvOpSelectionMerge, + SpvOpLabel, + SpvOpBranch, + SpvOpBranchConditional, + SpvOpSwitch, + SpvOpKill, + SpvOpReturn, + SpvOpReturnValue, + SpvOpUnreachable, + SpvOpLifetimeStart, + SpvOpLifetimeStop, + SpvOpGroupAsyncCopy, + SpvOpGroupWaitEvents, + SpvOpGroupAll, + SpvOpGroupAny, + SpvOpGroupBroadcast, + SpvOpGroupIAdd, + SpvOpGroupFAdd, + SpvOpGroupFMin, + SpvOpGroupUMin, + SpvOpGroupSMin, + SpvOpGroupFMax, + SpvOpGroupUMax, + SpvOpGroupSMax, + SpvOpReadPipe, + SpvOpWritePipe, + SpvOpReservedReadPipe, + SpvOpReservedWritePipe, + SpvOpReserveReadPipePackets, + SpvOpReserveWritePipePackets, + SpvOpCommitReadPipe, + SpvOpCommitWritePipe, + SpvOpIsValidReserveId, + SpvOpGetNumPipePackets, + SpvOpGetMaxPipePackets, + SpvOpGroupReserveReadPipePackets, + SpvOpGroupReserveWritePipePackets, + SpvOpGroupCommitReadPipe, + SpvOpGroupCommitWritePipe, + SpvOpEnqueueMarker, + SpvOpEnqueueKernel, + SpvOpGetKernelNDrangeSubGroupCount, + SpvOpGetKernelNDrangeMaxSubGroupSize, + SpvOpGetKernelWorkGroupSize, + SpvOpGetKernelPreferredWorkGroupSizeMultiple, + SpvOpRetainEvent, + SpvOpReleaseEvent, + SpvOpCreateUserEvent, + SpvOpIsValidEvent, + SpvOpSetUserEventStatus, + SpvOpCaptureEventProfilingInfo, + SpvOpGetDefaultQueue, + SpvOpBuildNDRange, + SpvOpImageSparseSampleImplicitLod, + SpvOpImageSparseSampleExplicitLod, + SpvOpImageSparseSampleDrefImplicitLod, + SpvOpImageSparseSampleDrefExplicitLod, + SpvOpImageSparseSampleProjImplicitLod, + SpvOpImageSparseSampleProjExplicitLod, + SpvOpImageSparseSampleProjDrefImplicitLod, + SpvOpImageSparseSampleProjDrefExplicitLod, + SpvOpImageSparseFetch, + SpvOpImageSparseGather, + SpvOpImageSparseDrefGather, + SpvOpImageSparseTexelsResident, + SpvOpNoLine, + SpvOpAtomicFlagTestAndSet, + SpvOpAtomicFlagClear, + SpvOpImageSparseRead, + SpvOpSizeOf, + SpvOpTypePipeStorage, + SpvOpConstantPipeStorage, + SpvOpCreatePipeFromPipeStorage, + SpvOpGetKernelLocalSizeForSubgroupCount, + SpvOpGetKernelMaxNumSubgroups, + SpvOpTypeNamedBarrier, + SpvOpNamedBarrierInitialize, + SpvOpMemoryNamedBarrier, + SpvOpModuleProcessed, + SpvOpExecutionModeId, + SpvOpDecorateId, + SpvOpSubgroupBallotKHR, + SpvOpSubgroupFirstInvocationKHR, + SpvOpSubgroupAllKHR, + SpvOpSubgroupAnyKHR, + SpvOpSubgroupAllEqualKHR, + SpvOpSubgroupReadInvocationKHR, }); } std::string GetVersionString(uint32_t word) { std::stringstream ss; - ss << "Version " << SPV_SPIRV_VERSION_MAJOR_PART(word) - << "." << SPV_SPIRV_VERSION_MINOR_PART(word); + ss << "Version " << SPV_SPIRV_VERSION_MAJOR_PART(word) << "." + << SPV_SPIRV_VERSION_MINOR_PART(word); return ss.str(); } @@ -429,10 +429,9 @@ void WriteFreq(std::ostream& out, const std::unordered_map<Key, double>& freq, }); for (const auto& pair : sorted_freq) { - if (pair.second < threshold) - break; - out << label_from_key(pair.first) << " " << pair.second * 100.0 - << "%" << std::endl; + if (pair.second < threshold) break; + out << label_from_key(pair.first) << " " << pair.second * 100.0 << "%" + << std::endl; } } @@ -521,8 +520,7 @@ void StatsAnalyzer::WriteConstantLiterals(std::ostream& out) { } void StatsAnalyzer::WriteOpcodeMarkov(std::ostream& out) { - if (stats_.opcode_markov_hist.empty()) - return; + if (stats_.opcode_markov_hist.empty()) return; const std::unordered_map<uint32_t, std::unordered_map<uint32_t, uint32_t>>& cue_to_hist = stats_.opcode_markov_hist[0]; @@ -530,18 +528,17 @@ void StatsAnalyzer::WriteOpcodeMarkov(std::ostream& out) { // Sort by prevalence of the opcodes in opcode_freq_ (descending). std::vector<std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>> sorted_cue_to_hist(cue_to_hist.begin(), cue_to_hist.end()); - std::sort(sorted_cue_to_hist.begin(), sorted_cue_to_hist.end(), - [this]( - const std::pair<uint32_t, - std::unordered_map<uint32_t, uint32_t>>& left, - const std::pair<uint32_t, - std::unordered_map<uint32_t, uint32_t>>& right) { - const double lf = opcode_freq_[left.first]; - const double rf = opcode_freq_[right.first]; - if (lf == rf) - return right.first > left.first; - return lf > rf; - }); + std::sort( + sorted_cue_to_hist.begin(), sorted_cue_to_hist.end(), + [this](const std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>& + left, + const std::pair<uint32_t, std::unordered_map<uint32_t, uint32_t>>& + right) { + const double lf = opcode_freq_[left.first]; + const double rf = opcode_freq_[right.first]; + if (lf == rf) return right.first > left.first; + return lf > rf; + }); for (const auto& kv : sorted_cue_to_hist) { const uint32_t cue = kv.first; @@ -555,8 +552,8 @@ void StatsAnalyzer::WriteOpcodeMarkov(std::ostream& out) { total += pair.second; } - std::vector<std::pair<uint32_t, uint32_t>> - sorted_hist(hist.begin(), hist.end()); + std::vector<std::pair<uint32_t, uint32_t>> sorted_hist(hist.begin(), + hist.end()); std::sort(sorted_hist.begin(), sorted_hist.end(), [](const std::pair<uint32_t, uint32_t>& left, const std::pair<uint32_t, uint32_t>& right) { @@ -593,10 +590,8 @@ void StatsAnalyzer::WriteCodegenOpcodeHist(std::ostream& out) { const uint32_t count = it == stats_.opcode_hist.end() ? 0 : it->second; const double kMaxValue = 1000.0; uint32_t value = uint32_t(kMaxValue * double(count) / double(total)); - if (value == 0) - value = 1; - out << " { SpvOp" << GetOpcodeString(opcode) - << ", " << value << " },\n"; + if (value == 0) value = 1; + out << " { SpvOp" << GetOpcodeString(opcode) << ", " << value << " },\n"; } // Add kMarkvNoneOfTheAbove as a signal for unknown opcode. @@ -608,7 +603,6 @@ void StatsAnalyzer::WriteCodegenOpcodeAndNumOperandsHist(std::ostream& out) { out << "std::map<uint64_t, uint32_t> GetOpcodeAndNumOperandsHist() {\n" << " return std::map<uint64_t, uint32_t>({\n"; - uint32_t total = 0; for (const auto& kv : stats_.opcode_and_num_operands_hist) { total += kv.second; @@ -630,13 +624,12 @@ void StatsAnalyzer::WriteCodegenOpcodeAndNumOperandsHist(std::ostream& out) { } out << " { CombineOpcodeAndNumOperands(SpvOp" - << spvOpcodeString(SpvOp(opcode)) - << ", " << num_operands << "), " << count << " },\n"; + << spvOpcodeString(SpvOp(opcode)) << ", " << num_operands << "), " + << count << " },\n"; } // Heuristic. - const uint32_t none_of_the_above = - std::max(1, int(left_out + total * 0.01)); + const uint32_t none_of_the_above = std::max(1, int(left_out + total * 0.01)); out << " { kMarkvNoneOfTheAbove, " << none_of_the_above << " },\n"; out << " });\n}\n"; } @@ -667,8 +660,7 @@ void StatsAnalyzer::WriteCodegenOpcodeAndNumOperandsMarkovHuffmanCodecs( const uint32_t opcode_and_num_operands = pair.first; const uint32_t opcode = opcode_and_num_operands & 0xFFFF; - if (opcode == SpvOpTypeStruct) - continue; + if (opcode == SpvOpTypeStruct) continue; const uint32_t num_operands = opcode_and_num_operands >> 16; const uint32_t count = pair.second; @@ -711,8 +703,7 @@ void StatsAnalyzer::WriteCodegenLiteralStringHuffmanCodecs(std::ostream& out) { for (const auto& kv : stats_.literal_strings_hist) { const uint32_t opcode = kv.first; - if (opcode == SpvOpName || opcode == SpvOpMemberName) - continue; + if (opcode == SpvOpName || opcode == SpvOpMemberName) continue; const double kOpcodeFrequentEnoughToAnalyze = 0.001; if (opcode_freq_[opcode] < kOpcodeFrequentEnoughToAnalyze) continue; @@ -806,16 +797,15 @@ void StatsAnalyzer::WriteCodegenNonIdWordHuffmanCodecs(std::ostream& out) { out << codec.SerializeToText(4); out << ");\n" << std::endl; out << " codecs.emplace(std::pair<uint32_t, uint32_t>(SpvOp" - << spvOpcodeString(SpvOp(opcode)) - << ", " << index << "), std::move(codec));\n"; + << spvOpcodeString(SpvOp(opcode)) << ", " << index + << "), std::move(codec));\n"; out << " }\n\n"; } out << " return codecs;\n}\n"; } -void StatsAnalyzer::WriteCodegenIdDescriptorHuffmanCodecs( - std::ostream& out) { +void StatsAnalyzer::WriteCodegenIdDescriptorHuffmanCodecs(std::ostream& out) { out << "std::map<std::pair<uint32_t, uint32_t>, " << "std::unique_ptr<HuffmanCodec<uint64_t>>>\n" << "GetIdDescriptorHuffmanCodecs() {\n" @@ -834,7 +824,6 @@ void StatsAnalyzer::WriteCodegenIdDescriptorHuffmanCodecs( const std::map<uint32_t, uint32_t>& hist = kv.second; - uint32_t total = 0; for (const auto& pair : hist) { total += pair.second; @@ -860,7 +849,6 @@ void StatsAnalyzer::WriteCodegenIdDescriptorHuffmanCodecs( processed_hist.emplace(kMarkvNoneOfTheAbove, std::max(1, int(left_out + total * 0.01))); - HuffmanCodec<uint64_t> codec(processed_hist); out << " {\n"; @@ -869,8 +857,8 @@ void StatsAnalyzer::WriteCodegenIdDescriptorHuffmanCodecs( out << codec.SerializeToText(4); out << ");\n" << std::endl; out << " codecs.emplace(std::pair<uint32_t, uint32_t>(SpvOp" - << spvOpcodeString(SpvOp(opcode)) - << ", " << index << "), std::move(codec));\n"; + << spvOpcodeString(SpvOp(opcode)) << ", " << index + << "), std::move(codec));\n"; out << " }\n\n"; } diff --git a/tools/stats/stats_analyzer.h b/tools/stats/stats_analyzer.h index 6cff20a0..a3b91bae 100644 --- a/tools/stats/stats_analyzer.h +++ b/tools/stats/stats_analyzer.h @@ -77,5 +77,4 @@ class StatsAnalyzer { std::unordered_map<uint32_t, double> opcode_freq_; }; - #endif // LIBSPIRV_TOOLS_STATS_STATS_ANALYZER_H_ |