@@ -38,6 +38,14 @@ IGC_INITIALIZE_PASS_DEPENDENCY(MetaDataUtilsWrapper)
38
38
IGC_INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
39
39
IGC_INITIALIZE_PASS_END(StatelessToStateful, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY, PASS_ANALYSIS)
40
40
41
+ static cl::opt<TargetAddressing> targetAddressingMode(
42
+ " target-addressing-mode" , cl::init(TargetAddressing::BINDFUL), cl::Hidden,
43
+ cl::values(
44
+ clEnumValN (TargetAddressing::BINDFUL, " bindful" , " Set bindful as target addressing mode" ),
45
+ clEnumValN(TargetAddressing::BINDLESS, " bindless" , " Set bindless as target addressing mode" )
46
+ ),
47
+ cl::desc(" Set target addressing for stateful promotion" ));
48
+
41
49
// This pass turns a global/constants address space (stateless) load/store into a stateful a load/store.
42
50
//
43
51
// The conservative approach is to search for any directly positively-indexed kernels argument, such as:
@@ -129,15 +137,11 @@ IGC_INITIALIZE_PASS_END(StatelessToStateful, PASS_FLAG, PASS_DESCRIPTION, PASS_C
129
137
130
138
char StatelessToStateful::ID = 0 ;
131
139
132
- StatelessToStateful::StatelessToStateful ()
140
+ StatelessToStateful::StatelessToStateful () : FunctionPass(ID), m_targetAddressing(targetAddressingMode) {}
141
+
142
+ StatelessToStateful::StatelessToStateful (TargetAddressing addressing)
133
143
: FunctionPass(ID),
134
- m_hasBufferOffsetArg(false ),
135
- m_hasOptionalBufferOffsetArg(false ),
136
- m_hasPositivePointerOffset(false ),
137
- m_ACT(nullptr ),
138
- m_pImplicitArgs(nullptr ),
139
- m_pKernelArgs(nullptr ),
140
- m_changed(false )
144
+ m_targetAddressing(addressing)
141
145
{
142
146
initializeStatelessToStatefulPass (*PassRegistry::getPassRegistry ());
143
147
}
@@ -538,7 +542,7 @@ bool StatelessToStateful::isUntypedAtomic(const GenISAIntrinsic::ID intrinID)
538
542
intrinID == GenISAIntrinsic::GenISA_fcmpxchgatomicrawA64);
539
543
}
540
544
541
- unsigned StatelessToStateful::encodeStatefulAddrspace (unsigned uavIndex)
545
+ unsigned StatelessToStateful::encodeBindfulAddrspace (unsigned uavIndex)
542
546
{
543
547
auto int32Ty = Type::getInt32Ty (m_Module->getContext ());
544
548
auto resourceNumber = ConstantInt::get (int32Ty, uavIndex);
@@ -555,8 +559,37 @@ void StatelessToStateful::promoteIntrinsic(InstructionInfo& II)
555
559
Module* M = m_F->getParent ();
556
560
const DebugLoc& DL = I->getDebugLoc ();
557
561
GenISAIntrinsic::ID const intrinID = I->getIntrinsicID ();
558
-
559
562
PointerType* pTy = PointerType::get (IGCLLVM::getNonOpaquePtrEltTy (II.ptr ->getType ()), II.getStatefulAddrSpace ());
563
+
564
+ if (m_targetAddressing == TargetAddressing::BINDLESS)
565
+ {
566
+ Argument* srcOffset = m_pImplicitArgs->getNumberedImplicitArg (*m_F, ImplicitArg::BINDLESS_OFFSET, II.getBaseArgIndex ());
567
+ auto newBasePtr = IntToPtrInst::Create (Instruction::IntToPtr, srcOffset, pTy, " " , I);
568
+ if (intrinID == GenISAIntrinsic::GenISA_simdBlockRead)
569
+ {
570
+ Function* newBlockReadFunc = GenISAIntrinsic::getDeclaration (M,
571
+ GenISAIntrinsic::GenISA_simdBlockReadBindless,
572
+ { I->getType (), newBasePtr->getType (), Type::getInt32Ty (M->getContext ())});
573
+ Instruction* newBlockRead = CallInst::Create (newBlockReadFunc, { newBasePtr, II.offset }, " " , I);
574
+ newBlockRead->setDebugLoc (I->getDebugLoc ());
575
+ I->replaceAllUsesWith (newBlockRead);
576
+ I->eraseFromParent ();
577
+ }
578
+ else if (intrinID == GenISAIntrinsic::GenISA_simdBlockWrite)
579
+ {
580
+ Function* newBlockWriteFunc = GenISAIntrinsic::getDeclaration (M,
581
+ GenISAIntrinsic::GenISA_simdBlockWriteBindless,
582
+ { newBasePtr->getType (), I->getOperand (1 )->getType (), Type::getInt32Ty (M->getContext ())});
583
+ Instruction* newBlockWrite = CallInst::Create (newBlockWriteFunc, { newBasePtr, I->getOperand (1 ), II.offset }, " " , I);
584
+ newBlockWrite->setDebugLoc (I->getDebugLoc ());
585
+ I->replaceAllUsesWith (newBlockWrite);
586
+ I->eraseFromParent ();
587
+ }
588
+ return ;
589
+ }
590
+
591
+ IGC_ASSERT (m_targetAddressing == TargetAddressing::BINDFUL);
592
+
560
593
Instruction* statefulPtr = IntToPtrInst::Create (Instruction::IntToPtr, II.offset , pTy, " " , I);
561
594
Instruction* statefulInst = nullptr ;
562
595
@@ -614,31 +647,51 @@ void StatelessToStateful::promoteLoad(InstructionInfo& II)
614
647
LoadInst* I = cast<LoadInst>(II.statelessInst );
615
648
PointerType* pTy = PointerType::get (I->getType (), II.getStatefulAddrSpace ());
616
649
617
- Instruction* statefulPtr = IntToPtrInst::Create (Instruction::IntToPtr, II.offset , pTy, " " , I);
618
- Instruction* pLoad = new LoadInst (
619
- IGCLLVM::getNonOpaquePtrEltTy (statefulPtr->getType ()),
620
- statefulPtr,
621
- " " ,
622
- I->isVolatile (),
623
- IGCLLVM::getAlign (*I), I->getOrdering (), I->getSyncScopeID (),
624
- I);
625
-
626
650
const DebugLoc& DL = I->getDebugLoc ();
627
- statefulPtr->setDebugLoc (DL);
628
- pLoad->setDebugLoc (DL);
629
651
630
- Value* ptr = I->getPointerOperand ();
631
- PointerType* ptrType = dyn_cast<PointerType>(ptr->getType ());
632
- if (ptrType && ptrType->getAddressSpace () == ADDRESS_SPACE_CONSTANT)
652
+ if (m_targetAddressing == TargetAddressing::BINDLESS)
633
653
{
634
- LLVMContext& context = I->getContext ();
635
- MDString* const metadataName = MDString::get (context, " invariant.load" );
636
- MDNode* node = MDNode::get (context, metadataName);
637
- pLoad->setMetadata (LLVMContext::MD_invariant_load, node);
654
+ Argument* srcOffset = m_pImplicitArgs->getNumberedImplicitArg (*m_F, ImplicitArg::BINDLESS_OFFSET, II.getBaseArgIndex ());
655
+ auto newBasePtr = IntToPtrInst::Create (Instruction::IntToPtr, srcOffset, pTy, " " , I);
656
+ auto bindlessLoad = IGC::CreateLoadRawIntrinsic (I, cast<Instruction>(newBasePtr), II.offset );
657
+
658
+ newBasePtr->setDebugLoc (DL);
659
+ bindlessLoad->setDebugLoc (DL);
660
+
661
+ I->replaceAllUsesWith (bindlessLoad);
662
+ I->eraseFromParent ();
638
663
}
664
+ else if (m_targetAddressing == TargetAddressing::BINDFUL)
665
+ {
666
+ auto newBasePtr = IntToPtrInst::Create (Instruction::IntToPtr, II.offset , pTy, " " , I);
667
+ auto bindfulLoad = new LoadInst (
668
+ IGCLLVM::getNonOpaquePtrEltTy (newBasePtr->getType ()),
669
+ newBasePtr,
670
+ " " ,
671
+ I->isVolatile (),
672
+ IGCLLVM::getAlign (*I), I->getOrdering (), I->getSyncScopeID (),
673
+ I);
674
+
675
+ newBasePtr->setDebugLoc (DL);
676
+ bindfulLoad->setDebugLoc (DL);
677
+
678
+ Value* ptr = I->getPointerOperand ();
679
+ PointerType* ptrType = dyn_cast<PointerType>(ptr->getType ());
680
+ if (ptrType && ptrType->getAddressSpace () == ADDRESS_SPACE_CONSTANT)
681
+ {
682
+ LLVMContext& context = I->getContext ();
683
+ MDString* const metadataName = MDString::get (context, " invariant.load" );
684
+ MDNode* node = MDNode::get (context, metadataName);
685
+ bindfulLoad->setMetadata (LLVMContext::MD_invariant_load, node);
686
+ }
639
687
640
- I->replaceAllUsesWith (pLoad);
641
- I->eraseFromParent ();
688
+ I->replaceAllUsesWith (bindfulLoad);
689
+ I->eraseFromParent ();
690
+ }
691
+ else
692
+ {
693
+ IGC_ASSERT_MESSAGE (false , " Unsupported addressing!" );
694
+ }
642
695
}
643
696
644
697
void StatelessToStateful::promoteStore (InstructionInfo& II)
@@ -648,19 +701,38 @@ void StatelessToStateful::promoteStore(InstructionInfo& II)
648
701
Value* dataVal = I->getValueOperand ();
649
702
PointerType* pTy = PointerType::get (dataVal->getType (), II.getStatefulAddrSpace ());
650
703
651
- Instruction* statefulPtr = IntToPtrInst::Create (Instruction::IntToPtr, II.offset , pTy, " " , I);
652
- Instruction* pStore = new StoreInst (
653
- dataVal,
654
- statefulPtr,
655
- I->isVolatile (),
656
- IGCLLVM::getAlign (*I), I->getOrdering (), I->getSyncScopeID (),
657
- I);
658
-
659
704
const DebugLoc& DL = I->getDebugLoc ();
660
- statefulPtr->setDebugLoc (DL);
661
- pStore->setDebugLoc (DL);
662
705
663
- I->eraseFromParent ();
706
+ if (m_targetAddressing == TargetAddressing::BINDLESS)
707
+ {
708
+ Argument* srcOffset = m_pImplicitArgs->getNumberedImplicitArg (*m_F, ImplicitArg::BINDLESS_OFFSET, II.getBaseArgIndex ());
709
+ auto newBasePtr = IntToPtrInst::Create (Instruction::IntToPtr, srcOffset, pTy, " " , I);
710
+ auto bindlessStore = IGC::CreateStoreRawIntrinsic (I, cast<Instruction>(newBasePtr), II.offset );
711
+
712
+ newBasePtr->setDebugLoc (DL);
713
+ bindlessStore->setDebugLoc (DL);
714
+
715
+ I->eraseFromParent ();
716
+ }
717
+ else if (m_targetAddressing == TargetAddressing::BINDFUL)
718
+ {
719
+ auto newBasePtr = IntToPtrInst::Create (Instruction::IntToPtr, II.offset , pTy, " " , I);
720
+ auto bindfulStore = new StoreInst (
721
+ dataVal,
722
+ newBasePtr,
723
+ I->isVolatile (),
724
+ IGCLLVM::getAlign (*I), I->getOrdering (), I->getSyncScopeID (),
725
+ I);
726
+
727
+ newBasePtr->setDebugLoc (DL);
728
+ bindfulStore->setDebugLoc (DL);
729
+
730
+ I->eraseFromParent ();
731
+ }
732
+ else
733
+ {
734
+ IGC_ASSERT_MESSAGE (false , " Unsupported addressing!" );
735
+ }
664
736
}
665
737
666
738
void StatelessToStateful::promoteInstruction (StatelessToStateful::InstructionInfo& InstInfo)
@@ -696,21 +768,34 @@ void StatelessToStateful::promote()
696
768
{
697
769
IGC_ASSERT (bufferPos < maxPromotionCount);
698
770
699
- ArgAllocMD* argAlloc = &resAllocMD->argAllocMDList [baseArgIndex];
700
-
701
- // If the support for dynamic BTIs allocation is disabled, then BTIs are pre-assigned
702
- // in ResourceAllocator pass for all resources independently whether they are
703
- // accessed through stateful addressing model or not.
704
- if (ctx->platform .supportDynamicBTIsAllocation ())
771
+ unsigned statefullAddrspace = 0 ;
772
+ if (m_targetAddressing == TargetAddressing::BINDLESS)
705
773
{
706
- argAlloc->type = ResourceTypeEnum::UAVResourceType;
707
- argAlloc->indexType = resAllocMD->uavsNumType + bufferPos;
774
+ statefullAddrspace =
775
+ IGC::EncodeAS4GFXResource (
776
+ *UndefValue::get (Type::getInt32Ty (m_Module->getContext ())),
777
+ IGC::BINDLESS);
778
+ }
779
+ else
780
+ {
781
+ ArgAllocMD* argAlloc = &resAllocMD->argAllocMDList [baseArgIndex];
782
+
783
+ // If the support for dynamic BTIs allocation is disabled, then BTIs are pre-assigned
784
+ // in ResourceAllocator pass for all resources independently whether they are
785
+ // accessed through stateful addressing model or not.
786
+ if (ctx->platform .supportDynamicBTIsAllocation ())
787
+ {
788
+ argAlloc->type = ResourceTypeEnum::UAVResourceType;
789
+ argAlloc->indexType = resAllocMD->uavsNumType + bufferPos;
790
+ }
791
+
792
+ statefullAddrspace = encodeBindfulAddrspace (argAlloc->indexType );
708
793
}
709
794
710
- unsigned statefullAddrspace = encodeStatefulAddrspace (argAlloc->indexType );
711
795
for (auto &instInfo : instsToPromote)
712
796
{
713
797
instInfo.setStatefulAddrspace (statefullAddrspace);
798
+ instInfo.setBaseArgIndex (baseArgIndex);
714
799
promoteInstruction (instInfo);
715
800
}
716
801
bufferPos++;
0 commit comments