Skip to content

Commit ccea7c2

Browse files
authored
PIX: Fix instrumentation of libraries; instruction numbering reports (#4817)
* PIX: A few fixes for instrumentation of libraries; instruction numbering reporting * Fix for tests: don't debug-instrument the patch constant fn
1 parent d0e0aa9 commit ccea7c2

7 files changed

Lines changed: 286 additions & 58 deletions

File tree

lib/DxilPIXPasses/DxilAnnotateWithVirtualRegister.cpp

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <memory>
1515

1616
#include "dxc/DXIL/DxilModule.h"
17+
#include "dxc/DXIL/DxilOperations.h"
1718
#include "dxc/DxilPIXPasses/DxilPIXPasses.h"
1819
#include "dxc/DxilPIXPasses/DxilPIXVirtualRegisters.h"
1920
#include "dxc/Support/Global.h"
@@ -70,6 +71,7 @@ class DxilAnnotateWithVirtualRegister : public llvm::ModulePass {
7071
DxilAnnotateWithVirtualRegister() : llvm::ModulePass(ID) {}
7172

7273
bool runOnModule(llvm::Module &M) override;
74+
void applyOptions(llvm::PassOptions O) override;
7375

7476
private:
7577
void AnnotateValues(llvm::Instruction *pI);
@@ -86,6 +88,8 @@ class DxilAnnotateWithVirtualRegister : public llvm::ModulePass {
8688
hlsl::DxilModule* m_DM;
8789
std::uint32_t m_uVReg;
8890
std::unique_ptr<llvm::ModuleSlotTracker> m_MST;
91+
int m_StartInstruction = 0;
92+
8993
void Init(llvm::Module &M) {
9094
m_DM = &M.GetOrCreateDxilModule();
9195
m_uVReg = 0;
@@ -97,6 +101,10 @@ class DxilAnnotateWithVirtualRegister : public llvm::ModulePass {
97101
}
98102
};
99103

104+
void DxilAnnotateWithVirtualRegister::applyOptions(llvm::PassOptions O) {
105+
GetPassOptionInt(O, "startInstruction", &m_StartInstruction, 0);
106+
}
107+
100108
char DxilAnnotateWithVirtualRegister::ID = 0;
101109

102110
bool DxilAnnotateWithVirtualRegister::runOnModule(llvm::Module &M) {
@@ -111,37 +119,55 @@ bool DxilAnnotateWithVirtualRegister::runOnModule(llvm::Module &M) {
111119
m_DM->SetValidatorVersion(1, 4);
112120
}
113121

114-
std::uint32_t InstNum = 0;
115-
auto blocks = PIXPassHelpers::GetAllBlocks(*m_DM);
116-
for(auto * block : blocks) {
117-
for (llvm::Instruction& I : block->getInstList()) {
118-
if (!llvm::isa<llvm::DbgDeclareInst>(&I)) {
119-
pix_dxil::PixDxilInstNum::AddMD(M.getContext(), &I, InstNum++);
122+
std::uint32_t InstNum = m_StartInstruction;
123+
std::map<llvm::StringRef, std::pair<int, int>> InstructionRangeByFunctionName;
124+
125+
auto instrumentableFunctions = PIXPassHelpers::GetAllInstrumentableFunctions(*m_DM);
126+
127+
for (auto * F : instrumentableFunctions) {
128+
auto &EndInstruction = InstructionRangeByFunctionName[F->getName()];
129+
EndInstruction.first = InstNum;
130+
for (auto &block : F->getBasicBlockList()) {
131+
for (llvm::Instruction &I : block.getInstList()) {
132+
if (!llvm::isa<llvm::DbgDeclareInst>(&I)) {
133+
pix_dxil::PixDxilInstNum::AddMD(M.getContext(), &I, InstNum++);
134+
EndInstruction.second = InstNum;
135+
}
120136
}
121137
}
122138
}
123139

124140
if (OSOverride != nullptr) {
141+
// Print a set of strings of the exemplary form "InstructionCount: <n> <fnName>"
125142
*OSOverride << "\nInstructionCount:" << InstNum << "\n";
126-
}
127-
128-
if (OSOverride != nullptr) {
129-
*OSOverride << "\nEnd - instruction ID to line\n";
130-
}
143+
for (auto const &fn : InstructionRangeByFunctionName) {
144+
*OSOverride << "InstructionRange: ";
145+
int skipOverLeadingUnprintableCharacters = 0;
146+
if (fn.first.size() > 2 && fn.first[0] == '\1' && fn.first[1] == '?') {
147+
skipOverLeadingUnprintableCharacters = 2;
148+
}
149+
*OSOverride << fn.second.first << " " << fn.second.second << " "
150+
<< (fn.first.str().c_str() +
151+
skipOverLeadingUnprintableCharacters)
152+
<< "\n";
153+
}
131154

132-
if (OSOverride != nullptr) {
133155
*OSOverride << "\nBegin - dxil values to virtual register mapping\n";
134156
}
135157

136-
for (auto* block : blocks) {
137-
for (llvm::Instruction& I : block->getInstList()) {
138-
AnnotateValues(&I);
158+
for (auto * F : instrumentableFunctions) {
159+
for (auto &block : F->getBasicBlockList()) {
160+
for (llvm::Instruction &I : block.getInstList()) {
161+
AnnotateValues(&I);
162+
}
139163
}
140164
}
141165

142-
for (auto* block : blocks) {
143-
for (llvm::Instruction& I : block->getInstList()) {
144-
AnnotateStore(&I);
166+
for (auto * F : instrumentableFunctions) {
167+
for (auto &block : F->getBasicBlockList()) {
168+
for (llvm::Instruction &I : block.getInstList()) {
169+
AnnotateStore(&I);
170+
}
145171
}
146172
}
147173

lib/DxilPIXPasses/DxilDebugInstrumentation.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -955,14 +955,16 @@ bool DxilDebugInstrumentation::runOnModule(Module &M) {
955955

956956
bool modified = false;
957957
if (shaderKind == DXIL::ShaderKind::Library) {
958-
for (llvm::Function& F : M.functions()) {
959-
modified = modified | RunOnFunction(M, DM, &F);
960-
return modified;
958+
auto instrumentableFunctions =
959+
PIXPassHelpers::GetAllInstrumentableFunctions(DM);
960+
for (auto *F : instrumentableFunctions) {
961+
if (RunOnFunction(M, DM, F)) {
962+
modified = true;
963+
}
961964
}
962-
}
963-
else {
965+
} else {
964966
llvm::Function *entryFunction = PIXPassHelpers::GetEntryFunction(DM);
965-
modified = RunOnFunction(M, DM, entryFunction);
967+
modified = RunOnFunction(M, DM, entryFunction);
966968
}
967969
return modified;
968970
}

lib/DxilPIXPasses/DxilShaderAccessTracking.cpp

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -894,51 +894,49 @@ bool DxilShaderAccessTracking::runOnModule(Module &M) {
894894
}
895895
}
896896
} else {
897+
898+
auto instrumentableFunctions =
899+
PIXPassHelpers::GetAllInstrumentableFunctions(DM);
900+
897901
if (DM.m_ShaderFlags.GetForceEarlyDepthStencil()) {
898902
if (OSOverride != nullptr) {
899903
formatted_raw_ostream FOS(*OSOverride);
900904
FOS << "ShouldAssumeDsvAccess";
901905
}
902906
}
903907
int uavRegId = 0;
904-
for (llvm::Function &F : M.functions()) {
905-
if (!F.getBasicBlockList().empty()) {
906-
907-
DXIL::ShaderKind shaderKind = DXIL::ShaderKind::Invalid;
908-
if (!DM.HasDxilFunctionProps(&F)) {
909-
auto ShaderModel = DM.GetShaderModel();
910-
shaderKind = ShaderModel->GetKind();
911-
if (shaderKind == DXIL::ShaderKind::Library) {
912-
continue;
913-
}
914-
} else {
915-
hlsl::DxilFunctionProps const &props = DM.GetDxilFunctionProps(&F);
916-
shaderKind = props.shaderKind;
908+
for (auto * F : instrumentableFunctions) {
909+
DXIL::ShaderKind shaderKind = DXIL::ShaderKind::Invalid;
910+
if (!DM.HasDxilFunctionProps(F)) {
911+
auto ShaderModel = DM.GetShaderModel();
912+
shaderKind = ShaderModel->GetKind();
913+
if (shaderKind == DXIL::ShaderKind::Library) {
914+
continue;
917915
}
916+
} else {
917+
hlsl::DxilFunctionProps const &props = DM.GetDxilFunctionProps(F);
918+
shaderKind = props.shaderKind;
919+
}
918920

919-
IRBuilder<> Builder(F.getEntryBlock().getFirstInsertionPt());
920-
921-
m_FunctionToUAVHandle[&F] = PIXPassHelpers::CreateUAV(
922-
DM, Builder, uavRegId++, "PIX_CountUAV_Handle");
923-
OP *HlslOP = DM.GetOP();
924-
for (int accessStyle = static_cast<int>(ResourceAccessStyle::None);
925-
accessStyle < static_cast<int>(ResourceAccessStyle::EndOfEnum);
926-
++accessStyle) {
927-
ResourceAccessStyle style =
928-
static_cast<ResourceAccessStyle>(accessStyle);
929-
m_FunctionToEncodedAccess[&F][style] = HlslOP->GetU32Const(
930-
EncodeShaderModel(shaderKind) | EncodeAccess(style));
931-
}
921+
IRBuilder<> Builder(F->getEntryBlock().getFirstInsertionPt());
922+
923+
m_FunctionToUAVHandle[F] = PIXPassHelpers::CreateUAV(
924+
DM, Builder, uavRegId++, "PIX_CountUAV_Handle");
925+
OP *HlslOP = DM.GetOP();
926+
for (int accessStyle = static_cast<int>(ResourceAccessStyle::None);
927+
accessStyle < static_cast<int>(ResourceAccessStyle::EndOfEnum);
928+
++accessStyle) {
929+
ResourceAccessStyle style =
930+
static_cast<ResourceAccessStyle>(accessStyle);
931+
m_FunctionToEncodedAccess[F][style] = HlslOP->GetU32Const(
932+
EncodeShaderModel(shaderKind) | EncodeAccess(style));
932933
}
933934
}
934935
DM.ReEmitDxilResources();
935936

936937
for (llvm::Function &F : M.functions()) {
937-
// Only used DXIL intrinsics:
938-
if (!F.isDeclaration() || F.isIntrinsic() || F.use_empty() ||
939-
!OP::IsDxilOpFunc(&F))
938+
if (!F.isDeclaration() || F.isIntrinsic() || !OP::IsDxilOpFunc(&F))
940939
continue;
941-
942940
// Gather handle parameter indices, if any
943941
FunctionType *fnTy =
944942
cast<FunctionType>(F.getType()->getPointerElementType());

lib/DxilPIXPasses/PixPassHelpers.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,22 @@ llvm::Function* GetEntryFunction(hlsl::DxilModule& DM) {
224224
return DM.GetPatchConstantFunction();
225225
}
226226

227+
std::vector<llvm::Function *>
228+
GetAllInstrumentableFunctions(hlsl::DxilModule &DM) {
229+
230+
std::vector<llvm::Function *> ret;
231+
232+
for (llvm::Function &F : DM.GetModule()->functions()) {
233+
if (F.isDeclaration() || F.isIntrinsic() || hlsl::OP::IsDxilOpFunc(&F))
234+
continue;
235+
if (F.getBasicBlockList().empty())
236+
continue;
237+
ret.push_back(&F);
238+
}
239+
240+
return ret;
241+
}
242+
227243
std::vector<llvm::BasicBlock*> GetAllBlocks(hlsl::DxilModule& DM) {
228244
std::vector<llvm::BasicBlock*> ret;
229245
auto entryPoints = DM.GetExportedFunctions();

lib/DxilPIXPasses/PixPassHelpers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace PIXPassHelpers
2929
const char* name);
3030
llvm::Function* GetEntryFunction(hlsl::DxilModule& DM);
3131
std::vector<llvm::BasicBlock*> GetAllBlocks(hlsl::DxilModule& DM);
32+
std::vector<llvm::Function*> GetAllInstrumentableFunctions(hlsl::DxilModule& DM);
3233
#ifdef PIX_DEBUG_DUMP_HELPER
3334
void Log(const char* format, ...);
3435
void LogPartialLine(const char* format, ...);

0 commit comments

Comments
 (0)