@@ -76,19 +76,29 @@ class DxilAnnotateWithVirtualRegister : public llvm::ModulePass {
7676
7777private:
7878 void AnnotateValues (llvm::Instruction *pI);
79- void AnnotateStore (llvm::Instruction *pI);
80- void SplitVectorStores (hlsl::OP *HlslOP, llvm::Instruction *pI);
79+ void AnnotateStore (hlsl::OP *HlslOP, llvm::Instruction *pI);
80+ void SplitVectorStores (llvm::Instruction *pI);
8181 bool IsAllocaRegisterWrite (llvm::Value *V, llvm::AllocaInst **pAI,
8282 llvm::Value **pIdx);
8383 void AnnotateAlloca (llvm::AllocaInst *pAlloca);
8484 void AnnotateGeneric (llvm::Instruction *pI);
8585 void AssignNewDxilRegister (llvm::Instruction *pI);
8686 void AssignNewAllocaRegister (llvm::AllocaInst *pAlloca, std::uint32_t C);
87-
87+ llvm::Value *AddConstIntValues (llvm::Value *l, llvm::Value *r);
88+ llvm::Value *MultiplyConstIntValue (llvm::Value *l, uint32_t r);
89+ llvm::Value *GetStructOffset (llvm::GetElementPtrInst *pGEP,
90+ uint32_t &GEPOperandIndex,
91+ llvm::Type *pElementType);
8892 hlsl::DxilModule *m_DM;
8993 std::uint32_t m_uVReg;
9094 std::unique_ptr<llvm::ModuleSlotTracker> m_MST;
9195 int m_StartInstruction = 0 ;
96+ struct RememberedAllocaStores {
97+ llvm::StoreInst *StoreInst;
98+ llvm::Value *Index;
99+ llvm::MDNode *AllocaReg;
100+ };
101+ std::vector<RememberedAllocaStores> m_RememberedAllocaStores;
92102
93103 void Init (llvm::Module &M) {
94104 m_DM = &M.GetOrCreateDxilModule ();
@@ -129,16 +139,14 @@ bool DxilAnnotateWithVirtualRegister::runOnModule(llvm::Module &M) {
129139 m_DM->SetValidatorVersion (1 , 4 );
130140 }
131141
132- std::uint32_t InstNum = m_StartInstruction;
133-
134142 auto instrumentableFunctions =
135143 PIXPassHelpers::GetAllInstrumentableFunctions (*m_DM);
136144
137145 for (auto *F : instrumentableFunctions) {
138146 for (auto &block : F->getBasicBlockList ()) {
139147 for (auto it = block.begin (); it != block.end ();) {
140148 llvm::Instruction *I = &*(it++);
141- SplitVectorStores (m_DM-> GetOP (), I);
149+ SplitVectorStores (I);
142150 }
143151 }
144152 }
@@ -151,17 +159,32 @@ bool DxilAnnotateWithVirtualRegister::runOnModule(llvm::Module &M) {
151159 }
152160 }
153161
162+ // Process all allocas referenced by dbg.declare intrinsics
154163 for (auto *F : instrumentableFunctions) {
155164 for (auto &block : F->getBasicBlockList ()) {
156- for (llvm::Instruction &I : block.getInstList ()) {
157- AnnotateStore (&I);
165+ for (auto &I : block) {
166+ if (auto *DbgDeclare = llvm::dyn_cast<llvm::DbgDeclareInst>(&I)) {
167+ // The first operand of DbgDeclare is the address (typically an
168+ // AllocaInst)
169+ if (auto *AddrVal =
170+ llvm::dyn_cast<llvm::Instruction>(DbgDeclare->getAddress ())) {
171+ AnnotateValues (AddrVal);
172+ }
173+ }
158174 }
159175 }
160176 }
161177
178+ for (auto *F : instrumentableFunctions)
179+ for (auto &block : F->getBasicBlockList ()) {
180+ for (llvm::Instruction &I : block.getInstList ()) {
181+ AnnotateStore (m_DM->GetOP (), &I);
182+ }
183+ }
184+
162185 for (auto *F : instrumentableFunctions) {
163- int InstructionRangeStart = InstNum ;
164- int InstructionRangeEnd = InstNum ;
186+ int InstructionRangeStart = m_StartInstruction ;
187+ int InstructionRangeEnd = m_StartInstruction ;
165188 for (auto &block : F->getBasicBlockList ()) {
166189 for (llvm::Instruction &I : block.getInstList ()) {
167190 // If the instruction is part of the debug value instrumentation added
@@ -171,8 +194,9 @@ bool DxilAnnotateWithVirtualRegister::runOnModule(llvm::Module &M) {
171194 if (PixAllocaReg::FromInst (Alloca, &unused1, &unused2))
172195 continue ;
173196 if (!llvm::isa<llvm::DbgDeclareInst>(&I)) {
174- pix_dxil::PixDxilInstNum::AddMD (M.getContext (), &I, InstNum++);
175- InstructionRangeEnd = InstNum;
197+ pix_dxil::PixDxilInstNum::AddMD (M.getContext (), &I,
198+ m_StartInstruction++);
199+ InstructionRangeEnd = m_StartInstruction;
176200 }
177201 }
178202 }
@@ -188,12 +212,17 @@ bool DxilAnnotateWithVirtualRegister::runOnModule(llvm::Module &M) {
188212 }
189213 }
190214
215+ for (auto const &as : m_RememberedAllocaStores) {
216+ PixAllocaRegWrite::AddMD (m_DM->GetCtx (), as.StoreInst , as.AllocaReg ,
217+ as.Index );
218+ }
219+
191220 if (OSOverride != nullptr ) {
192221 // Print a set of strings of the exemplary form "InstructionCount: <n>
193222 // <fnName>"
194223 if (m_DM->GetShaderModel ()->GetKind () == hlsl::ShaderModel::Kind::Library)
195224 *OSOverride << " \n IsLibrary\n " ;
196- *OSOverride << " \n InstructionCount:" << InstNum << " \n " ;
225+ *OSOverride << " \n InstructionCount:" << m_StartInstruction << " \n " ;
197226 }
198227
199228 m_DM = nullptr ;
@@ -210,7 +239,8 @@ void DxilAnnotateWithVirtualRegister::AnnotateValues(llvm::Instruction *pI) {
210239 }
211240}
212241
213- void DxilAnnotateWithVirtualRegister::AnnotateStore (llvm::Instruction *pI) {
242+ void DxilAnnotateWithVirtualRegister::AnnotateStore (hlsl::OP *HlslOP,
243+ llvm::Instruction *pI) {
214244 auto *pSt = llvm::dyn_cast<llvm::StoreInst>(pI);
215245 if (pSt == nullptr ) {
216246 return ;
@@ -226,15 +256,47 @@ void DxilAnnotateWithVirtualRegister::AnnotateStore(llvm::Instruction *pI) {
226256 if (AllocaReg == nullptr ) {
227257 return ;
228258 }
259+ m_RememberedAllocaStores.push_back ({pSt, Index, AllocaReg});
260+ }
261+
262+ llvm::Value *
263+ DxilAnnotateWithVirtualRegister::MultiplyConstIntValue (llvm::Value *l,
264+ uint32_t r) {
265+ if (r == 1 )
266+ return l;
267+ if (auto *lci = llvm::dyn_cast<llvm::ConstantInt>(l))
268+ return m_DM->GetOP ()->GetU32Const (lci->getLimitedValue () * r);
269+ // Should never get here, but if we do, return the left as a reasonable
270+ // default:
271+ return l;
272+ }
229273
230- PixAllocaRegWrite::AddMD (m_DM->GetCtx (), pSt, AllocaReg, Index);
274+ llvm::Value *
275+ DxilAnnotateWithVirtualRegister::AddConstIntValues (llvm::Value *l,
276+ llvm::Value *r) {
277+ auto *rci = llvm::dyn_cast<llvm::ConstantInt>(r);
278+ if (rci && rci->getLimitedValue () == 0 )
279+ return l;
280+ auto *lci = llvm::dyn_cast<llvm::ConstantInt>(l);
281+ if (lci && lci->getLimitedValue () == 0 )
282+ return r;
283+ // Both an assert and a check, in case of unexpected circumstances.
284+ DXASSERT (lci != nullptr && rci != nullptr ,
285+ " Both sides of add should be constant ints" );
286+ if (lci != nullptr && rci != nullptr )
287+ return m_DM->GetOP ()->GetU32Const (lci->getLimitedValue () +
288+ rci->getLimitedValue ());
289+ // In an emergency, return the left argument. It'll be closest to
290+ // the desired value.
291+ return l;
231292}
232293
233- static uint32_t GetStructOffset (llvm::GetElementPtrInst *pGEP,
234- uint32_t &GEPOperandIndex,
235- llvm::Type *pElementType) {
294+ llvm::Value *
295+ DxilAnnotateWithVirtualRegister::GetStructOffset (llvm::GetElementPtrInst *pGEP,
296+ uint32_t &GEPOperandIndex,
297+ llvm::Type *pElementType) {
236298 if (IsInstrumentableFundamentalType (pElementType)) {
237- return 0 ;
299+ return m_DM-> GetOP ()-> GetU32Const ( 0 ) ;
238300 } else if (auto *pArray = llvm::dyn_cast<llvm::ArrayType>(pElementType)) {
239301 // 1D-array example:
240302 //
@@ -248,18 +310,13 @@ static uint32_t GetStructOffset(llvm::GetElementPtrInst *pGEP,
248310 // -The zeroth element in the struct (which is the array)
249311 // -The zeroth element in that array
250312
251- auto *pArrayIndex =
252- llvm::dyn_cast<llvm::ConstantInt>(pGEP->getOperand (GEPOperandIndex++));
253-
254- if (pArrayIndex == nullptr ) {
255- return 0 ;
256- }
313+ auto *pArrayIndex = pGEP->getOperand (GEPOperandIndex++);
257314
258- uint32_t ArrayIndex = pArrayIndex->getLimitedValue ();
259315 auto pArrayElementType = pArray->getArrayElementType ();
260- uint32_t MemberIndex = ArrayIndex * CountStructMembers (pArrayElementType);
261- return MemberIndex +
262- GetStructOffset (pGEP, GEPOperandIndex, pArrayElementType);
316+ auto *MemberIndex = MultiplyConstIntValue (
317+ pArrayIndex, CountStructMembers (pArrayElementType));
318+ return AddConstIntValues (
319+ MemberIndex, GetStructOffset (pGEP, GEPOperandIndex, pArrayElementType));
263320 } else if (auto *pStruct = llvm::dyn_cast<llvm::StructType>(pElementType)) {
264321 DXASSERT (GEPOperandIndex < pGEP->getNumOperands (),
265322 " Unexpectedly read too many GetElementPtrInst operands" );
@@ -268,7 +325,7 @@ static uint32_t GetStructOffset(llvm::GetElementPtrInst *pGEP,
268325 llvm::dyn_cast<llvm::ConstantInt>(pGEP->getOperand (GEPOperandIndex++));
269326
270327 if (pMemberIndex == nullptr ) {
271- return 0 ;
328+ return m_DM-> GetOP ()-> GetU32Const ( 0 ) ;
272329 }
273330
274331 uint32_t MemberIndex = pMemberIndex->getLimitedValue ();
@@ -278,16 +335,17 @@ static uint32_t GetStructOffset(llvm::GetElementPtrInst *pGEP,
278335 MemberOffset += CountStructMembers (pStruct->getElementType (i));
279336 }
280337
281- return MemberOffset + GetStructOffset (pGEP, GEPOperandIndex,
282- pStruct->getElementType (MemberIndex));
338+ return AddConstIntValues (
339+ m_DM->GetOP ()->GetU32Const (MemberOffset),
340+ GetStructOffset (pGEP, GEPOperandIndex,
341+ pStruct->getElementType (MemberIndex)));
283342 } else {
284- return 0 ;
343+ return m_DM-> GetOP ()-> GetU32Const ( 0 ) ;
285344 }
286345}
287346
288347bool DxilAnnotateWithVirtualRegister::IsAllocaRegisterWrite (
289348 llvm::Value *V, llvm::AllocaInst **pAI, llvm::Value **pIdx) {
290- llvm::IRBuilder<> B (m_DM->GetCtx ());
291349
292350 *pAI = nullptr ;
293351 *pIdx = nullptr ;
@@ -366,7 +424,8 @@ bool DxilAnnotateWithVirtualRegister::IsAllocaRegisterWrite(
366424
367425 auto offset = GetStructOffset (pGEP, GEPOperandIndex, pStructType);
368426
369- llvm::Value *IndexValue = B.getInt32 (offset + precedingMemberCount);
427+ llvm::Value *IndexValue = AddConstIntValues (
428+ offset, m_DM->GetOP ()->GetU32Const (precedingMemberCount));
370429
371430 if (IndexValue != nullptr ) {
372431 *pAI = Alloca;
@@ -383,7 +442,7 @@ bool DxilAnnotateWithVirtualRegister::IsAllocaRegisterWrite(
383442 }
384443
385444 *pAI = pAlloca;
386- *pIdx = B. getInt32 (0 );
445+ *pIdx = m_DM-> GetOP ()-> GetU32Const (0 );
387446 return true ;
388447 }
389448
@@ -463,12 +522,13 @@ void DxilAnnotateWithVirtualRegister::AssignNewDxilRegister(
463522
464523void DxilAnnotateWithVirtualRegister::AssignNewAllocaRegister (
465524 llvm::AllocaInst *pAlloca, std::uint32_t C) {
466- PixAllocaReg::AddMD (m_DM->GetCtx (), pAlloca, m_uVReg, C);
467- m_uVReg += C;
525+ if (!PixAllocaReg::FromInst (pAlloca, nullptr , nullptr )) {
526+ PixAllocaReg::AddMD (m_DM->GetCtx (), pAlloca, m_uVReg, C);
527+ m_uVReg += C;
528+ }
468529}
469530
470- void DxilAnnotateWithVirtualRegister::SplitVectorStores (hlsl::OP *HlslOP,
471- llvm::Instruction *pI) {
531+ void DxilAnnotateWithVirtualRegister::SplitVectorStores (llvm::Instruction *pI) {
472532 auto *pSt = llvm::dyn_cast<llvm::StoreInst>(pI);
473533 if (pSt == nullptr ) {
474534 return ;
0 commit comments