diff --git a/source/slang/slang-ir-defer-buffer-load.cpp b/source/slang/slang-ir-defer-buffer-load.cpp index d1eb4b5e5c..fea73e7052 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 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 mapAccessChainToPtr; Dictionary mapValueToPtr; + // Map an ptr to its loaded value. Dictionary 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& 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 dependentBlocks; - List 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;