@@ -697,6 +697,9 @@ bool DXILResourceTypeMap::invalidate(Module &M, const PreservedAnalyses &PA,
697697}
698698
699699// ===----------------------------------------------------------------------===//
700+ static bool isUpdateCounterIntrinsic (Function &F) {
701+ return F.getIntrinsicID () == Intrinsic::dx_resource_updatecounter;
702+ }
700703
701704void DXILResourceMap::populate (Module &M, DXILResourceTypeMap &DRTM) {
702705 SmallVector<std::tuple<CallInst *, ResourceInfo, ResourceTypeInfo>> CIToInfos;
@@ -775,6 +778,42 @@ void DXILResourceMap::populate(Module &M, DXILResourceTypeMap &DRTM) {
775778 // Adjust the resource binding to use the next ID.
776779 RI.setBindingID (NextID++);
777780 }
781+
782+ for (Function &F : M.functions ()) {
783+ if (!isUpdateCounterIntrinsic (F))
784+ continue ;
785+
786+ LLVM_DEBUG (dbgs () << " Update Counter Function: " << F.getName () << " \n " );
787+
788+ for (const User *U : F.users ()) {
789+ const CallInst *CI = dyn_cast<CallInst>(U);
790+ assert (CI && " Users of dx_resource_updateCounter must be call instrs" );
791+
792+ // Determine if the use is an increment or decrement
793+ Value *CountArg = CI->getArgOperand (1 );
794+ ConstantInt *CountValue = cast<ConstantInt>(CountArg);
795+ int64_t CountLiteral = CountValue->getSExtValue ();
796+
797+ // 0 is an unknown direction and shouldn't result in an insert
798+ if (CountLiteral == 0 )
799+ continue ;
800+
801+ ResourceCounterDirection Direction = ResourceCounterDirection::Decrement;
802+ if (CountLiteral > 0 )
803+ Direction = ResourceCounterDirection::Increment;
804+
805+ // Collect all potential creation points for the handle arg
806+ Value *HandleArg = CI->getArgOperand (0 );
807+ SmallVector<ResourceInfo *> RBInfos = findByUse (HandleArg);
808+ for (ResourceInfo *RBInfo : RBInfos) {
809+ if (RBInfo->CounterDirection == ResourceCounterDirection::Unknown ||
810+ RBInfo->CounterDirection == Direction)
811+ RBInfo->CounterDirection = Direction;
812+ else
813+ RBInfo->CounterDirection = ResourceCounterDirection::Invalid;
814+ }
815+ }
816+ }
778817}
779818
780819void DXILResourceMap::print (raw_ostream &OS, DXILResourceTypeMap &DRTM,
@@ -793,10 +832,9 @@ void DXILResourceMap::print(raw_ostream &OS, DXILResourceTypeMap &DRTM,
793832 }
794833}
795834
796- SmallVector<dxil::ResourceInfo>
797- DXILResourceMap::findByUse (const Value *Key) const {
835+ SmallVector<dxil::ResourceInfo *> DXILResourceMap::findByUse (const Value *Key) {
798836 if (const PHINode *Phi = dyn_cast<PHINode>(Key)) {
799- SmallVector<dxil::ResourceInfo> Children;
837+ SmallVector<dxil::ResourceInfo * > Children;
800838 for (const Value *V : Phi->operands ()) {
801839 Children.append (findByUse (V));
802840 }
@@ -810,9 +848,10 @@ DXILResourceMap::findByUse(const Value *Key) const {
810848 switch (CI->getIntrinsicID ()) {
811849 // Found the create, return the binding
812850 case Intrinsic::dx_resource_handlefrombinding: {
813- const auto *It = find (CI);
851+ auto Pos = CallMap.find (CI);
852+ ResourceInfo *It = &Infos[Pos->second ];
814853 assert (It != Infos.end () && " HandleFromBinding must be in resource map" );
815- return {* It};
854+ return {It};
816855 }
817856 default :
818857 break ;
@@ -821,7 +860,7 @@ DXILResourceMap::findByUse(const Value *Key) const {
821860 // Check if any of the parameters are the resource we are following. If so
822861 // keep searching. If none of them are return an empty list
823862 const Type *UseType = CI->getType ();
824- SmallVector<dxil::ResourceInfo> Children;
863+ SmallVector<dxil::ResourceInfo * > Children;
825864 for (const Value *V : CI->args ()) {
826865 if (V->getType () != UseType)
827866 continue ;
0 commit comments