Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
213799 views
1
//===- DXILPostOptimizationValidation.cpp - Opt DXIL validation ----------===//
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 "DXILPostOptimizationValidation.h"
10
#include "DXILShaderFlags.h"
11
#include "DirectX.h"
12
#include "llvm/ADT/SmallString.h"
13
#include "llvm/Analysis/DXILMetadataAnalysis.h"
14
#include "llvm/Analysis/DXILResource.h"
15
#include "llvm/IR/DiagnosticInfo.h"
16
#include "llvm/IR/Instructions.h"
17
#include "llvm/IR/IntrinsicsDirectX.h"
18
#include "llvm/IR/Module.h"
19
#include "llvm/InitializePasses.h"
20
21
#define DEBUG_TYPE "dxil-post-optimization-validation"
22
23
using namespace llvm;
24
using namespace llvm::dxil;
25
26
namespace {
27
28
static void reportInvalidDirection(Module &M, DXILResourceMap &DRM) {
29
for (const auto &UAV : DRM.uavs()) {
30
if (UAV.CounterDirection != ResourceCounterDirection::Invalid)
31
continue;
32
33
CallInst *ResourceHandle = nullptr;
34
for (CallInst *MaybeHandle : DRM.calls()) {
35
if (*DRM.find(MaybeHandle) == UAV) {
36
ResourceHandle = MaybeHandle;
37
break;
38
}
39
}
40
41
StringRef Message = "RWStructuredBuffers may increment or decrement their "
42
"counters, but not both.";
43
for (const auto &U : ResourceHandle->users()) {
44
const CallInst *CI = dyn_cast<CallInst>(U);
45
if (!CI && CI->getIntrinsicID() != Intrinsic::dx_resource_updatecounter)
46
continue;
47
48
M.getContext().diagnose(DiagnosticInfoGenericWithLoc(
49
Message, *CI->getFunction(), CI->getDebugLoc()));
50
}
51
}
52
}
53
54
static void reportOverlappingError(Module &M, ResourceInfo R1,
55
ResourceInfo R2) {
56
SmallString<128> Message;
57
raw_svector_ostream OS(Message);
58
OS << "resource " << R1.getName() << " at register "
59
<< R1.getBinding().LowerBound << " overlaps with resource " << R2.getName()
60
<< " at register " << R2.getBinding().LowerBound << " in space "
61
<< R2.getBinding().Space;
62
M.getContext().diagnose(DiagnosticInfoGeneric(Message));
63
}
64
65
static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {
66
if (DRM.empty())
67
return;
68
69
for (const auto &ResList :
70
{DRM.srvs(), DRM.uavs(), DRM.cbuffers(), DRM.samplers()}) {
71
if (ResList.empty())
72
continue;
73
const ResourceInfo *PrevRI = &*ResList.begin();
74
for (auto *I = ResList.begin() + 1; I != ResList.end(); ++I) {
75
const ResourceInfo *CurrentRI = &*I;
76
const ResourceInfo *RI = CurrentRI;
77
while (RI != ResList.end() &&
78
PrevRI->getBinding().overlapsWith(RI->getBinding())) {
79
reportOverlappingError(M, *PrevRI, *RI);
80
RI++;
81
}
82
PrevRI = CurrentRI;
83
}
84
}
85
}
86
87
static void reportErrors(Module &M, DXILResourceMap &DRM,
88
DXILResourceBindingInfo &DRBI) {
89
if (DRM.hasInvalidCounterDirection())
90
reportInvalidDirection(M, DRM);
91
92
if (DRBI.hasOverlappingBinding())
93
reportOverlappingBinding(M, DRM);
94
95
assert(!DRBI.hasImplicitBinding() && "implicit bindings should be handled in "
96
"DXILResourceImplicitBinding pass");
97
}
98
} // namespace
99
100
PreservedAnalyses
101
DXILPostOptimizationValidation::run(Module &M, ModuleAnalysisManager &MAM) {
102
DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M);
103
DXILResourceBindingInfo &DRBI = MAM.getResult<DXILResourceBindingAnalysis>(M);
104
reportErrors(M, DRM, DRBI);
105
return PreservedAnalyses::all();
106
}
107
108
namespace {
109
class DXILPostOptimizationValidationLegacy : public ModulePass {
110
public:
111
bool runOnModule(Module &M) override {
112
DXILResourceMap &DRM =
113
getAnalysis<DXILResourceWrapperPass>().getResourceMap();
114
DXILResourceBindingInfo &DRBI =
115
getAnalysis<DXILResourceBindingWrapperPass>().getBindingInfo();
116
reportErrors(M, DRM, DRBI);
117
return false;
118
}
119
StringRef getPassName() const override {
120
return "DXIL Post Optimization Validation";
121
}
122
DXILPostOptimizationValidationLegacy() : ModulePass(ID) {}
123
124
static char ID; // Pass identification.
125
void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
126
AU.addRequired<DXILResourceWrapperPass>();
127
AU.addRequired<DXILResourceBindingWrapperPass>();
128
AU.addPreserved<DXILResourceWrapperPass>();
129
AU.addPreserved<DXILResourceBindingWrapperPass>();
130
AU.addPreserved<DXILMetadataAnalysisWrapperPass>();
131
AU.addPreserved<ShaderFlagsAnalysisWrapper>();
132
}
133
};
134
char DXILPostOptimizationValidationLegacy::ID = 0;
135
} // end anonymous namespace
136
137
INITIALIZE_PASS_BEGIN(DXILPostOptimizationValidationLegacy, DEBUG_TYPE,
138
"DXIL Post Optimization Validation", false, false)
139
INITIALIZE_PASS_DEPENDENCY(DXILResourceBindingWrapperPass)
140
INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)
141
INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
142
INITIALIZE_PASS_END(DXILPostOptimizationValidationLegacy, DEBUG_TYPE,
143
"DXIL Post Optimization Validation", false, false)
144
145
ModulePass *llvm::createDXILPostOptimizationValidationLegacyPass() {
146
return new DXILPostOptimizationValidationLegacy();
147
}
148
149