Skip to content

Commit 78e1dd1

Browse files
authored
PIX: Cherry pick (split vector writes, and SAT pass returns modification status) (#7027)
Original PRs: #6990 (cherry picked from commit a03a77f) #7010 (cherry picked from commit 848b7c4)
1 parent 8df0a9d commit 78e1dd1

File tree

4 files changed

+335
-17
lines changed

4 files changed

+335
-17
lines changed

lib/DxilPIXPasses/DxilAnnotateWithVirtualRegister.cpp

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class DxilAnnotateWithVirtualRegister : public llvm::ModulePass {
7777
private:
7878
void AnnotateValues(llvm::Instruction *pI);
7979
void AnnotateStore(llvm::Instruction *pI);
80+
void SplitVectorStores(hlsl::OP *HlslOP, llvm::Instruction *pI);
8081
bool IsAllocaRegisterWrite(llvm::Value *V, llvm::AllocaInst **pAI,
8182
llvm::Value **pIdx);
8283
void AnnotateAlloca(llvm::AllocaInst *pAlloca);
@@ -133,6 +134,15 @@ bool DxilAnnotateWithVirtualRegister::runOnModule(llvm::Module &M) {
133134
auto instrumentableFunctions =
134135
PIXPassHelpers::GetAllInstrumentableFunctions(*m_DM);
135136

137+
for (auto *F : instrumentableFunctions) {
138+
for (auto &block : F->getBasicBlockList()) {
139+
for (auto it = block.begin(); it != block.end();) {
140+
llvm::Instruction *I = &*(it++);
141+
SplitVectorStores(m_DM->GetOP(), I);
142+
}
143+
}
144+
}
145+
136146
for (auto *F : instrumentableFunctions) {
137147
for (auto &block : F->getBasicBlockList()) {
138148
for (llvm::Instruction &I : block.getInstList()) {
@@ -297,15 +307,37 @@ bool DxilAnnotateWithVirtualRegister::IsAllocaRegisterWrite(
297307
return false;
298308
}
299309
// And of course the member we're after might not be at the beginning of
300-
// the struct:
301-
auto *pStructType = llvm::dyn_cast<llvm::StructType>(
302-
pPointerGEP->getPointerOperandType()->getPointerElementType());
303-
auto *pStructMember =
304-
llvm::dyn_cast<llvm::ConstantInt>(pPointerGEP->getOperand(2));
305-
uint64_t memberIndex = pStructMember->getLimitedValue();
306-
for (uint64_t i = 0; i < memberIndex; ++i) {
307-
precedingMemberCount +=
308-
CountStructMembers(pStructType->getStructElementType(i));
310+
// any containing struct:
311+
if (auto *pStructType = llvm::dyn_cast<llvm::StructType>(
312+
pPointerGEP->getPointerOperandType()
313+
->getPointerElementType())) {
314+
auto *pStructMember =
315+
llvm::dyn_cast<llvm::ConstantInt>(pPointerGEP->getOperand(2));
316+
uint64_t memberIndex = pStructMember->getLimitedValue();
317+
for (uint64_t i = 0; i < memberIndex; ++i) {
318+
precedingMemberCount +=
319+
CountStructMembers(pStructType->getStructElementType(i));
320+
}
321+
}
322+
323+
// And the source pointer may be a vector (floatn) type,
324+
// and if so, that's another offset to consider.
325+
llvm::Type *DestType = pGEP->getPointerOperand()->getType();
326+
// We expect this to be a pointer type (it's a GEP after all):
327+
if (DestType->isPointerTy()) {
328+
llvm::Type *PointedType = DestType->getPointerElementType();
329+
// Being careful to check num operands too in order to avoid false
330+
// positives:
331+
if (PointedType->isVectorTy() && pGEP->getNumOperands() == 3) {
332+
// Fetch the second deref (in operand 2).
333+
// (the first derefs the pointer to the "floatn",
334+
// and the second denotes the index into the floatn.)
335+
llvm::Value *vectorIndex = pGEP->getOperand(2);
336+
if (auto *constIntIIndex =
337+
llvm::cast<llvm::ConstantInt>(vectorIndex)) {
338+
precedingMemberCount += constIntIIndex->getLimitedValue();
339+
}
340+
}
309341
}
310342
} else {
311343
return false;
@@ -365,6 +397,8 @@ void DxilAnnotateWithVirtualRegister::AnnotateAlloca(
365397
AssignNewAllocaRegister(pAlloca, 1);
366398
} else if (auto *AT = llvm::dyn_cast<llvm::ArrayType>(pAllocaTy)) {
367399
AssignNewAllocaRegister(pAlloca, AT->getNumElements());
400+
} else if (auto *VT = llvm::dyn_cast<llvm::VectorType>(pAllocaTy)) {
401+
AssignNewAllocaRegister(pAlloca, VT->getNumElements());
368402
} else if (auto *ST = llvm::dyn_cast<llvm::StructType>(pAllocaTy)) {
369403
AssignNewAllocaRegister(pAlloca, CountStructMembers(ST));
370404
} else {
@@ -433,6 +467,36 @@ void DxilAnnotateWithVirtualRegister::AssignNewAllocaRegister(
433467
m_uVReg += C;
434468
}
435469

470+
void DxilAnnotateWithVirtualRegister::SplitVectorStores(hlsl::OP *HlslOP,
471+
llvm::Instruction *pI) {
472+
auto *pSt = llvm::dyn_cast<llvm::StoreInst>(pI);
473+
if (pSt == nullptr) {
474+
return;
475+
}
476+
477+
llvm::AllocaInst *Alloca;
478+
llvm::Value *Index;
479+
if (!IsAllocaRegisterWrite(pSt->getPointerOperand(), &Alloca, &Index)) {
480+
return;
481+
}
482+
483+
llvm::Type *SourceType = pSt->getValueOperand()->getType();
484+
if (SourceType->isVectorTy()) {
485+
if (auto *constIntIIndex = llvm::cast<llvm::ConstantInt>(Index)) {
486+
// break vector alloca stores up into individual stores
487+
llvm::IRBuilder<> B(pSt);
488+
for (uint64_t el = 0; el < SourceType->getVectorNumElements(); ++el) {
489+
llvm::Value *destPointer = B.CreateGEP(pSt->getPointerOperand(),
490+
{B.getInt32(0), B.getInt32(el)});
491+
llvm::Value *source =
492+
B.CreateExtractElement(pSt->getValueOperand(), el);
493+
B.CreateStore(source, destPointer);
494+
}
495+
pI->eraseFromParent();
496+
}
497+
}
498+
}
499+
436500
} // namespace
437501

438502
using namespace llvm;

lib/DxilPIXPasses/DxilShaderAccessTracking.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,9 @@ bool DxilShaderAccessTracking::runOnModule(Module &M) {
10521052
// Done with these guys:
10531053
m_GEPOperandAsInstructionDestroyers.clear();
10541054

1055+
if (OSOverride != nullptr && !Modified) {
1056+
*OSOverride << "\nNotModified\n";
1057+
}
10551058
return Modified;
10561059
}
10571060
char DxilShaderAccessTracking::ID = 0;

0 commit comments

Comments
 (0)