Keep debug info for handle created by local resource. (#61)
* Keep debug info for handle created by local resource. * Add IsResourceAlloc to share code.
This commit is contained in:
Родитель
3c7734c7da
Коммит
199aa5a0b5
|
@ -106,8 +106,46 @@ public:
|
|||
// Mark handle map.
|
||||
// If cannot find, will return false in run();
|
||||
if (Instruction *I = dyn_cast<Instruction>(V)) {
|
||||
if (handleMap.count(I))
|
||||
handleMap[NewInst] = handleMap[I];
|
||||
if (handleMap.count(I)) {
|
||||
Instruction *handle = cast<Instruction>(handleMap[I]);
|
||||
// Clone the handle to save debug info of LI.
|
||||
handle = handle->clone();
|
||||
Builder.Insert(handle);
|
||||
handleMap[NewInst] = handle;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Collect unused phi of resources and remove them.
|
||||
class ResourceRemover : public LoadAndStorePromoter {
|
||||
AllocaInst *AI;
|
||||
mutable std::unordered_set<PHINode *> unusedPhis;
|
||||
|
||||
public:
|
||||
ResourceRemover(ArrayRef<Instruction *> Insts, SSAUpdater &S)
|
||||
: LoadAndStorePromoter(Insts, S), AI(nullptr) {}
|
||||
|
||||
void run(AllocaInst *AI, const SmallVectorImpl<Instruction *> &Insts) {
|
||||
// Remember which alloca we're promoting (for isInstInList).
|
||||
this->AI = AI;
|
||||
LoadAndStorePromoter::run(Insts);
|
||||
for (PHINode *P : unusedPhis) {
|
||||
P->eraseFromParent();
|
||||
}
|
||||
}
|
||||
bool
|
||||
isInstInList(Instruction *I,
|
||||
const SmallVectorImpl<Instruction *> &Insts) const override {
|
||||
if (LoadInst *LI = dyn_cast<LoadInst>(I))
|
||||
return LI->getOperand(0) == AI;
|
||||
return cast<StoreInst>(I)->getPointerOperand() == AI;
|
||||
}
|
||||
|
||||
void replaceLoadWithValue(LoadInst *LI, Value *V) const override {
|
||||
if (PHINode *PHI = dyn_cast<PHINode>(V)) {
|
||||
if (PHI->user_empty())
|
||||
unusedPhis.insert(PHI);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -315,6 +353,16 @@ public:
|
|||
|
||||
GenerateDxilOperations(M, handleMap);
|
||||
|
||||
if (NotOptimized || m_HasDbgInfo) {
|
||||
// For module which not promote mem2reg.
|
||||
// Remove local resource alloca/load/store/phi.
|
||||
Module &M = *m_pHLModule->GetModule();
|
||||
for (Function &F : M.functions()) {
|
||||
if (!F.isDeclaration())
|
||||
RemoveLocalDxilResourceAllocas(&F);
|
||||
}
|
||||
}
|
||||
|
||||
// Translate precise on allocas into function call to keep the information after mem2reg.
|
||||
// The function calls will be removed after propagate precise attribute.
|
||||
TranslatePreciseAttribute();
|
||||
|
@ -351,6 +399,7 @@ private:
|
|||
bool HasClipPlanes();
|
||||
|
||||
void TranslateLocalDxilResourceUses(Function *F, std::unordered_map<Instruction *, Value *> &handleMap);
|
||||
void RemoveLocalDxilResourceAllocas(Function *F);
|
||||
void MapLocalDxilResourceHandles(
|
||||
std::unordered_map<Instruction *, Value *> &handleMap);
|
||||
void TranslateDxilResourceUses(
|
||||
|
@ -1778,24 +1827,27 @@ static void AddCreateHandleForPhiNode(std::unordered_map<Instruction *, Value *>
|
|||
}
|
||||
}
|
||||
|
||||
static bool IsResourceAlloc(AllocaInst *AI) {
|
||||
bool isResource = HLModule::IsHLSLObjectType(AI->getAllocatedType());
|
||||
|
||||
if (ArrayType *AT = dyn_cast<ArrayType>(AI->getAllocatedType())) {
|
||||
Type *EltTy = AT->getElementType();
|
||||
while (isa<ArrayType>(EltTy)) {
|
||||
EltTy = EltTy->getArrayElementType();
|
||||
}
|
||||
isResource = HLModule::IsHLSLObjectType(EltTy);
|
||||
// TODO: support local resource array.
|
||||
DXASSERT(!isResource, "local resource array");
|
||||
}
|
||||
return isResource;
|
||||
}
|
||||
|
||||
void DxilGenerationPass::TranslateLocalDxilResourceUses(Function *F, std::unordered_map<Instruction *, Value *> &handleMap) {
|
||||
BasicBlock &BB = F->getEntryBlock(); // Get the entry node for the function
|
||||
std::unordered_set<AllocaInst *> localResources;
|
||||
for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
|
||||
if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) { // Is it an alloca?
|
||||
|
||||
bool isResource = HLModule::IsHLSLObjectType(AI->getAllocatedType());
|
||||
|
||||
if (ArrayType *AT = dyn_cast<ArrayType>(AI->getAllocatedType())) {
|
||||
Type *EltTy = AT->getElementType();
|
||||
while (isa<ArrayType>(EltTy)) {
|
||||
EltTy = EltTy->getArrayElementType();
|
||||
}
|
||||
isResource = HLModule::IsHLSLObjectType(EltTy);
|
||||
// TODO: support local resource array.
|
||||
DXASSERT(!isResource, "local resource array");
|
||||
}
|
||||
if (isResource) {
|
||||
if (IsResourceAlloc(AI)) {
|
||||
localResources.insert(AI);
|
||||
}
|
||||
}
|
||||
|
@ -1820,6 +1872,30 @@ void DxilGenerationPass::TranslateLocalDxilResourceUses(Function *F, std::unorde
|
|||
}
|
||||
}
|
||||
|
||||
void DxilGenerationPass::RemoveLocalDxilResourceAllocas(Function *F) {
|
||||
BasicBlock &BB = F->getEntryBlock(); // Get the entry node for the function
|
||||
std::unordered_set<AllocaInst *> localResources;
|
||||
for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
|
||||
if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) { // Is it an alloca?
|
||||
if (IsResourceAlloc(AI)) {
|
||||
localResources.insert(AI);
|
||||
}
|
||||
}
|
||||
|
||||
SSAUpdater SSA;
|
||||
SmallVector<Instruction *, 4> Insts;
|
||||
|
||||
for (AllocaInst *AI : localResources) {
|
||||
// Build list of instructions to promote.
|
||||
for (User *U : AI->users())
|
||||
Insts.emplace_back(cast<Instruction>(U));
|
||||
|
||||
ResourceRemover(Insts, SSA).run(AI, Insts);
|
||||
|
||||
Insts.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void DxilGenerationPass::MapLocalDxilResourceHandles(
|
||||
std::unordered_map<Instruction *, Value *> &handleMap) {
|
||||
Module &M = *m_pHLModule->GetModule();
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
// RUN: %dxc -E main -T cs_6_0 %s
|
||||
// RUN: %dxc -E main -Zi -Od -T cs_6_0 %s | FileCheck %s
|
||||
|
||||
// Make sure createHandle has debug info.
|
||||
// CHECK: @dx.op.createHandle(i32 59, i8 1, i32 0, i32 0, i1 false), !dbg
|
||||
// CHECK: @dx.op.createHandle(i32 59, i8 1, i32 1, i32 1, i1 false), !dbg
|
||||
|
||||
RWBuffer<uint> uav1;
|
||||
RWBuffer<uint> uav2;
|
||||
|
|
|
@ -557,6 +557,7 @@ public:
|
|||
TEST_METHOD(CodeGenBindings1)
|
||||
TEST_METHOD(CodeGenBindings2)
|
||||
TEST_METHOD(CodeGenBindings3)
|
||||
TEST_METHOD(CodeGenResCopy)
|
||||
TEST_METHOD(CodeGenResourceInStruct)
|
||||
TEST_METHOD(CodeGenResourceInCB)
|
||||
TEST_METHOD(CodeGenResourceInCBV)
|
||||
|
@ -2732,6 +2733,10 @@ TEST_F(CompilerTest, CodeGenBindings3) {
|
|||
CodeGenTestCheck(L"..\\CodeGenHLSL\\bindings2.hlsl");
|
||||
}
|
||||
|
||||
TEST_F(CompilerTest, CodeGenResCopy) {
|
||||
CodeGenTestCheck(L"..\\CodeGenHLSL\\resCopy.hlsl");
|
||||
}
|
||||
|
||||
TEST_F(CompilerTest, CodeGenResourceInStruct) {
|
||||
CodeGenTestCheck(L"..\\CodeGenHLSL\\resource-in-struct.hlsl");
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче