Refactoring DxilEmitMetadata pass.
This commit is contained in:
Родитель
7878c0168e
Коммит
46e47f01e5
|
@ -46,6 +46,7 @@ ModulePass *createDxilFinalizeModulePass();
|
|||
ModulePass *createDxilEmitMetadataPass();
|
||||
FunctionPass *createDxilExpandTrigIntrinsicsPass();
|
||||
ModulePass *createDxilLoadMetadataPass();
|
||||
ModulePass *createDxilDeadFunctionEliminationPass();
|
||||
ModulePass *createDxilPrecisePropagatePass();
|
||||
FunctionPass *createDxilPreserveAllOutputsPass();
|
||||
FunctionPass *createDxilLegalizeResourceUsePass();
|
||||
|
@ -68,6 +69,7 @@ void initializeDxilFinalizeModulePass(llvm::PassRegistry&);
|
|||
void initializeDxilEmitMetadataPass(llvm::PassRegistry&);
|
||||
void initializeDxilExpandTrigIntrinsicsPass(llvm::PassRegistry&);
|
||||
void initializeDxilLoadMetadataPass(llvm::PassRegistry&);
|
||||
void initializeDxilDeadFunctionEliminationPass(llvm::PassRegistry&);
|
||||
void initializeDxilPrecisePropagatePassPass(llvm::PassRegistry&);
|
||||
void initializeDxilPreserveAllOutputsPass(llvm::PassRegistry&);
|
||||
void initializeDxilLegalizeResourceUsePassPass(llvm::PassRegistry&);
|
||||
|
|
|
@ -84,6 +84,7 @@ HRESULT SetupRegistryPassForHLSL() {
|
|||
initializeDeadInstEliminationPass(Registry);
|
||||
initializeDxilAddPixelHitInstrumentationPass(Registry);
|
||||
initializeDxilCondenseResourcesPass(Registry);
|
||||
initializeDxilDeadFunctionEliminationPass(Registry);
|
||||
initializeDxilEliminateOutputDynamicIndexingPass(Registry);
|
||||
initializeDxilEmitMetadataPass(Registry);
|
||||
initializeDxilExpandTrigIntrinsicsPass(Registry);
|
||||
|
|
|
@ -618,6 +618,7 @@ void DxilLinkJob::RunPreparePass(Module &M) {
|
|||
legacy::PassManager PM;
|
||||
|
||||
PM.add(createAlwaysInlinerPass(/*InsertLifeTime*/ false));
|
||||
PM.add(createDxilDeadFunctionEliminationPass());
|
||||
// mem2reg.
|
||||
PM.add(createPromoteMemoryToRegisterPass());
|
||||
// Remove unused functions.
|
||||
|
@ -630,6 +631,7 @@ void DxilLinkJob::RunPreparePass(Module &M) {
|
|||
PM.add(createDxilCondenseResourcesPass());
|
||||
PM.add(createDxilFinalizeModulePass());
|
||||
PM.add(createComputeViewIdStatePass());
|
||||
PM.add(createDxilDeadFunctionEliminationPass());
|
||||
PM.add(createDxilEmitMetadataPass());
|
||||
|
||||
PM.run(M);
|
||||
|
|
|
@ -92,6 +92,53 @@ ModulePass *llvm::createDxilLoadMetadataPass() {
|
|||
|
||||
INITIALIZE_PASS(DxilLoadMetadata, "hlsl-dxilload", "HLSL load DxilModule from metadata", false, false)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace {
|
||||
class DxilDeadFunctionElimination : public ModulePass {
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
explicit DxilDeadFunctionElimination () : ModulePass(ID) {}
|
||||
|
||||
const char *getPassName() const override { return "Remove all unused function except entry from DxilModule"; }
|
||||
|
||||
bool runOnModule(Module &M) override {
|
||||
if (M.HasDxilModule()) {
|
||||
DxilModule &DM = M.GetDxilModule();
|
||||
|
||||
bool IsLib = DM.GetShaderModel()->IsLib();
|
||||
// Remove unused functions except entry and patch constant func.
|
||||
// For library profile, only remove unused external functions.
|
||||
Function *EntryFunc = DM.GetEntryFunction();
|
||||
Function *PatchConstantFunc = DM.GetPatchConstantFunction();
|
||||
|
||||
std::vector<Function *> deadList;
|
||||
for (iplist<Function>::iterator F : M.getFunctionList()) {
|
||||
if (&(*F) == EntryFunc || &(*F) == PatchConstantFunc)
|
||||
continue;
|
||||
if (F->isDeclaration() || !IsLib) {
|
||||
if (F->user_empty())
|
||||
deadList.emplace_back(F);
|
||||
}
|
||||
}
|
||||
bool bUpdated = deadList.size();
|
||||
for (Function *F : deadList)
|
||||
F->eraseFromParent();
|
||||
return bUpdated;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
char DxilDeadFunctionElimination::ID = 0;
|
||||
|
||||
ModulePass *llvm::createDxilDeadFunctionEliminationPass() {
|
||||
return new DxilDeadFunctionElimination();
|
||||
}
|
||||
|
||||
INITIALIZE_PASS(DxilDeadFunctionElimination, "dxil-dfe", "Remove all unused function except entry from DxilModule", false, false)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -205,11 +252,9 @@ public:
|
|||
bool runOnModule(Module &M) override {
|
||||
if (M.HasDxilModule()) {
|
||||
DxilModule &DM = M.GetDxilModule();
|
||||
// Remove store undef output.
|
||||
hlsl::OP *hlslOP = M.GetDxilModule().GetOP();
|
||||
|
||||
bool IsLib = DM.GetShaderModel()->IsLib();
|
||||
// Skip patch for lib.
|
||||
// Skip validation patch for lib.
|
||||
if (!IsLib) {
|
||||
unsigned ValMajor = 0;
|
||||
unsigned ValMinor = 0;
|
||||
|
@ -219,59 +264,32 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
for (iplist<Function>::iterator F : M.getFunctionList()) {
|
||||
if (!hlslOP->IsDxilOpFunc(F))
|
||||
continue;
|
||||
// Remove store undef output.
|
||||
hlsl::OP *hlslOP = M.GetDxilModule().GetOP();
|
||||
RemoveStoreUndefOutput(M, hlslOP);
|
||||
|
||||
// Check store output.
|
||||
FunctionType *FT = F->getFunctionType();
|
||||
// Num params not match.
|
||||
if (FT->getNumParams() !=
|
||||
(DXIL::OperandIndex::kStoreOutputValOpIdx + 1))
|
||||
continue;
|
||||
RemoveUnusedStaticGlobal(M);
|
||||
|
||||
Type *overloadTy =
|
||||
FT->getParamType(DXIL::OperandIndex::kStoreOutputValOpIdx);
|
||||
// overload illegal.
|
||||
if (!hlslOP->IsOverloadLegal(DXIL::OpCode::StoreOutput, overloadTy))
|
||||
continue;
|
||||
Function *storeOutput =
|
||||
hlslOP->GetOpFunc(DXIL::OpCode::StoreOutput, overloadTy);
|
||||
// Not store output.
|
||||
if (storeOutput != F)
|
||||
continue;
|
||||
// Clear inbound for GEP which has none-const index.
|
||||
LegalizeShareMemoryGEPInbound(M);
|
||||
|
||||
for (auto it = F->user_begin(); it != F->user_end();) {
|
||||
CallInst *CI = dyn_cast<CallInst>(*(it++));
|
||||
if (!CI)
|
||||
continue;
|
||||
// Strip parameters of entry function.
|
||||
StripEntryParameters(M, DM, IsLib);
|
||||
|
||||
Value *V =
|
||||
CI->getArgOperand(DXIL::OperandIndex::kStoreOutputValOpIdx);
|
||||
// Remove the store of undef.
|
||||
if (isa<UndefValue>(V))
|
||||
CI->eraseFromParent();
|
||||
}
|
||||
}
|
||||
// Remove unused external functions.
|
||||
// For none library profile, remove unused functions except entry and
|
||||
// patchconstant function.
|
||||
Function *EntryFunc = DM.GetEntryFunction();
|
||||
Function *PatchConstantFunc = DM.GetPatchConstantFunction();
|
||||
|
||||
std::vector<Function *> deadList;
|
||||
for (iplist<Function>::iterator F : M.getFunctionList()) {
|
||||
if (&(*F) == EntryFunc || &(*F) == PatchConstantFunc)
|
||||
continue;
|
||||
if (F->isDeclaration() || !IsLib) {
|
||||
if (F->user_empty())
|
||||
deadList.emplace_back(F);
|
||||
// Skip shader flag for library.
|
||||
if (!IsLib) {
|
||||
DM.CollectShaderFlags(); // Update flags to reflect any changes.
|
||||
// Update Validator Version
|
||||
DM.UpgradeToMinValidatorVersion();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
for (Function *F : deadList)
|
||||
F->eraseFromParent();
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
void RemoveUnusedStaticGlobal(Module &M) {
|
||||
// Remove unused internal global.
|
||||
std::vector<GlobalVariable *> staticGVs;
|
||||
for (GlobalVariable &GV : M.globals()) {
|
||||
|
@ -304,7 +322,31 @@ public:
|
|||
GV->eraseFromParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveStoreUndefOutput(Module &M, hlsl::OP *hlslOP) {
|
||||
for (iplist<Function>::iterator F : M.getFunctionList()) {
|
||||
if (!hlslOP->IsDxilOpFunc(F))
|
||||
continue;
|
||||
DXIL::OpCodeClass opClass;
|
||||
DXASSERT(hlslOP->GetOpCodeClass(F, opClass), "else not a dxil op func");
|
||||
if (opClass != DXIL::OpCodeClass::StoreOutput)
|
||||
continue;
|
||||
|
||||
for (auto it = F->user_begin(); it != F->user_end();) {
|
||||
CallInst *CI = dyn_cast<CallInst>(*(it++));
|
||||
if (!CI)
|
||||
continue;
|
||||
|
||||
Value *V = CI->getArgOperand(DXIL::OperandIndex::kStoreOutputValOpIdx);
|
||||
// Remove the store of undef.
|
||||
if (isa<UndefValue>(V))
|
||||
CI->eraseFromParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LegalizeShareMemoryGEPInbound(Module &M) {
|
||||
const DataLayout &DL = M.getDataLayout();
|
||||
// Clear inbound for GEP which has none-const index.
|
||||
for (GlobalVariable &GV : M.globals()) {
|
||||
|
@ -312,7 +354,9 @@ public:
|
|||
CheckInBoundForTGSM(GV, DL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StripEntryParameters(Module &M, DxilModule &DM, bool IsLib) {
|
||||
DenseMap<const Function *, DISubprogram *> FunctionDIs =
|
||||
makeSubprogramMap(M);
|
||||
// Strip parameters of entry function.
|
||||
|
@ -349,18 +393,6 @@ public:
|
|||
StripFunctionParameter(entry, DM, FunctionDIs);
|
||||
}
|
||||
}
|
||||
|
||||
// Skip shader flag for library.
|
||||
if (!IsLib) {
|
||||
DM.CollectShaderFlags(); // Update flags to reflect any changes.
|
||||
// Update Validator Version
|
||||
DM.UpgradeToMinValidatorVersion();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -210,6 +210,10 @@ static void addHLSLPasses(bool HLSLHighLevel, bool NoOpt, hlsl::HLSLExtensionsCo
|
|||
return;
|
||||
}
|
||||
|
||||
if (!NoOpt) {
|
||||
MPM.add(createDxilDeadFunctionEliminationPass());
|
||||
}
|
||||
|
||||
// Split struct and array of parameter.
|
||||
MPM.add(createSROA_Parameter_HLSL());
|
||||
|
||||
|
@ -295,6 +299,7 @@ void PassManagerBuilder::populateModulePassManager(
|
|||
MPM.add(createDxilLegalizeSampleOffsetPass()); // HLSL Change
|
||||
MPM.add(createDxilFinalizeModulePass()); // HLSL Change
|
||||
MPM.add(createComputeViewIdStatePass()); // HLSL Change
|
||||
MPM.add(createDxilDeadFunctionEliminationPass()); // HLSL Change
|
||||
MPM.add(createDxilEmitMetadataPass()); // HLSL Change
|
||||
}
|
||||
// HLSL Change Ends.
|
||||
|
@ -566,6 +571,7 @@ void PassManagerBuilder::populateModulePassManager(
|
|||
MPM.add(createDxilLegalizeSampleOffsetPass()); // HLSL Change
|
||||
MPM.add(createDxilFinalizeModulePass());
|
||||
MPM.add(createComputeViewIdStatePass()); // HLSL Change
|
||||
MPM.add(createDxilDeadFunctionEliminationPass()); // HLSL Change
|
||||
MPM.add(createDxilEmitMetadataPass());
|
||||
}
|
||||
// HLSL Change Ends.
|
||||
|
|
|
@ -1285,6 +1285,7 @@ class db_dxil(object):
|
|||
add_pass('hlsl-dxilfinalize', 'DxilFinalizeModule', 'HLSL DXIL Finalize Module', [])
|
||||
add_pass('hlsl-dxilemit', 'DxilEmitMetadata', 'HLSL DXIL Metadata Emit', [])
|
||||
add_pass('hlsl-dxilload', 'DxilLoadMetadata', 'HLSL DXIL Metadata Load', [])
|
||||
add_pass('dxil-dfe', 'DxilDeadFunctionElimination', 'Remove all unused function except entry from DxilModule', [])
|
||||
add_pass('hlsl-dxil-expand-trig', 'DxilExpandTrigIntrinsics', 'DXIL expand trig intrinsics', [])
|
||||
add_pass('hlsl-hca', 'HoistConstantArray', 'HLSL constant array hoisting', [])
|
||||
add_pass('hlsl-dxil-preserve-all-outputs', 'DxilPreserveAllOutputs', 'DXIL write to all outputs in signature', [])
|
||||
|
|
Загрузка…
Ссылка в новой задаче