summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-11-13 20:32:02 -0800
committerGitHub <noreply@github.com>2024-11-13 20:32:02 -0800
commite0d03dabf2591bb8a0a0686c9d38b0046487964e (patch)
treeac1bbf2fcedd08e129f0e90fb9f975726e55d9a8 /source
parent5948326af964d46461a9c9fc51676a450fdb31a8 (diff)
Fix regression caused by defer buffer load. (#5552)
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-ir-defer-buffer-load.cpp150
1 files changed, 2 insertions, 148 deletions
diff --git a/source/slang/slang-ir-defer-buffer-load.cpp b/source/slang/slang-ir-defer-buffer-load.cpp
index d1eb4b5e5..fea73e705 100644
--- a/source/slang/slang-ir-defer-buffer-load.cpp
+++ b/source/slang/slang-ir-defer-buffer-load.cpp
@@ -11,131 +11,15 @@ namespace Slang
{
struct DeferBufferLoadContext
{
- struct AccessChain
- {
- List<IRInst*> chain;
- mutable HashCode64 hash = 0;
-
- bool operator==(const AccessChain& rhs) const
- {
- ensureHash();
- rhs.ensureHash();
- if (hash != rhs.hash)
- return false;
- if (chain.getCount() != rhs.chain.getCount())
- return false;
- for (Index i = 0; i < chain.getCount(); i++)
- {
- if (chain[i] != rhs.chain[i])
- return false;
- }
- return true;
- }
- void ensureHash() const
- {
- if (hash == 0)
- {
- for (auto inst : chain)
- {
- hash = combineHash(hash, Slang::getHashCode(inst));
- }
- }
- }
- HashCode64 getHashCode() const
- {
- ensureHash();
- return hash;
- }
- };
-
// Map an original SSA value to a pointer that can be used to load the value.
- Dictionary<AccessChain, IRInst*> mapAccessChainToPtr;
Dictionary<IRInst*, IRInst*> mapValueToPtr;
+
// Map an ptr to its loaded value.
Dictionary<IRInst*, IRInst*> mapPtrToValue;
IRFunc* currentFunc = nullptr;
IRDominatorTree* dominatorTree = nullptr;
- // Find the block that is dominated by all dependent blocks, and is the earliest block that
- // dominates the target block.
- // This is the place where we can insert the load instruction such that all access chain
- // operands are defined and the load can be made avaialble to the location of valueInst.
- //
- IRBlock* findEarliestDominatingBlock(IRInst* valueInst, List<IRBlock*>& dependentBlocks)
- {
- auto targetBlock = getBlock(valueInst);
- while (targetBlock)
- {
- auto idom = dominatorTree->getImmediateDominator(targetBlock);
- if (!idom)
- break;
- bool isValid = true;
- for (auto block : dependentBlocks)
- {
- if (!dominatorTree->dominates(block, idom))
- {
- isValid = false;
- break;
- }
- }
- if (isValid)
- {
- targetBlock = idom;
- }
- else
- {
- break;
- }
- }
- return targetBlock;
- }
-
- // Find the earliest instruction before which we can insert the load instruction such that
- // all dependent instructions for the load address are defined, and the load can reach all
- // locations where the address is available.
- //
- IRInst* findEarliestInsertionPoint(IRInst* valueInst, AccessChain& chain)
- {
- List<IRBlock*> dependentBlocks;
- List<IRInst*> dependentInsts;
- for (auto inst : chain.chain)
- {
- if (auto block = getBlock(inst))
- {
- dependentBlocks.add(block);
- dependentInsts.add(inst);
- }
- }
- auto targetBlock = findEarliestDominatingBlock(valueInst, dependentBlocks);
- IRInst* insertBeforeInst =
- targetBlock == getBlock(valueInst) ? valueInst : targetBlock->getTerminator();
- for (;;)
- {
- auto prev = insertBeforeInst->getPrevInst();
- if (!prev)
- break;
- bool valid = true;
- for (auto inst : dependentInsts)
- {
- if (!dominatorTree->dominates(inst, prev) || inst == prev)
- {
- valid = false;
- break;
- }
- }
- if (valid)
- {
- insertBeforeInst = prev;
- }
- else
- {
- break;
- }
- }
- return insertBeforeInst;
- }
-
// Ensure that for an original SSA value, we have formed a pointer that can be used to load the
// value.
IRInst* ensurePtr(IRInst* valueInst)
@@ -143,38 +27,9 @@ struct DeferBufferLoadContext
IRInst* result = nullptr;
if (mapValueToPtr.tryGetValue(valueInst, result))
return result;
- AccessChain chain;
- IRInst* current = valueInst;
- while (current)
- {
- bool processed = false;
- switch (current->getOp())
- {
- case kIROp_GetElement:
- case kIROp_FieldExtract:
- chain.chain.add(current->getOperand(1));
- current = current->getOperand(0);
- processed = true;
- break;
- default:
- break;
- }
- if (!processed)
- break;
- }
- chain.chain.add(current);
- chain.chain.reverse();
- if (mapAccessChainToPtr.tryGetValue(chain, result))
- return result;
- // Find the proper place to insert the load instruction.
- // This is the location where all operands of the access chain are defined.
- // And is the earliest block so all possible uses of the value at access chain
- // can be reached.
IRBuilder b(valueInst);
-
- auto insertBeforeInst = findEarliestInsertionPoint(valueInst, chain);
- b.setInsertBefore(insertBeforeInst);
+ b.setInsertBefore(valueInst);
switch (valueInst->getOp())
{
@@ -205,7 +60,6 @@ struct DeferBufferLoadContext
}
if (result)
{
- mapAccessChainToPtr[chain] = result;
mapValueToPtr[valueInst] = result;
}
return result;