Skip to content

Commit

Permalink
PIX: Cherry pick (split vector writes, and SAT pass returns modificat…
Browse files Browse the repository at this point in the history
…ion status) (#7027)

Original PRs:
#6990
(cherry picked from commit
a03a77f)

#7010
(cherry picked from commit
848b7c4)
  • Loading branch information
jeffnn authored Dec 5, 2024
1 parent 8df0a9d commit 78e1dd1
Show file tree
Hide file tree
Showing 4 changed files with 335 additions and 17 deletions.
82 changes: 73 additions & 9 deletions lib/DxilPIXPasses/DxilAnnotateWithVirtualRegister.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class DxilAnnotateWithVirtualRegister : public llvm::ModulePass {
private:
void AnnotateValues(llvm::Instruction *pI);
void AnnotateStore(llvm::Instruction *pI);
void SplitVectorStores(hlsl::OP *HlslOP, llvm::Instruction *pI);
bool IsAllocaRegisterWrite(llvm::Value *V, llvm::AllocaInst **pAI,
llvm::Value **pIdx);
void AnnotateAlloca(llvm::AllocaInst *pAlloca);
Expand Down Expand Up @@ -133,6 +134,15 @@ bool DxilAnnotateWithVirtualRegister::runOnModule(llvm::Module &M) {
auto instrumentableFunctions =
PIXPassHelpers::GetAllInstrumentableFunctions(*m_DM);

for (auto *F : instrumentableFunctions) {
for (auto &block : F->getBasicBlockList()) {
for (auto it = block.begin(); it != block.end();) {
llvm::Instruction *I = &*(it++);
SplitVectorStores(m_DM->GetOP(), I);
}
}
}

for (auto *F : instrumentableFunctions) {
for (auto &block : F->getBasicBlockList()) {
for (llvm::Instruction &I : block.getInstList()) {
Expand Down Expand Up @@ -297,15 +307,37 @@ bool DxilAnnotateWithVirtualRegister::IsAllocaRegisterWrite(
return false;
}
// And of course the member we're after might not be at the beginning of
// the struct:
auto *pStructType = llvm::dyn_cast<llvm::StructType>(
pPointerGEP->getPointerOperandType()->getPointerElementType());
auto *pStructMember =
llvm::dyn_cast<llvm::ConstantInt>(pPointerGEP->getOperand(2));
uint64_t memberIndex = pStructMember->getLimitedValue();
for (uint64_t i = 0; i < memberIndex; ++i) {
precedingMemberCount +=
CountStructMembers(pStructType->getStructElementType(i));
// any containing struct:
if (auto *pStructType = llvm::dyn_cast<llvm::StructType>(
pPointerGEP->getPointerOperandType()
->getPointerElementType())) {
auto *pStructMember =
llvm::dyn_cast<llvm::ConstantInt>(pPointerGEP->getOperand(2));
uint64_t memberIndex = pStructMember->getLimitedValue();
for (uint64_t i = 0; i < memberIndex; ++i) {
precedingMemberCount +=
CountStructMembers(pStructType->getStructElementType(i));
}
}

// And the source pointer may be a vector (floatn) type,
// and if so, that's another offset to consider.
llvm::Type *DestType = pGEP->getPointerOperand()->getType();
// We expect this to be a pointer type (it's a GEP after all):
if (DestType->isPointerTy()) {
llvm::Type *PointedType = DestType->getPointerElementType();
// Being careful to check num operands too in order to avoid false
// positives:
if (PointedType->isVectorTy() && pGEP->getNumOperands() == 3) {
// Fetch the second deref (in operand 2).
// (the first derefs the pointer to the "floatn",
// and the second denotes the index into the floatn.)
llvm::Value *vectorIndex = pGEP->getOperand(2);
if (auto *constIntIIndex =
llvm::cast<llvm::ConstantInt>(vectorIndex)) {
precedingMemberCount += constIntIIndex->getLimitedValue();
}
}
}
} else {
return false;
Expand Down Expand Up @@ -365,6 +397,8 @@ void DxilAnnotateWithVirtualRegister::AnnotateAlloca(
AssignNewAllocaRegister(pAlloca, 1);
} else if (auto *AT = llvm::dyn_cast<llvm::ArrayType>(pAllocaTy)) {
AssignNewAllocaRegister(pAlloca, AT->getNumElements());
} else if (auto *VT = llvm::dyn_cast<llvm::VectorType>(pAllocaTy)) {
AssignNewAllocaRegister(pAlloca, VT->getNumElements());
} else if (auto *ST = llvm::dyn_cast<llvm::StructType>(pAllocaTy)) {
AssignNewAllocaRegister(pAlloca, CountStructMembers(ST));
} else {
Expand Down Expand Up @@ -433,6 +467,36 @@ void DxilAnnotateWithVirtualRegister::AssignNewAllocaRegister(
m_uVReg += C;
}

void DxilAnnotateWithVirtualRegister::SplitVectorStores(hlsl::OP *HlslOP,
llvm::Instruction *pI) {
auto *pSt = llvm::dyn_cast<llvm::StoreInst>(pI);
if (pSt == nullptr) {
return;
}

llvm::AllocaInst *Alloca;
llvm::Value *Index;
if (!IsAllocaRegisterWrite(pSt->getPointerOperand(), &Alloca, &Index)) {
return;
}

llvm::Type *SourceType = pSt->getValueOperand()->getType();
if (SourceType->isVectorTy()) {
if (auto *constIntIIndex = llvm::cast<llvm::ConstantInt>(Index)) {
// break vector alloca stores up into individual stores
llvm::IRBuilder<> B(pSt);
for (uint64_t el = 0; el < SourceType->getVectorNumElements(); ++el) {
llvm::Value *destPointer = B.CreateGEP(pSt->getPointerOperand(),
{B.getInt32(0), B.getInt32(el)});
llvm::Value *source =
B.CreateExtractElement(pSt->getValueOperand(), el);
B.CreateStore(source, destPointer);
}
pI->eraseFromParent();
}
}
}

} // namespace

using namespace llvm;
Expand Down
3 changes: 3 additions & 0 deletions lib/DxilPIXPasses/DxilShaderAccessTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,9 @@ bool DxilShaderAccessTracking::runOnModule(Module &M) {
// Done with these guys:
m_GEPOperandAsInstructionDestroyers.clear();

if (OSOverride != nullptr && !Modified) {
*OSOverride << "\nNotModified\n";
}
return Modified;
}
char DxilShaderAccessTracking::ID = 0;
Expand Down
Loading

0 comments on commit 78e1dd1

Please sign in to comment.