Skip to content

Commit

Permalink
Remove globals if they're left unused after inlining
Browse files Browse the repository at this point in the history
This closes shader-slang#5607.
  • Loading branch information
aleino-nv committed Dec 10, 2024
1 parent 0699129 commit ff5ed69
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 4 deletions.
16 changes: 15 additions & 1 deletion source/slang/slang-ir-legalize-global-values.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
namespace Slang
{

void GlobalInstInliningContextGeneric::inlineGlobalValues(IRModule * module)
void GlobalInstInliningContextGeneric::inlineGlobalValuesAndRemoveIfUnused(IRModule* module)
{
List<IRUse*> globalInstUsesToInline;
List<IRInst*> globalInstsToConsiderDeleting;

for (auto globalInst : module->getGlobalInsts())
{
Expand All @@ -17,8 +18,11 @@ void GlobalInstInliningContextGeneric::inlineGlobalValues(IRModule * module)
for (auto use = globalInst->firstUse; use; use = use->nextUse)
{
if (getParentFunc(use->getUser()) != nullptr)
{
globalInstUsesToInline.add(use);
}
}
globalInstsToConsiderDeleting.add(globalInst);
}
}

Expand All @@ -32,6 +36,16 @@ void GlobalInstInliningContextGeneric::inlineGlobalValues(IRModule * module)
if (val != use->get())
builder.replaceOperand(use, val);
}

// Since certain globals that appear in the IR are considered illegal for all targets,
// e.g. calls to functions, we delete globals which no longer have uses after inlining.
for (auto& globalInst: globalInstsToConsiderDeleting)
{
// TODO: Explain why tests/spirv/global-compute.slang fails if we don't exclude
// kIROp_SPIRVAsm
if (!globalInst->hasUses() && globalInst->getOp() != kIROp_SPIRVAsm)
globalInst->removeAndDeallocate();
}
}

bool GlobalInstInliningContextGeneric::isLegalGlobalInst(IRInst* inst)
Expand Down
3 changes: 2 additions & 1 deletion source/slang/slang-ir-legalize-global-values.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ struct GlobalInstInliningContextGeneric
virtual IRInst* getOutsideASM(IRInst* beforeInst) =0;

// Inline global values that can't represented by the target to their use sites.
void inlineGlobalValues(IRModule * module);
// If this leaves any global unused, then remove it.
void inlineGlobalValuesAndRemoveIfUnused(IRModule * module);

// Opcodes that can exist in global scope, as long as the operands are.
bool isLegalGlobalInst(IRInst* inst);
Expand Down
2 changes: 1 addition & 1 deletion source/slang/slang-ir-spirv-legalize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2016,7 +2016,7 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
}
}

GlobalInstInliningContext().inlineGlobalValues(m_module);
GlobalInstInliningContext().inlineGlobalValuesAndRemoveIfUnused(m_module);

// Some legalization processing may change the function parameter types,
// so we need to update the function types to match that.
Expand Down
4 changes: 3 additions & 1 deletion source/slang/slang-ir-wgsl-legalize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1643,7 +1643,9 @@ void legalizeIRForWGSL(IRModule* module, DiagnosticSink* sink)
// Go through every instruction in the module and legalize them as needed.
context.processInst(module->getModuleInst());

GlobalInstInliningContext().inlineGlobalValues(module);
// Some global insts are illegal, e.g. function calls.
// We need to inline and remove those.
GlobalInstInliningContext().inlineGlobalValuesAndRemoveIfUnused(module);
}

} // namespace Slang

0 comments on commit ff5ed69

Please sign in to comment.