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 5, 2024
1 parent d27d603 commit ad733b8
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 14 deletions.
34 changes: 23 additions & 11 deletions source/slang/slang-ir-legalize-global-values.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
namespace Slang
{

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

for (auto globalInst : module->getGlobalInsts())
{
Expand All @@ -17,20 +17,32 @@ void GlobalInstInliningContextGeneric::inlineGlobalValues(IRModule * module)
for (auto use = globalInst->firstUse; use; use = use->nextUse)
{
if (getParentFunc(use->getUser()) != nullptr)
globalInstUsesToInline.add(use);
{
globalInstUsesToInline.getOrAddValue(globalInst, List<IRUse*>()).add(use);
}
}
}
}

for (auto use : globalInstUsesToInline)
for (auto globalInstUses : globalInstUsesToInline)
{
auto user = use->getUser();
IRBuilder builder(user);
builder.setInsertBefore(getOutsideASM(user));
IRCloneEnv cloneEnv;
auto val = maybeInlineGlobalValue(builder, use->getUser(), use->get(), cloneEnv);
if (val != use->get())
builder.replaceOperand(use, val);
auto& inst = globalInstUses.first;
auto& uses = globalInstUses.second;
for (auto use : uses)
{
auto user = use->getUser();
IRBuilder builder(user);
builder.setInsertBefore(getOutsideASM(user));
IRCloneEnv cloneEnv;
auto val = maybeInlineGlobalValue(builder, use->getUser(), use->get(), cloneEnv);
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.
if (!inst->hasUses())
inst->removeAndDeallocate();
}
}

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 ad733b8

Please sign in to comment.