Skip to content

Commit 34a9b12

Browse files
committed
Raise error for each invalid use
1 parent 6ae40ec commit 34a9b12

File tree

1 file changed

+44
-41
lines changed

1 file changed

+44
-41
lines changed

llvm/lib/Analysis/DXILResource.cpp

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -879,58 +879,61 @@ void DXILResourceCounterDirectionMap::populate(Module &M, DXILBindingMap &DBM) {
879879
return L < R;
880880
});
881881

882-
// Remove the duplicate entries. Since direction is considered for equality
883-
// a unique resource with more than one direction will not be deduped.
884-
auto *const UniqueEnd = std::unique(
885-
DiagCounterDirs.begin(), DiagCounterDirs.end(),
886-
[](const auto &LHS, const auto &RHS) {
887-
const auto L =
888-
std::pair{std::get<const dxil::ResourceBindingInfo *>(LHS),
889-
std::get<ResourceCounterDirection>(LHS)};
890-
const auto R =
891-
std::pair{std::get<const dxil::ResourceBindingInfo *>(RHS),
892-
std::get<ResourceCounterDirection>(RHS)};
893-
return L == R;
894-
});
895-
896-
// Actually erase the invalidated items
897-
DiagCounterDirs.erase(UniqueEnd, DiagCounterDirs.end());
898-
899-
// If any duplicate entries still exist at this point then it must be a
900-
// resource that was both incremented and decremented which is not allowed.
901-
// Mark all those entries as invalid.
902882
{
903-
auto *DupFirst = DiagCounterDirs.begin();
904-
auto *DupNext = DupFirst + 1;
905-
auto *DupLast = DiagCounterDirs.end();
906-
for (; DupFirst < DupLast && DupNext < DupLast; ++DupFirst, ++DupNext) {
907-
if (std::get<const dxil::ResourceBindingInfo *>(*DupFirst) ==
908-
std::get<const dxil::ResourceBindingInfo *>(*DupNext)) {
909-
std::get<ResourceCounterDirection>(*DupFirst) =
910-
ResourceCounterDirection::Invalid;
911-
std::get<ResourceCounterDirection>(*DupNext) =
883+
auto *SpanStart = DiagCounterDirs.begin();
884+
auto *SpanEnd = SpanStart;
885+
auto *ItEnd = DiagCounterDirs.end();
886+
887+
while (SpanStart < ItEnd) {
888+
while (SpanEnd < ItEnd &&
889+
std::get<const dxil::ResourceBindingInfo *>(*SpanStart) ==
890+
std::get<const dxil::ResourceBindingInfo *>(*SpanEnd))
891+
SpanEnd++;
892+
893+
// SpanStart : SpanEnd-1 are the same binding. Its an error if they aren't
894+
// all the same direction
895+
ResourceCounterDirection ResourceDir =
896+
std::get<ResourceCounterDirection>(*SpanStart);
897+
bool ValidUse = true;
898+
for (auto *CheckIt = SpanStart; CheckIt < SpanEnd; ++CheckIt) {
899+
if (ResourceDir != std::get<ResourceCounterDirection>(*CheckIt)) {
900+
ValidUse = false;
901+
break;
902+
}
903+
}
904+
905+
// Update the direction and raise a diag when an invalid use is detected
906+
for (auto *RaiseIt = SpanStart; !ValidUse && RaiseIt < SpanEnd;
907+
++RaiseIt) {
908+
std::get<ResourceCounterDirection>(*RaiseIt) =
912909
ResourceCounterDirection::Invalid;
913910

914-
// Raise an error for every invalid entry
915911
StringRef Message =
916912
"RWStructuredBuffers may increment or decrement their "
917913
"counters, but not both.";
918-
const Function *FFirst = std::get<const Function *>(*DupFirst);
919-
const CallInst *CIFirst = std::get<const CallInst *>(*DupFirst);
920-
const Function *FNext = std::get<const Function *>(*DupNext);
921-
const CallInst *CINext = std::get<const CallInst *>(*DupNext);
922-
M.getContext().diagnose(DiagnosticInfoGenericWithLoc(
923-
Message, *FFirst, CIFirst->getDebugLoc()));
924-
M.getContext().diagnose(DiagnosticInfoGenericWithLoc(
925-
Message, *FNext, CINext->getDebugLoc()));
914+
const Function *F = std::get<const Function *>(*RaiseIt);
915+
const CallInst *CI = std::get<const CallInst *>(*RaiseIt);
916+
M.getContext().diagnose(
917+
DiagnosticInfoGenericWithLoc(Message, *F, CI->getDebugLoc()));
926918
}
919+
920+
SpanStart = SpanEnd;
927921
}
928922
}
929923

930-
// Copy the results into the final vec
924+
// Remove the duplicate entries. All entries with the same resource have the
925+
// same direction so it can be ignored.
926+
auto *const UniqueEnd =
927+
std::unique(DiagCounterDirs.begin(), DiagCounterDirs.end(),
928+
[](const auto &LHS, const auto &RHS) {
929+
return std::get<const dxil::ResourceBindingInfo *>(LHS) ==
930+
std::get<const dxil::ResourceBindingInfo *>(RHS);
931+
});
932+
933+
// Copy the results into the final location
931934
CounterDirections.clear();
932-
CounterDirections.reserve(DiagCounterDirs.size());
933-
std::transform(DiagCounterDirs.begin(), DiagCounterDirs.end(),
935+
CounterDirections.reserve(UniqueEnd - DiagCounterDirs.begin());
936+
std::transform(DiagCounterDirs.begin(), UniqueEnd,
934937
std::back_inserter(CounterDirections), [](const auto &Item) {
935938
return std::pair{
936939
std::get<const dxil::ResourceBindingInfo *>(Item),

0 commit comments

Comments
 (0)