diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2019-01-10 16:04:01 +0300 |
---|---|---|
committer | Hans-Kristian Arntzen <post@arntzen-software.no> | 2019-01-10 16:04:01 +0300 |
commit | b629878f45ae4eead5dcccdc20e3eb52c25ba4fd (patch) | |
tree | 900b1c485506c314bda5464b60fdb4e6463ba2ff /spirv_cross_parsed_ir.cpp | |
parent | d92de00cc182a436f4c0340247bde088eee2c921 (diff) |
Make meta a hashmap.
A flat array was consuming way too much memory and was far too slow to
initialize properly with a very large ID bound (8 million IDs, showed up as #1 hotspot in perf).
Meta struct does not have to be in-order as we never iterate over it in
a meaningful way, so using a hashmap here is reasonable. Very few IDs
should need decorations or meta-data, so this should also be a quite
decent memory save.
For the pathological case, a 6x uplift was observed.
Diffstat (limited to 'spirv_cross_parsed_ir.cpp')
-rw-r--r-- | spirv_cross_parsed_ir.cpp | 120 |
1 files changed, 82 insertions, 38 deletions
diff --git a/spirv_cross_parsed_ir.cpp b/spirv_cross_parsed_ir.cpp index 6d80fcb3..82bc5611 100644 --- a/spirv_cross_parsed_ir.cpp +++ b/spirv_cross_parsed_ir.cpp @@ -26,7 +26,6 @@ namespace spirv_cross void ParsedIR::set_id_bounds(uint32_t bounds) { ids.resize(bounds); - meta.resize(bounds); block_meta.resize(bounds); } @@ -66,19 +65,24 @@ static string ensure_valid_identifier(const string &name, bool member) const string &ParsedIR::get_name(uint32_t id) const { - return meta[id].decoration.alias; + auto *m = find_meta(id); + if (m) + return m->decoration.alias; + else + return empty_string; } const string &ParsedIR::get_member_name(uint32_t id, uint32_t index) const { - auto &m = meta[id]; - if (index >= m.members.size()) + auto *m = find_meta(id); + if (m) { - static string empty; - return empty; + if (index >= m->members.size()) + return empty_string; + return m->members[index].alias; } - - return m.members[index].alias; + else + return empty_string; } void ParsedIR::set_name(uint32_t id, const string &name) @@ -274,7 +278,10 @@ Bitset ParsedIR::get_buffer_block_flags(const SPIRVariable &var) const // Some flags like non-writable, non-readable are actually found // as member decorations. If all members have a decoration set, propagate // the decoration up as a regular variable decoration. - Bitset base_flags = meta[var.self].decoration.decoration_flags; + Bitset base_flags; + auto *m = find_meta(var.self); + if (m) + base_flags = m->decoration.decoration_flags; if (type.member_types.empty()) return base_flags; @@ -289,14 +296,15 @@ Bitset ParsedIR::get_buffer_block_flags(const SPIRVariable &var) const const Bitset &ParsedIR::get_member_decoration_bitset(uint32_t id, uint32_t index) const { - auto &m = meta[id]; - if (index >= m.members.size()) + auto *m = find_meta(id); + if (m) { - static const Bitset cleared = {}; - return cleared; + if (index >= m->members.size()) + return cleared_bitset; + return m->members[index].decoration_flags; } - - return m.members[index].decoration_flags; + else + return cleared_bitset; } bool ParsedIR::has_decoration(uint32_t id, Decoration decoration) const @@ -306,7 +314,11 @@ bool ParsedIR::has_decoration(uint32_t id, Decoration decoration) const uint32_t ParsedIR::get_decoration(uint32_t id, Decoration decoration) const { - auto &dec = meta[id].decoration; + auto *m = find_meta(id); + if (!m) + return 0; + + auto &dec = m->decoration; if (!dec.decoration_flags.get(decoration)) return 0; @@ -343,11 +355,14 @@ uint32_t ParsedIR::get_decoration(uint32_t id, Decoration decoration) const const string &ParsedIR::get_decoration_string(uint32_t id, Decoration decoration) const { - auto &dec = meta[id].decoration; - static const string empty; + auto *m = find_meta(id); + if (!m) + return empty_string; + + auto &dec = m->decoration; if (!dec.decoration_flags.get(decoration)) - return empty; + return empty_string; switch (decoration) { @@ -355,7 +370,7 @@ const string &ParsedIR::get_decoration_string(uint32_t id, Decoration decoration return dec.hlsl_semantic; default: - return empty; + return empty_string; } } @@ -428,11 +443,14 @@ bool ParsedIR::has_member_decoration(uint32_t id, uint32_t index, Decoration dec uint32_t ParsedIR::get_member_decoration(uint32_t id, uint32_t index, Decoration decoration) const { - auto &m = meta[id]; - if (index >= m.members.size()) + auto *m = find_meta(id); + if (!m) return 0; - auto &dec = m.members[index]; + if (index >= m->members.size()) + return 0; + + auto &dec = m->members[index]; if (!dec.decoration_flags.get(decoration)) return 0; @@ -459,8 +477,14 @@ uint32_t ParsedIR::get_member_decoration(uint32_t id, uint32_t index, Decoration const Bitset &ParsedIR::get_decoration_bitset(uint32_t id) const { - auto &dec = meta[id].decoration; - return dec.decoration_flags; + auto *m = find_meta(id); + if (m) + { + auto &dec = m->decoration; + return dec.decoration_flags; + } + else + return cleared_bitset; } void ParsedIR::set_member_decoration_string(uint32_t id, uint32_t index, Decoration decoration, const string &argument) @@ -482,22 +506,25 @@ void ParsedIR::set_member_decoration_string(uint32_t id, uint32_t index, Decorat const string &ParsedIR::get_member_decoration_string(uint32_t id, uint32_t index, Decoration decoration) const { - static const string empty; - auto &m = meta[id]; - - if (!has_member_decoration(id, index, decoration)) - return empty; + auto *m = find_meta(id); + if (m) + { + if (!has_member_decoration(id, index, decoration)) + return empty_string; - auto &dec = m.members[index]; + auto &dec = m->members[index]; - switch (decoration) - { - case DecorationHlslSemanticGOOGLE: - return dec.hlsl_semantic; + switch (decoration) + { + case DecorationHlslSemanticGOOGLE: + return dec.hlsl_semantic; - default: - return empty; + default: + return empty_string; + } } + else + return empty_string; } void ParsedIR::unset_member_decoration(uint32_t id, uint32_t index, Decoration decoration) @@ -545,7 +572,6 @@ uint32_t ParsedIR::increase_bound_by(uint32_t incr_amount) auto curr_bound = ids.size(); auto new_bound = curr_bound + incr_amount; ids.resize(new_bound); - meta.resize(new_bound); block_meta.resize(new_bound); return uint32_t(curr_bound); } @@ -601,4 +627,22 @@ void ParsedIR::add_typed_id(Types type, uint32_t id) } } +const Meta *ParsedIR::find_meta(uint32_t id) const +{ + auto itr = meta.find(id); + if (itr != end(meta)) + return &itr->second; + else + return nullptr; +} + +Meta *ParsedIR::find_meta(uint32_t id) +{ + auto itr = meta.find(id); + if (itr != end(meta)) + return &itr->second; + else + return nullptr; +} + } // namespace spirv_cross |