Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/SPIRV-Cross.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2019-01-10 16:04:01 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2019-01-10 16:04:01 +0300
commitb629878f45ae4eead5dcccdc20e3eb52c25ba4fd (patch)
tree900b1c485506c314bda5464b60fdb4e6463ba2ff /spirv_cross_parsed_ir.cpp
parentd92de00cc182a436f4c0340247bde088eee2c921 (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.cpp120
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