Skip to content

Commit ab1e78d

Browse files
committed
Implement trivial resource lookup with test
1 parent 01072e5 commit ab1e78d

File tree

4 files changed

+111
-1
lines changed

4 files changed

+111
-1
lines changed

llvm/include/llvm/Analysis/DXILResource.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,10 @@ class DXILBindingMap {
446446
return Pos == CallMap.end() ? Infos.end() : (Infos.begin() + Pos->second);
447447
}
448448

449+
// Resoloves the use of a resource handle into the unique description of that
450+
// resource by deduping calls to create.
451+
const_iterator findByUse(const Value *Key) const;
452+
449453
const_iterator find(const CallInst *Key) const {
450454
auto Pos = CallMap.find(Key);
451455
return Pos == CallMap.end() ? Infos.end() : (Infos.begin() + Pos->second);

llvm/lib/Analysis/DXILResource.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,23 @@ void DXILBindingMap::print(raw_ostream &OS, DXILResourceTypeMap &DRTM,
770770
}
771771
}
772772

773+
SmallVector<dxil::ResourceBindingInfo>::const_iterator DXILBindingMap::findByUse(const Value *Key) const {
774+
const CallInst *CI = dyn_cast<CallInst>(Key);
775+
if (!CI) {
776+
// TODO: Any other cases to follow up the tree?
777+
return Infos.end();
778+
}
779+
780+
switch (CI->getIntrinsicID()) {
781+
case Intrinsic::not_intrinsic:
782+
return Infos.end();
783+
case Intrinsic::dx_resource_handlefrombinding:
784+
return find(CI);
785+
}
786+
787+
return Infos.end();
788+
}
789+
773790
//===----------------------------------------------------------------------===//
774791

775792
AnalysisKey DXILResourceTypeAnalysis::Key;
@@ -828,7 +845,8 @@ bool DXILResourceBindingWrapperPass::runOnModule(Module &M) {
828845
return false;
829846
}
830847

831-
void DXILResourceBindingWrapperPass::releaseMemory() { Map.reset(); }
848+
void DXILResourceBindingWrapperPass::releaseMemory() {
849+
/*Map.reset();*/ }
832850

833851
void DXILResourceBindingWrapperPass::print(raw_ostream &OS,
834852
const Module *M) const {

llvm/unittests/Target/DirectX/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ set(LLVM_LINK_COMPONENTS
1414
add_llvm_target_unittest(DirectXTests
1515
CBufferDataLayoutTests.cpp
1616
PointerTypeAnalysisTests.cpp
17+
UniqueResourceFromUseTests.cpp
1718
)
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
//===- llvm/unittests/Target/DirectX/PointerTypeAnalysisTests.cpp ---------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "DirectXIRPasses/PointerTypeAnalysis.h"
10+
#include "llvm/Analysis/DXILResource.h"
11+
#include "llvm/AsmParser/Parser.h"
12+
#include "llvm/IR/Instructions.h"
13+
#include "llvm/IR/LLVMContext.h"
14+
#include "llvm/IR/Module.h"
15+
#include "llvm/IR/Type.h"
16+
#include "llvm/IR/TypedPointerType.h"
17+
#include "llvm/Support/Casting.h"
18+
#include "llvm/Support/SourceMgr.h"
19+
#include "llvm/Transforms/Utils/Debugify.h"
20+
21+
#include "gmock/gmock.h"
22+
#include "gtest/gtest.h"
23+
24+
using ::testing::Contains;
25+
using ::testing::Pair;
26+
27+
using namespace llvm;
28+
using namespace llvm::dxil;
29+
30+
template <typename T> struct IsA {
31+
friend bool operator==(const Value *V, const IsA &) { return isa<T>(V); }
32+
};
33+
34+
TEST(UniqueResourceFromUse, TestTrivialUse) {
35+
StringRef Assembly = R"(
36+
define void @main() {
37+
entry:
38+
%handle = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 1, i32 2, i32 3, i32 4, i1 false)
39+
call void @a.func(target("dx.RawBuffer", float, 1, 0) %handle)
40+
ret void
41+
}
42+
43+
declare target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32, i32, i32, i32, i1)
44+
45+
declare void @a.func(target("dx.RawBuffer", float, 1, 0) %handle)
46+
)";
47+
48+
LLVMContext Context;
49+
SMDiagnostic Error;
50+
auto M = parseAssemblyString(Assembly, Error, Context);
51+
ASSERT_TRUE(M) << "Bad assembly?";
52+
DebugifyCustomPassManager Passes;
53+
Passes.add(createDXILResourceTypeWrapperPassPass());
54+
DXILResourceBindingWrapperPass* RBPass = new DXILResourceBindingWrapperPass();
55+
Passes.add(RBPass);
56+
Passes.run(*M);
57+
58+
const DXILBindingMap &DBM = RBPass->getBindingMap();
59+
for (const Function& F : M->functions()) {
60+
if (F.getName() != "a.func") {
61+
continue;
62+
}
63+
64+
unsigned CalledResources = 0;
65+
66+
for (const User* U : F.users()) {
67+
const CallInst* CI = dyn_cast<CallInst>(U);
68+
ASSERT_TRUE(CI) << "All users of @a.func must be CallInst";
69+
70+
const Value* Handle = CI->getArgOperand(0);
71+
72+
const auto* It = DBM.findByUse(Handle);
73+
ASSERT_TRUE(It != DBM.end()) << "Handle should resolve into resource";
74+
75+
const llvm::dxil::ResourceBindingInfo::ResourceBinding& Binding = It->getBinding();
76+
EXPECT_EQ(0u, Binding.RecordID);
77+
EXPECT_EQ(1u, Binding.Space);
78+
EXPECT_EQ(2u, Binding.LowerBound);
79+
EXPECT_EQ(3u, Binding.Size);
80+
81+
CalledResources++;
82+
}
83+
84+
EXPECT_EQ(1u, CalledResources) << "Expected exactly 1 resolved call to create resource";
85+
}
86+
87+
}

0 commit comments

Comments
 (0)