Change DXIL ControlFlow to use a graph search instead of walking paths

Graph search is faster than walking paths
This commit is contained in:
Jake Turner
2025-08-20 13:41:03 +01:00
parent 046a86d5ab
commit 073eab90c9
3 changed files with 337 additions and 526 deletions
File diff suppressed because it is too large Load Diff
@@ -38,7 +38,7 @@ struct ControlFlow
public:
ControlFlow() = default;
ControlFlow(const rdcarray<rdcpair<uint32_t, uint32_t>> &links) { Construct(links); }
void Construct(const rdcarray<rdcpair<uint32_t, uint32_t>> &links);
void Construct(const rdcarray<BlockLink> &links);
rdcarray<uint32_t> GetUniformBlocks() const { return m_UniformBlocks; }
rdcarray<uint32_t> GetLoopBlocks() const { return m_LoopBlocks; }
rdcarray<uint32_t> GetDivergentBlocks() const { return m_DivergentBlocks; }
@@ -48,7 +48,7 @@ public:
return m_PartialConvergentBlocks;
}
uint32_t GetNextUniformBlock(uint32_t from) const;
bool IsForwardConnection(uint32_t from, uint32_t to) const;
bool IsConnected(uint32_t from, uint32_t to) const;
private:
typedef rdcarray<uint32_t> BlockPath;
@@ -60,55 +60,40 @@ private:
Connected,
};
enum PathType : uint32_t
struct Node
{
IncLoops = 0,
NoLoops = 1,
Count = 2
uint32_t blockId;
uint32_t idx;
rdcarray<Node *> parents;
rdcarray<Node *> children;
};
enum class DirectPathState
const Node *GetNode(const uint32_t blockId) const
{
None,
Single,
Multiple
};
return m_Nodes.data() + m_BlockIDsToIDx[blockId];
}
enum class RouteState
{
NoRoute,
RouteContainsBlock,
RouteDoesNotContainBlock,
};
void TraceBlockFlow(const Node *from, BlockPath &path);
bool BlockInAllPaths(uint32_t from, uint32_t to) const;
bool BlockInMultiplePaths(uint32_t from, uint32_t to) const;
bool TraceBlockFlow(const size_t pathsType, const uint32_t from, BlockPath &path);
bool BlockInAllPaths(const size_t pathsType, uint32_t block, uint32_t pathIdx,
int32_t startIdx) const;
int32_t BlockInAnyPath(const size_t pathsType, uint32_t block, uint32_t pathIdx, int32_t startIdx,
int32_t steps) const;
uint32_t BlockInMultipleUniquePaths(const size_t pathsType, uint32_t block, uint32_t pathIdx,
int32_t startIdx, BlockPath &route,
const uint32_t countPaths) const;
RouteState BlockInAllPossibleRoutes(const size_t pathsType, uint32_t to, uint32_t mustInclude,
uint32_t pathIdx, uint32_t startIdx, BlockArray &route) const;
bool IsBlockConnected(const size_t pathsType, uint32_t from, uint32_t to) const;
bool AnyPath(uint32_t from, uint32_t to) const;
bool AllPathsContainBlock(uint32_t from, uint32_t to, uint32_t mustInclude) const;
DirectPathState ComputeDirectPathState(uint32_t from, uint32_t to,
const rdcarray<uint32_t> *pathIdxsToCheck) const;
int32_t BlockInAnyPathSlow(uint32_t block, uint32_t pathIdx, int32_t startIdx, int32_t steps) const;
uint32_t PATH_END = ~0U;
rdcarray<Node> m_Nodes;
rdcarray<uint32_t> m_BlockIDsToIDx;
mutable rdcarray<uint8_t> m_TracedNodes;
std::unordered_set<uint32_t> m_Blocks;
rdcarray<BlockArray> m_BlockOutLinks;
rdcarray<BlockArray> m_BlockInLinks;
mutable rdcarray<bool> m_TracedBlocks;
mutable rdcarray<bool> m_CheckedPaths;
mutable rdcarray<BlockPath> m_ValidRoutes;
const size_t COUNT_PATHS_TYPES = 2;
rdcarray<rdcarray<uint32_t>> m_BlockPathLinks[PathType::Count];
rdcarray<BlockPath> m_PathSets[PathType::Count];
rdcarray<rdcarray<uint32_t>> m_BlockPathLinks;
rdcarray<BlockPath> m_Paths;
rdcarray<uint32_t> m_UniformBlocks;
rdcarray<uint32_t> m_LoopBlocks;
+1 -1
View File
@@ -1588,7 +1588,7 @@ bool ExecPointReference::IsAfter(const ExecPointReference &from,
{
if(block == from.block)
return instruction > from.instruction;
return controlFlow.IsForwardConnection(from.block, block);
return controlFlow.IsConnected(from.block, block);
}
void ResourceReferenceInfo::Create(const DXIL::ResourceReference *resRef, uint32_t arrayIndex)