Skip to content

Commit 1eb48c8

Browse files
rishipalgfxbot
authored andcommitted
When we have a resource access instruction inside a loop, the
calculation of offset use for access into that resource was incorrect. The offset calculation should begin from 0 (nullptr) and not Fixed that with this change. Change-Id: I594abd2cc8849483397c58cae0d09691590ae6b3
1 parent 1f09f26 commit 1eb48c8

File tree

2 files changed

+77
-86
lines changed

2 files changed

+77
-86
lines changed

IGC/Compiler/PromoteResourceToDirectAS.cpp

Lines changed: 71 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@ PromoteResourceToDirectAS::PromoteResourceToDirectAS()
6060
initializePromoteResourceToDirectASPass(*PassRegistry::getPassRegistry());
6161
}
6262

63+
inline bool isStatelessToBindlessPromotion(CodeGenContext* ctx)
64+
{
65+
if (ctx->type == ShaderType::OPENCL_SHADER)
66+
{
67+
if (static_cast<OpenCLProgramContext*>(ctx)->m_InternalOptions.PromoteStatelessToBindless)
68+
{
69+
return true;
70+
}
71+
}
72+
return false;
73+
}
74+
6375
bool PromoteResourceToDirectAS::runOnFunction(Function &F)
6476
{
6577
if(IGC_IS_FLAG_ENABLED(DisablePromoteToDirectAS))
@@ -70,6 +82,12 @@ bool PromoteResourceToDirectAS::runOnFunction(Function &F)
7082
m_pCodeGenContext = getAnalysis<CodeGenContextWrapper>().getCodeGenContext();
7183
m_pMdUtils = getAnalysis<MetaDataUtilsWrapper>().getMetaDataUtils();
7284
visit(F);
85+
86+
if (isStatelessToBindlessPromotion(m_pCodeGenContext))
87+
{
88+
PromoteStatelessToBindlessBuffers(F);
89+
}
90+
7391
return true;
7492
}
7593

@@ -593,16 +611,14 @@ void PromoteResourceToDirectAS::PromoteBufferToDirectAS(Instruction* inst, Value
593611
}
594612
}
595613

596-
void PromoteResourceToDirectAS::PromoteStatelessToBindlessBuffers(Instruction* inst, Value* resourcePtr)
614+
void PromoteResourceToDirectAS::GetAccessInstToSrcPointerMap(Instruction* inst, Value* resourcePtr)
597615
{
598-
IGCIRBuilder<> builder(inst);
599-
600616
unsigned addrSpace = resourcePtr->getType()->getPointerAddressSpace();
601617

602618
if (addrSpace != 1 && addrSpace != 2)
603619
{
604620
// Only try to promote stateless buffer pointers ( as(1) or as(2) )
605-
return;
621+
return;
606622
}
607623

608624
if (!isa<LoadInst>(inst) && !isa<StoreInst>(inst))
@@ -611,93 +627,66 @@ void PromoteResourceToDirectAS::PromoteStatelessToBindlessBuffers(Instruction* i
611627
return;
612628
}
613629

614-
std::vector<Value*> instructionList;
615-
Value* srcPtr = IGC::TracePointerSource(resourcePtr, false, true, instructionList);
630+
Value* srcPtr = IGC::TracePointerSource(resourcePtr);
616631

617632
if (!srcPtr ||
618633
!srcPtr->getType()->isPointerTy() ||
619634
!isa<Argument>(srcPtr))
620635
{
621636
// Cannot trace the resource pointer back to it's source, cannot promote
637+
assert(0 && "Stateless buffer pointer not tracable, cannot promote stateless to bindless");
622638
return;
623639
}
624640

625-
// Calculate the buffer offset value, and fix the instructions in the trace path if needed
626-
Value* bufferOffset = builder.getInt32(0);
627-
if (Argument* argPtr = dyn_cast<Argument>(srcPtr))
628-
{
629-
Constant* nullPtr = ConstantPointerNull::get(cast<PointerType>(srcPtr->getType()));
630-
631-
// The last instruction should be the argument
632-
assert(instructionList.back() == srcPtr);
633-
instructionList.pop_back();
634-
635-
int numInstsInPath = (int) instructionList.size();
641+
m_AccessToSrcPtrMap[inst] = srcPtr;
642+
return;
643+
}
636644

637-
// Check the list of instructions in the trace path. If there are any with multiple uses, we
638-
// want to clone all the instructions in the trace path so we don't interfere with the other users.
639-
bool needClonePath = false;
640-
for (int instIndex = numInstsInPath - 1; instIndex >= 0; instIndex--)
641-
{
642-
Instruction* nextInst = cast<Instruction>(instructionList[instIndex]);
643-
if (nextInst->getNumUses() > 1)
644-
{
645-
needClonePath = true;
646-
break;
647-
}
648-
}
649-
650-
if (needClonePath)
651-
{
652-
// Clone each instruction in the trace path
653-
Value* replacementValue = srcPtr;
654-
Value* newValue = nullPtr;
655-
for (int instIndex = numInstsInPath - 1; instIndex >= 0; instIndex--)
656-
{
657-
Instruction* nextInst = cast<Instruction>(instructionList[instIndex]);
658-
Instruction* cloneInst = nextInst->clone();
659-
cloneInst->insertAfter(nextInst);
660-
cloneInst->replaceUsesOfWith(replacementValue, newValue);
661-
replacementValue = nextInst;
662-
newValue = cloneInst;
663-
}
664-
bufferOffset = builder.CreatePtrToInt(newValue, builder.getInt32Ty());
665-
}
666-
else
667-
{
668-
// If there is only one user, we just directly replace the pointer with a null
669-
if (numInstsInPath > 0)
670-
{
671-
cast<Instruction>(instructionList[numInstsInPath - 1])->replaceUsesOfWith(srcPtr, nullPtr);
672-
bufferOffset = builder.CreatePtrToInt(resourcePtr, builder.getInt32Ty());
673-
}
674-
}
675-
676-
IGCMD::ResourceAllocMetaDataHandle resAllocMD = m_pMdUtils->getFunctionsInfoItem(inst->getParent()->getParent())->getResourceAlloc();
677-
IGCMD::ArgAllocMetaDataHandle argInfo = resAllocMD->getArgAllocsItem(argPtr->getArgNo());
678-
if (argInfo->getType() == IGCMD::ResourceTypeEnum::UAVResourceType)
679-
{
680-
// Update metadata to show bindless resource type
681-
argInfo->setType(IGCMD::ResourceTypeEnum::BindlessUAVResourceType);
682-
}
683-
}
645+
void PromoteResourceToDirectAS::PromoteStatelessToBindlessBuffers(Function& F)
646+
{
647+
for (auto inst : m_AccessToSrcPtrMap)
648+
{
649+
Argument* srcPtr = cast<Argument>(inst.second);
650+
if (srcPtr->getNumUses() > 0)
651+
{
652+
Value* nullSrcPtr = ConstantPointerNull::get(cast<PointerType>(srcPtr->getType()));
653+
srcPtr->replaceAllUsesWith(nullSrcPtr);
684654

685-
// Get the base bindless pointer
686-
unsigned bindlessAS = IGC::EncodeAS4GFXResource(*UndefValue::get(builder.getInt32Ty()), IGC::BINDLESS, 0);
687-
PointerType* basePointerType = PointerType::get(resourcePtr->getType()->getPointerElementType(), bindlessAS);
688-
Value* basePointer = builder.CreatePointerCast(srcPtr, basePointerType);
655+
IGCMD::ResourceAllocMetaDataHandle resAllocMD = m_pMdUtils->getFunctionsInfoItem(&F)->getResourceAlloc();
656+
IGCMD::ArgAllocMetaDataHandle argInfo = resAllocMD->getArgAllocsItem(srcPtr->getArgNo());
657+
if (argInfo->getType() == IGCMD::ResourceTypeEnum::UAVResourceType)
658+
{
659+
// Update metadata to show bindless resource type
660+
argInfo->setType(IGCMD::ResourceTypeEnum::BindlessUAVResourceType);
661+
}
662+
}
663+
}
689664

690-
if (LoadInst* load = dyn_cast<LoadInst>(inst))
691-
{
692-
Value* ldraw = IGC::CreateLoadRawIntrinsic(load, cast<Instruction>(basePointer), bufferOffset);
693-
load->replaceAllUsesWith(ldraw);
694-
load->eraseFromParent();
695-
}
696-
else if (StoreInst* store = dyn_cast<StoreInst>(inst))
697-
{
698-
IGC::CreateStoreRawIntrinsic(store, cast<Instruction>(basePointer), bufferOffset);
699-
store->eraseFromParent();
700-
}
665+
for (auto inst : m_AccessToSrcPtrMap)
666+
{
667+
Instruction* accessInst = cast<Instruction>(inst.first);
668+
Argument* srcPtr = cast<Argument>(inst.second);
669+
670+
// Get the base bindless pointer
671+
IGCIRBuilder<> builder(accessInst);
672+
Value* resourcePtr = GetBufferOperand(accessInst);
673+
unsigned bindlessAS = IGC::EncodeAS4GFXResource(*UndefValue::get(builder.getInt32Ty()), IGC::BINDLESS, 0);
674+
PointerType* basePointerType = PointerType::get(resourcePtr->getType()->getPointerElementType(), bindlessAS);
675+
Value* basePointer = builder.CreatePointerCast(srcPtr, basePointerType);
676+
Value* bufferOffset = builder.CreatePtrToInt(resourcePtr, builder.getInt32Ty());
677+
678+
if (LoadInst* load = dyn_cast<LoadInst>(accessInst))
679+
{
680+
Value* ldraw = IGC::CreateLoadRawIntrinsic(load, cast<Instruction>(basePointer), bufferOffset);
681+
load->replaceAllUsesWith(ldraw);
682+
load->eraseFromParent();
683+
}
684+
else if (StoreInst* store = dyn_cast<StoreInst>(accessInst))
685+
{
686+
IGC::CreateStoreRawIntrinsic(store, cast<Instruction>(basePointer), bufferOffset);
687+
store->eraseFromParent();
688+
}
689+
}
701690
}
702691

703692
void PromoteResourceToDirectAS::visitInstruction(Instruction &I)
@@ -728,12 +717,9 @@ void PromoteResourceToDirectAS::visitInstruction(Instruction &I)
728717

729718
if (bufptr && bufptr->getType()->isPointerTy())
730719
{
731-
if (m_pCodeGenContext->type == ShaderType::OPENCL_SHADER)
732-
{
733-
if (static_cast<OpenCLProgramContext*>(m_pCodeGenContext)->m_InternalOptions.PromoteStatelessToBindless)
734-
{
735-
PromoteStatelessToBindlessBuffers(&I, bufptr);
736-
}
720+
if (isStatelessToBindlessPromotion(m_pCodeGenContext))
721+
{
722+
GetAccessInstToSrcPointerMap(&I, bufptr);
737723
}
738724
else
739725
{

IGC/Compiler/PromoteResourceToDirectAS.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3434

3535
#include "Compiler/MetaDataUtilsWrapper.h"
3636
#include "GenISAIntrinsics/GenIntrinsicInst.h"
37+
#include <unordered_map>
3738

3839
namespace IGC
3940
{
@@ -62,7 +63,11 @@ namespace IGC
6263
private:
6364
void PromoteSamplerTextureToDirectAS(llvm::GenIntrinsicInst *&pIntr, llvm::Value* resourcePtr);
6465
void PromoteBufferToDirectAS(llvm::Instruction* inst, llvm::Value* resourcePtr);
65-
void PromoteStatelessToBindlessBuffers(llvm::Instruction* inst, llvm::Value* resourcePtr);
66+
67+
void GetAccessInstToSrcPointerMap(llvm::Instruction* inst, llvm::Value* resourcePtr);
68+
void PromoteStatelessToBindlessBuffers(llvm::Function& F);
69+
70+
std::unordered_map<llvm::Value*, llvm::Value*> m_AccessToSrcPtrMap;
6671

6772
CodeGenContext* m_pCodeGenContext;
6873
IGCMD::MetaDataUtils* m_pMdUtils;

0 commit comments

Comments
 (0)