@@ -60,6 +60,18 @@ PromoteResourceToDirectAS::PromoteResourceToDirectAS()
60
60
initializePromoteResourceToDirectASPass (*PassRegistry::getPassRegistry ());
61
61
}
62
62
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
+
63
75
bool PromoteResourceToDirectAS::runOnFunction (Function &F)
64
76
{
65
77
if (IGC_IS_FLAG_ENABLED (DisablePromoteToDirectAS))
@@ -70,6 +82,12 @@ bool PromoteResourceToDirectAS::runOnFunction(Function &F)
70
82
m_pCodeGenContext = getAnalysis<CodeGenContextWrapper>().getCodeGenContext ();
71
83
m_pMdUtils = getAnalysis<MetaDataUtilsWrapper>().getMetaDataUtils ();
72
84
visit (F);
85
+
86
+ if (isStatelessToBindlessPromotion (m_pCodeGenContext))
87
+ {
88
+ PromoteStatelessToBindlessBuffers (F);
89
+ }
90
+
73
91
return true ;
74
92
}
75
93
@@ -593,16 +611,14 @@ void PromoteResourceToDirectAS::PromoteBufferToDirectAS(Instruction* inst, Value
593
611
}
594
612
}
595
613
596
- void PromoteResourceToDirectAS::PromoteStatelessToBindlessBuffers (Instruction* inst, Value* resourcePtr)
614
+ void PromoteResourceToDirectAS::GetAccessInstToSrcPointerMap (Instruction* inst, Value* resourcePtr)
597
615
{
598
- IGCIRBuilder<> builder (inst);
599
-
600
616
unsigned addrSpace = resourcePtr->getType ()->getPointerAddressSpace ();
601
617
602
618
if (addrSpace != 1 && addrSpace != 2 )
603
619
{
604
620
// Only try to promote stateless buffer pointers ( as(1) or as(2) )
605
- return ;
621
+ return ;
606
622
}
607
623
608
624
if (!isa<LoadInst>(inst) && !isa<StoreInst>(inst))
@@ -611,93 +627,66 @@ void PromoteResourceToDirectAS::PromoteStatelessToBindlessBuffers(Instruction* i
611
627
return ;
612
628
}
613
629
614
- std::vector<Value*> instructionList;
615
- Value* srcPtr = IGC::TracePointerSource (resourcePtr, false , true , instructionList);
630
+ Value* srcPtr = IGC::TracePointerSource (resourcePtr);
616
631
617
632
if (!srcPtr ||
618
633
!srcPtr->getType ()->isPointerTy () ||
619
634
!isa<Argument>(srcPtr))
620
635
{
621
636
// 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" );
622
638
return ;
623
639
}
624
640
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
+ }
636
644
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);
684
654
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
+ }
689
664
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
+ }
701
690
}
702
691
703
692
void PromoteResourceToDirectAS::visitInstruction (Instruction &I)
@@ -728,12 +717,9 @@ void PromoteResourceToDirectAS::visitInstruction(Instruction &I)
728
717
729
718
if (bufptr && bufptr->getType ()->isPointerTy ())
730
719
{
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);
737
723
}
738
724
else
739
725
{
0 commit comments