|
|
|
@ -46,7 +46,9 @@ using StorageBufferSet = |
|
|
|
using StorageInstVector = boost::container::small_vector<StorageInst, 24>; |
|
|
|
using VisitedBlocks = boost::container::flat_set<IR::Block*, std::less<IR::Block*>, |
|
|
|
boost::container::small_vector<IR::Block*, 4>>; |
|
|
|
using StorageWritesMap = std::map<StorageBufferAddr, bool>; |
|
|
|
using StorageWritesSet = |
|
|
|
boost::container::flat_set<StorageBufferAddr, std::less<StorageBufferAddr>, |
|
|
|
boost::container::small_vector<StorageBufferAddr, 16>>; |
|
|
|
|
|
|
|
/// Returns true when the instruction is a global memory instruction
|
|
|
|
bool IsGlobalMemory(const IR::Inst& inst) { |
|
|
|
@ -266,7 +268,7 @@ std::optional<StorageBufferAddr> Track(IR::Block* block, const IR::Value& value, |
|
|
|
|
|
|
|
/// Collects the storage buffer used by a global memory instruction and the instruction itself
|
|
|
|
void CollectStorageBuffers(IR::Block& block, IR::Inst& inst, StorageBufferSet& storage_buffer_set, |
|
|
|
StorageInstVector& to_replace, StorageWritesMap& writes_map) { |
|
|
|
StorageInstVector& to_replace, StorageWritesSet& writes_set) { |
|
|
|
// NVN puts storage buffers in a specific range, we have to bias towards these addresses to
|
|
|
|
// avoid getting false positives
|
|
|
|
static constexpr Bias nvn_bias{ |
|
|
|
@ -295,12 +297,8 @@ void CollectStorageBuffers(IR::Block& block, IR::Inst& inst, StorageBufferSet& s |
|
|
|
} |
|
|
|
} |
|
|
|
// Collect storage buffer and the instruction
|
|
|
|
const bool is_a_write{IsGlobalMemoryWrite(inst)}; |
|
|
|
auto it{writes_map.find(*storage_buffer)}; |
|
|
|
if (it == writes_map.end()) { |
|
|
|
writes_map[*storage_buffer] = is_a_write; |
|
|
|
} else { |
|
|
|
it->second = it->second || is_a_write; |
|
|
|
if (IsGlobalMemoryWrite(inst)) { |
|
|
|
writes_set.insert(*storage_buffer); |
|
|
|
} |
|
|
|
storage_buffer_set.insert(*storage_buffer); |
|
|
|
to_replace.push_back(StorageInst{ |
|
|
|
@ -375,14 +373,14 @@ void Replace(IR::Block& block, IR::Inst& inst, const IR::U32& storage_index, |
|
|
|
void GlobalMemoryToStorageBufferPass(IR::Program& program) { |
|
|
|
StorageBufferSet storage_buffers; |
|
|
|
StorageInstVector to_replace; |
|
|
|
StorageWritesMap writes_map; |
|
|
|
StorageWritesSet writes_set; |
|
|
|
|
|
|
|
for (IR::Block* const block : program.post_order_blocks) { |
|
|
|
for (IR::Inst& inst : block->Instructions()) { |
|
|
|
if (!IsGlobalMemory(inst)) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
CollectStorageBuffers(*block, inst, storage_buffers, to_replace, writes_map); |
|
|
|
CollectStorageBuffers(*block, inst, storage_buffers, to_replace, writes_set); |
|
|
|
} |
|
|
|
} |
|
|
|
Info& info{program.info}; |
|
|
|
@ -392,7 +390,7 @@ void GlobalMemoryToStorageBufferPass(IR::Program& program) { |
|
|
|
.cbuf_index{storage_buffer.index}, |
|
|
|
.cbuf_offset{storage_buffer.offset}, |
|
|
|
.count{1}, |
|
|
|
.is_written{writes_map[storage_buffer]}, |
|
|
|
.is_written{writes_set.contains(storage_buffer)}, |
|
|
|
}); |
|
|
|
++storage_index; |
|
|
|
} |
|
|
|
|