Skip to content

Commit 4fefba3

Browse files
authored
Pix: Debug instrumentation: Create values per-function (#4976) (#4977)
The previous formulation had a single member variable for several Values which would be used in multiple functions of a lib, which of course means that in all but one of those functions, the Values' creation function was not the right one. Funnily enough, I had got this right in the access-tracking pass but somehow neglected to do it in the debugging pass. (Also need to audit the other passes to make sure I haven't been repeating the mistake.)
1 parent 4f0c290 commit 4fefba3

1 file changed

Lines changed: 58 additions & 48 deletions

File tree

lib/DxilPIXPasses/DxilDebugInstrumentation.cpp

Lines changed: 58 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -214,27 +214,28 @@ class DxilDebugInstrumentation : public ModulePass {
214214
};
215215

216216
uint64_t m_UAVSize = 1024 * 1024;
217-
Value *m_SelectionCriterion = nullptr;
218-
CallInst *m_HandleForUAV = nullptr;
219-
Value *m_InvocationId = nullptr;
220-
221-
// Together these two values allow branchless writing to the UAV. An
222-
// invocation of the shader is either of interest or not (e.g. it writes to
223-
// the pixel the user selected for debugging or it doesn't). If not of
224-
// interest, debugging output will still occur, but it will be relegated to
225-
// the very top few bytes of the UAV. Invocations of interest, by contrast,
226-
// will be written to the UAV at sequentially increasing offsets.
227-
228-
// This value will either be one or zero (one if the invocation is of
229-
// interest, zero otherwise)
230-
Value *m_OffsetMultiplicand = nullptr;
231-
// This will either be zero (if the invocation is of interest) or
232-
// (UAVSize)-(SmallValue) if not.
233-
Value *m_OffsetAddend = nullptr;
234-
235-
Constant *m_OffsetMask = nullptr;
236-
237-
Constant *m_CounterOffset = nullptr;
217+
struct PerFunctionValues
218+
{
219+
CallInst *UAVHandle;
220+
Constant *CounterOffset;
221+
Value *InvocationId;
222+
// Together these two values allow branchless writing to the UAV. An
223+
// invocation of the shader is either of interest or not (e.g. it writes to
224+
// the pixel the user selected for debugging or it doesn't). If not of
225+
// interest, debugging output will still occur, but it will be relegated to
226+
// the very top few bytes of the UAV. Invocations of interest, by contrast,
227+
// will be written to the UAV at sequentially increasing offsets.
228+
// This value will either be one or zero (one if the invocation is of
229+
// interest, zero otherwise)
230+
Value *OffsetMultiplicand;
231+
// This will either be zero (if the invocation is of interest) or
232+
// (UAVSize)-(SmallValue) if not.
233+
Value *OffsetAddend;
234+
Constant *OffsetMask;
235+
Value *SelectionCriterion = nullptr;
236+
Value *CurrentIndex = nullptr;
237+
};
238+
std::map<llvm::Function *, PerFunctionValues> m_FunctionToValues;
238239

239240
struct BuilderContext {
240241
Module &M;
@@ -245,7 +246,6 @@ class DxilDebugInstrumentation : public ModulePass {
245246
};
246247

247248
uint32_t m_RemainingReservedSpaceInBytes = 0;
248-
Value *m_CurrentIndex = nullptr;
249249

250250
public:
251251
static char ID; // Pass identification, replacement for typeid
@@ -651,25 +651,25 @@ void DxilDebugInstrumentation::addInvocationSelectionProlog(
651651

652652
// This is a convenient place to calculate the values that modify the UAV
653653
// offset for invocations of interest and for UAV size.
654-
m_OffsetMultiplicand =
654+
auto &values = m_FunctionToValues[BC.Builder.GetInsertBlock()->getParent()];
655+
values.OffsetMultiplicand =
655656
BC.Builder.CreateCast(Instruction::CastOps::ZExt, ParameterTestResult,
656657
Type::getInt32Ty(BC.Ctx), "OffsetMultiplicand");
657658
auto InverseOffsetMultiplicand =
658-
BC.Builder.CreateSub(BC.HlslOP->GetU32Const(1), m_OffsetMultiplicand,
659+
BC.Builder.CreateSub(BC.HlslOP->GetU32Const(1), values.OffsetMultiplicand,
659660
"ComplementOfMultiplicand");
660-
m_OffsetAddend =
661+
values.OffsetAddend =
661662
BC.Builder.CreateMul(BC.HlslOP->GetU32Const(UAVDumpingGroundOffset()),
662663
InverseOffsetMultiplicand, "OffsetAddend");
663-
m_OffsetMask = BC.HlslOP->GetU32Const(UAVDumpingGroundOffset() - 1);
664+
values.OffsetMask = BC.HlslOP->GetU32Const(UAVDumpingGroundOffset() - 1);
664665

665-
m_CounterOffset = BC.HlslOP->GetU32Const(UAVDumpingGroundOffset() + CounterOffsetBeyondUsefulData);
666-
667-
m_SelectionCriterion = ParameterTestResult;
666+
values.SelectionCriterion = ParameterTestResult;
668667
}
669668

670669
void DxilDebugInstrumentation::reserveDebugEntrySpace(BuilderContext &BC,
671670
uint32_t SpaceInBytes) {
672-
assert(m_CurrentIndex == nullptr);
671+
auto &values = m_FunctionToValues[BC.Builder.GetInsertBlock()->getParent()];
672+
assert(values.CurrentIndex == nullptr);
673673
assert(m_RemainingReservedSpaceInBytes == 0);
674674

675675
m_RemainingReservedSpaceInBytes = SpaceInBytes;
@@ -686,36 +686,36 @@ void DxilDebugInstrumentation::reserveDebugEntrySpace(BuilderContext &BC,
686686
// so inc will be zero for uninteresting invocations:
687687
Constant *Increment = BC.HlslOP->GetU32Const(SpaceInBytes);
688688
Value *IncrementForThisInvocation = BC.Builder.CreateMul(
689-
Increment, m_OffsetMultiplicand, "IncrementForThisInvocation");
689+
Increment, values.OffsetMultiplicand, "IncrementForThisInvocation");
690690

691691
auto PreviousValue = BC.Builder.CreateCall(
692692
AtomicOpFunc,
693693
{
694694
AtomicBinOpcode, // i32, ; opcode
695-
m_HandleForUAV, // %dx.types.Handle, ; resource handle
695+
values.UAVHandle, // %dx.types.Handle, ; resource handle
696696
AtomicAdd, // i32, ; binary operation code : EXCHANGE, IADD, AND, OR,
697697
// XOR, IMIN, IMAX, UMIN, UMAX
698-
m_CounterOffset, // i32, ; coordinate c0: index in bytes
698+
values.CounterOffset, // i32, ; coordinate c0: index in bytes
699699
UndefArg, // i32, ; coordinate c1 (unused)
700700
UndefArg, // i32, ; coordinate c2 (unused)
701701
IncrementForThisInvocation, // i32); increment value
702702
},
703703
"UAVIncResult");
704704

705-
if (m_InvocationId == nullptr) {
706-
m_InvocationId = PreviousValue;
705+
if (values.InvocationId == nullptr) {
706+
values.InvocationId = PreviousValue;
707707
}
708708

709709
auto MaskedForLimit =
710-
BC.Builder.CreateAnd(PreviousValue, m_OffsetMask, "MaskedForUAVLimit");
710+
BC.Builder.CreateAnd(PreviousValue, values.OffsetMask, "MaskedForUAVLimit");
711711
// The return value will either end up being itself (multiplied by one and
712712
// added with zero) or the "dump uninteresting things here" value of (UAVSize
713713
// - a bit).
714714
auto MultipliedForInterest = BC.Builder.CreateMul(
715-
MaskedForLimit, m_OffsetMultiplicand, "MultipliedForInterest");
715+
MaskedForLimit, values.OffsetMultiplicand, "MultipliedForInterest");
716716
auto AddedForInterest = BC.Builder.CreateAdd(
717-
MultipliedForInterest, m_OffsetAddend, "AddedForInterest");
718-
m_CurrentIndex = AddedForInterest;
717+
MultipliedForInterest, values.OffsetAddend, "AddedForInterest");
718+
values.CurrentIndex = AddedForInterest;
719719
}
720720

721721
void DxilDebugInstrumentation::addDebugEntryValue(BuilderContext &BC,
@@ -774,10 +774,13 @@ void DxilDebugInstrumentation::addDebugEntryValue(BuilderContext &BC,
774774
assert(false);
775775
}
776776
Constant *WriteMask_X = BC.HlslOP->GetI8Const(1);
777+
778+
auto &values = m_FunctionToValues[BC.Builder.GetInsertBlock()->getParent()];
779+
777780
(void)BC.Builder.CreateCall(
778781
StoreValue, {StoreValueOpcode, // i32 opcode
779-
m_HandleForUAV, // %dx.types.Handle, ; resource handle
780-
m_CurrentIndex, // i32 c0: index in bytes into UAV
782+
values.UAVHandle, // %dx.types.Handle, ; resource handle
783+
values.CurrentIndex, // i32 c0: index in bytes into UAV
781784
Undef32Arg, // i32 c1: unused
782785
TheValue,
783786
UndefArg, // unused values
@@ -789,10 +792,10 @@ void DxilDebugInstrumentation::addDebugEntryValue(BuilderContext &BC,
789792
assert(m_RemainingReservedSpaceInBytes < 1024); // check for underflow
790793

791794
if (m_RemainingReservedSpaceInBytes != 0) {
792-
m_CurrentIndex =
793-
BC.Builder.CreateAdd(m_CurrentIndex, BC.HlslOP->GetU32Const(4));
795+
values.CurrentIndex =
796+
BC.Builder.CreateAdd(values.CurrentIndex, BC.HlslOP->GetU32Const(4));
794797
} else {
795-
m_CurrentIndex = nullptr;
798+
values.CurrentIndex = nullptr;
796799
}
797800
}
798801
}
@@ -808,7 +811,8 @@ void DxilDebugInstrumentation::addInvocationStartMarker(BuilderContext &BC) {
808811
marker.Header.Details.Type =
809812
DebugShaderModifierRecordTypeInvocationStartMarker;
810813
addDebugEntryValue(BC, BC.HlslOP->GetU32Const(marker.Header.u32Header));
811-
addDebugEntryValue(BC, m_InvocationId);
814+
auto &values = m_FunctionToValues[BC.Builder.GetInsertBlock()->getParent()];
815+
addDebugEntryValue(BC, values.InvocationId);
812816
}
813817

814818
template <typename ReturnType>
@@ -819,11 +823,13 @@ void DxilDebugInstrumentation::addStepEntryForType(
819823
DebugShaderModifierRecordDXILStep<ReturnType> step = {};
820824
reserveDebugEntrySpace(BC, sizeof(step));
821825

826+
auto &values = m_FunctionToValues[BC.Builder.GetInsertBlock()->getParent()];
827+
822828
step.Header.Details.SizeDwords =
823829
DebugShaderModifierRecordPayloadSizeDwords(sizeof(step));
824830
step.Header.Details.Type = static_cast<uint8_t>(RecordType);
825831
addDebugEntryValue(BC, BC.HlslOP->GetU32Const(step.Header.u32Header));
826-
addDebugEntryValue(BC, m_InvocationId);
832+
addDebugEntryValue(BC, values.InvocationId);
827833
addDebugEntryValue(BC, BC.HlslOP->GetU32Const(InstNum));
828834

829835
if (RecordType != DebugShaderModifierRecordTypeDXILStepVoid) {
@@ -1034,8 +1040,12 @@ bool DxilDebugInstrumentation::RunOnFunction(
10341040

10351041
BuilderContext BC{M, DM, Ctx, HlslOP, Builder};
10361042

1037-
m_HandleForUAV =
1038-
PIXPassHelpers::CreateUAV(BC.DM, BC.Builder, 0, "PIX_DebugUAV_Handle");
1043+
auto &values = m_FunctionToValues[BC.Builder.GetInsertBlock()->getParent()];
1044+
1045+
values.UAVHandle = PIXPassHelpers::CreateUAV(
1046+
DM, Builder, static_cast<unsigned int>(m_FunctionToValues.size()),
1047+
"PIX_DebugUAV_Handle");
1048+
values.CounterOffset = BC.HlslOP->GetU32Const(UAVDumpingGroundOffset() + CounterOffsetBeyondUsefulData);
10391049

10401050
auto SystemValues = addRequiredSystemValues(BC, shaderKind);
10411051
addInvocationSelectionProlog(BC, SystemValues, shaderKind);

0 commit comments

Comments
 (0)