Skip to content

Commit 176b862

Browse files
committed
Add location to error message
1 parent 92f2a46 commit 176b862

File tree

3 files changed

+44
-13
lines changed

3 files changed

+44
-13
lines changed

llvm/lib/Analysis/DXILResource.cpp

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "llvm/ADT/SmallString.h"
1212
#include "llvm/ADT/StringRef.h"
1313
#include "llvm/IR/Constants.h"
14+
#include "llvm/IR/DebugLoc.h"
1415
#include "llvm/IR/DerivedTypes.h"
1516
#include "llvm/IR/DiagnosticInfo.h"
1617
#include "llvm/IR/Instructions.h"
@@ -21,6 +22,7 @@
2122
#include "llvm/InitializePasses.h"
2223
#include "llvm/Support/FormatVariadic.h"
2324
#include <algorithm>
25+
#include <iterator>
2426

2527
#define DEBUG_TYPE "dxil-resource"
2628

@@ -830,7 +832,8 @@ static bool isUpdateCounterIntrinsic(Function &F) {
830832
}
831833

832834
void DXILResourceCounterDirectionMap::populate(Module &M, DXILBindingMap &DBM) {
833-
CounterDirections.clear();
835+
std::vector<std::tuple<dxil::ResourceBindingInfo, ResourceCounterDirection, const Function*, const CallInst*>>
836+
DiagCounterDirs;
834837

835838
for (Function &F : M.functions()) {
836839
if (!isUpdateCounterIntrinsic(F))
@@ -855,39 +858,59 @@ void DXILResourceCounterDirectionMap::populate(Module &M, DXILBindingMap &DBM) {
855858
Value *HandleArg = CI->getArgOperand(0);
856859
SmallVector<dxil::ResourceBindingInfo> RBInfos = DBM.findByUse(HandleArg);
857860
for (const dxil::ResourceBindingInfo RBInfo : RBInfos)
858-
CounterDirections.emplace_back(RBInfo, Direction);
861+
DiagCounterDirs.emplace_back(RBInfo, Direction, &F, CI);
859862
}
860863
}
861864

862865
// An entry that is not in the map is considered unknown so its wasted
863866
// overhead and increased complexity to keep an entry explicitly marked
864867
// unknown
865868
const auto RemoveEnd = std::remove_if(
866-
CounterDirections.begin(), CounterDirections.end(), [](const auto &Item) {
867-
return Item.second == ResourceCounterDirection::Unknown;
869+
DiagCounterDirs.begin(), DiagCounterDirs.end(), [](const auto &Item) {
870+
return std::get<ResourceCounterDirection>(Item) == ResourceCounterDirection::Unknown;
868871
});
869872

870-
// Order for fast lookup
871-
std::sort(CounterDirections.begin(), RemoveEnd);
873+
// Sort by the Binding and Direction for fast lookup
874+
std::sort(DiagCounterDirs.begin(), RemoveEnd, [](const auto &LHS, const auto &RHS) {
875+
const auto L = std::pair{std::get<dxil::ResourceBindingInfo>(LHS), std::get<ResourceCounterDirection>(LHS)};
876+
const auto R = std::pair{std::get<dxil::ResourceBindingInfo>(RHS), std::get<ResourceCounterDirection>(RHS)};
877+
return L < R;
878+
});
872879

873880
// Remove the duplicate entries. Since direction is considered for equality
874881
// a unique resource with more than one direction will not be deduped.
875-
const auto UniqueEnd = std::unique(CounterDirections.begin(), RemoveEnd);
882+
const auto UniqueEnd = std::unique(DiagCounterDirs.begin(), RemoveEnd, [](const auto &LHS, const auto &RHS) {
883+
const auto L = std::pair{std::get<dxil::ResourceBindingInfo>(LHS), std::get<ResourceCounterDirection>(LHS)};
884+
const auto R = std::pair{std::get<dxil::ResourceBindingInfo>(RHS), std::get<ResourceCounterDirection>(RHS)};
885+
return L == R;
886+
});
876887

877888
// Actually erase the items invalidated by remove_if + unique
878-
CounterDirections.erase(UniqueEnd, CounterDirections.end());
889+
DiagCounterDirs.erase(UniqueEnd, DiagCounterDirs.end());
879890

880891
// If any duplicate entries still exist at this point then it must be a
881892
// resource that was both incremented and decremented which is not allowed.
882893
const auto DuplicateEntry = std::adjacent_find(
883-
CounterDirections.begin(), CounterDirections.end(),
884-
[](const auto &LHS, const auto &RHS) { return LHS.first == RHS.first; });
885-
if (DuplicateEntry == CounterDirections.end())
894+
DiagCounterDirs.begin(), DiagCounterDirs.end(),
895+
[](const auto &LHS, const auto &RHS) {
896+
return std::get<dxil::ResourceBindingInfo>(LHS) == std::get<dxil::ResourceBindingInfo>(RHS);
897+
});
898+
899+
// Copy the results into the final vec
900+
CounterDirections.clear();
901+
CounterDirections.reserve(DiagCounterDirs.size());
902+
std::transform(DiagCounterDirs.begin(), DiagCounterDirs.end(), std::back_inserter(CounterDirections), [](const auto &Item){
903+
return std::pair{std::get<dxil::ResourceBindingInfo>(Item), std::get<ResourceCounterDirection>(Item)};
904+
});
905+
906+
if (DuplicateEntry == DiagCounterDirs.end())
886907
return;
887908

909+
const Function* F = std::get<const Function*>(*DuplicateEntry);
910+
const CallInst* CI = std::get<const CallInst*>(*DuplicateEntry);
888911
StringRef Message = "RWStructuredBuffers may increment or decrement their "
889912
"counters, but not both.";
890-
M.getContext().diagnose(DiagnosticInfoGeneric(Message));
913+
M.getContext().diagnose(DiagnosticInfoGenericWithLoc(Message, *F, CI->getDebugLoc()));
891914
}
892915

893916
void DXILResourceCounterDirectionWrapperPass::getAnalysisUsage(

llvm/test/CodeGen/DirectX/resource_counter_error.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; RUN: not opt -S -passes='dxil-op-lower' -mtriple=dxil-pc-shadermodel6.3-library %s 2>&1 | FileCheck %s
2-
; CHECK: RWStructuredBuffers may increment or decrement their counters, but not both.
2+
; CHECK: <unknown>:0:0: RWStructuredBuffers may increment or decrement their counters, but not both.
33

44
define void @inc_and_dec() {
55
entry:

llvm/unittests/Target/DirectX/UniqueResourceFromUseTests.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ declare target("dx.RawBuffer", float, 1, 0) @ind.func(target("dx.RawBuffer", flo
281281
}
282282
}
283283

284+
// Test that several calls to decrement on the same resource don't raise a
285+
// Diagnositic and resolves to a single decrement entry
284286
TEST_F(UniqueResourceFromUseTest, TestResourceCounterDecrement) {
285287
StringRef Assembly = R"(
286288
define void @main() {
@@ -322,6 +324,8 @@ declare void @a.func(target("dx.RawBuffer", float, 1, 0) %handle)
322324
}
323325
}
324326

327+
// Test that several calls to increment on the same resource don't raise a
328+
// Diagnositic and resolves to a single increment entry
325329
TEST_F(UniqueResourceFromUseTest, TestResourceCounterIncrement) {
326330
StringRef Assembly = R"(
327331
define void @main() {
@@ -363,6 +367,8 @@ declare void @a.func(target("dx.RawBuffer", float, 1, 0) %handle)
363367
}
364368
}
365369

370+
// Test that looking up a resource that doesn't have the counter updated
371+
// resoves to unknown
366372
TEST_F(UniqueResourceFromUseTest, TestResourceCounterUnknown) {
367373
StringRef Assembly = R"(
368374
define void @main() {
@@ -401,6 +407,8 @@ declare void @a.func(target("dx.RawBuffer", float, 1, 0) %handle)
401407
}
402408
}
403409

410+
// Test that multiple different resources with unique incs/decs don't
411+
// raise a Diagnostic and can be individually checked for direction
404412
TEST_F(UniqueResourceFromUseTest, TestResourceCounterMultiple) {
405413
StringRef Assembly = R"(
406414
define void @main() {

0 commit comments

Comments
 (0)