mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 05:46:56 +01:00
Share CFG reachability for descriptor bounds analysis
This commit is contained in:
@@ -512,6 +512,28 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Block* FindBlock(uint32_t id) const {
|
||||||
|
const auto info = std::ranges::find(m_program.block_info, id, &BlockInfo::id);
|
||||||
|
return info == m_program.block_info.end()
|
||||||
|
? nullptr
|
||||||
|
: m_program.blocks[info - m_program.block_info.begin()];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanReach(const Block* start, const Block* target, const Block* avoid) const {
|
||||||
|
std::vector<const Block*> pending {start};
|
||||||
|
std::vector<const Block*> visited;
|
||||||
|
while (!pending.empty()) {
|
||||||
|
const auto* block = pending.back();
|
||||||
|
pending.pop_back();
|
||||||
|
if (block == nullptr || block == avoid ||
|
||||||
|
std::ranges::find(visited, block) != visited.end()) continue;
|
||||||
|
if (block == target) return true;
|
||||||
|
visited.push_back(block);
|
||||||
|
for (const auto* next: block->ImmSuccessors()) pending.push_back(next);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Value BoundedLoopCount(Value key, const Block* use) const {
|
Value BoundedLoopCount(Value key, const Block* use) const {
|
||||||
const auto* phi = key.Resolve().TryInstruction();
|
const auto* phi = key.Resolve().TryInstruction();
|
||||||
if (m_shader_writes || phi == nullptr || phi->GetOpcode() != ValueOpcode::Phi ||
|
if (m_shader_writes || phi == nullptr || phi->GetOpcode() != ValueOpcode::Phi ||
|
||||||
@@ -537,26 +559,6 @@ private:
|
|||||||
}
|
}
|
||||||
if (!induction) return {};
|
if (!induction) return {};
|
||||||
|
|
||||||
const auto find_block = [&](uint32_t id) -> const Block* {
|
|
||||||
const auto info = std::ranges::find(m_program.block_info, id, &BlockInfo::id);
|
|
||||||
return info == m_program.block_info.end()
|
|
||||||
? nullptr
|
|
||||||
: m_program.blocks[info - m_program.block_info.begin()];
|
|
||||||
};
|
|
||||||
const auto reaches = [&](const Block* start, const Block* target, const Block* avoid) {
|
|
||||||
std::vector<const Block*> pending {start};
|
|
||||||
std::vector<const Block*> visited;
|
|
||||||
while (!pending.empty()) {
|
|
||||||
const auto* block = pending.back();
|
|
||||||
pending.pop_back();
|
|
||||||
if (block == nullptr || block == avoid ||
|
|
||||||
std::ranges::find(visited, block) != visited.end()) continue;
|
|
||||||
if (block == target) return true;
|
|
||||||
visited.push_back(block);
|
|
||||||
for (const auto* next: block->ImmSuccessors()) pending.push_back(next);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
const auto contains = [&](auto&& self, Value value, const Inst* comparison) -> bool {
|
const auto contains = [&](auto&& self, Value value, const Inst* comparison) -> bool {
|
||||||
value = value.Resolve();
|
value = value.Resolve();
|
||||||
if (value.TryInstruction() == comparison) return true;
|
if (value.TryInstruction() == comparison) return true;
|
||||||
@@ -576,10 +578,10 @@ private:
|
|||||||
negated->GetOpcode() != ValueOpcode::LogicalNot ||
|
negated->GetOpcode() != ValueOpcode::LogicalNot ||
|
||||||
!contains(contains, negated->Arg(0), compare) ||
|
!contains(contains, negated->Arg(0), compare) ||
|
||||||
use == m_program.blocks[i] ||
|
use == m_program.blocks[i] ||
|
||||||
reaches(m_program.blocks.front(), use, m_program.blocks[i]) ||
|
CanReach(m_program.blocks.front(), use, m_program.blocks[i]) ||
|
||||||
reaches(phi->Parent(), use, m_program.blocks[i]) ||
|
CanReach(phi->Parent(), use, m_program.blocks[i]) ||
|
||||||
reaches(find_block(info.terminator.true_block), use, phi->Parent()) ||
|
CanReach(FindBlock(info.terminator.true_block), use, phi->Parent()) ||
|
||||||
!reaches(find_block(info.terminator.false_block), use, phi->Parent())) {
|
!CanReach(FindBlock(info.terminator.false_block), use, phi->Parent())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return compare->Arg(1);
|
return compare->Arg(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user