Repository: shader-slang/slang
File: source/slang/slang-ir-cleanup-void.cpp (C++)

Code before:
                    }
                    newArgs.add(arg);
                }
                if (newArgs.getCount() != (Index)inst->getOperandCount())
                {
                    IRBuilder builder(module);
                    builder.setInsertBefore(inst);
                    auto newCall = builder.emitIntrinsicInst(
                        inst->getFullType(),
                        inst->getOp(),
                        newArgs.getCount(),
                        newArgs.getBuffer());
                    inst->replaceUsesWith(newCall);
                    inst->removeAndDeallocate();
                    inst = newCall;
                }
            }
            break;
        case kIROp_Func:
            {
                // Remove void parameters.
                // To keep the ArgIndex operand of the IRDebugVars
                // corresponding to the function parameters correct, we build a
                // map to update the IRDebugVar argument indices later.
                List<IRParam*> paramsToRemove;
                List<Index> argIndexRemap; // Indexed by old ArgIndex, with value of new ArgIndex
                auto func = as<IRFunc>(inst);
                Index nextKeptArgIndex = 0;
                for (auto param : func->getParams())
                {
                    if (param->getDataType()->getOp() == kIROp_VoidType)
                    {
                        paramsToRemove.add(param);
                        argIndexRemap.add(-1); // We can remove the IRDebugVar
                    }
                    else
                    {
                        argIndexRemap.add(nextKeptArgIndex);
                        nextKeptArgIndex++;
                    }
                }
                IRBuilder builder(module);
                builder.setInsertBefore(func);
                for (auto param : paramsToRemove)
                {
                    auto voidVal = builder.getVoidValue();
                    param->replaceUsesWith(voidVal);
                    param->removeAndDeallocate();
                }

                if (paramsToRemove.getCount() != 0)

Review comment (performance):
I am wondering if we can call `reserve()` for the List instances, which often turns out to be a performance problem if we don't call it.

Code after:
                    }
                    newArgs.add(arg);
                }
                if (newArgs.getCount() != (Index)inst->getOperandCount())
                {
                    IRBuilder builder(module);
                    builder.setInsertBefore(inst);
                    auto newCall = builder.emitIntrinsicInst(
                        inst->getFullType(),
                        inst->getOp(),
                        newArgs.getCount(),
                        newArgs.getBuffer());
                    inst->replaceUsesWith(newCall);
                    inst->removeAndDeallocate();
                    inst = newCall;
                }
            }
            break;
        case kIROp_Func:
            {
                // Remove void parameters.
                // To keep the ArgIndex operand of the IRDebugVars
                // corresponding to the function parameters correct, we build a
                // map to update the IRDebugVar argument indices later.
                List<IRParam*> paramsToRemove;
                auto func = as<IRFunc>(inst);
                List<Index> argIndexRemap; // Indexed by old ArgIndex, with value of new ArgIndex
                argIndexRemap.reserve(func->getParamCount());
                Index nextKeptArgIndex = 0;
                for (auto param : func->getParams())
                {
                    bool needToRemove = (param->getDataType()->getOp() == kIROp_VoidType);
                    argIndexRemap.add(needToRemove ? -1 : nextKeptArgIndex);

                    if (needToRemove)
                    {
                        paramsToRemove.add(param);
                    }
                    else
                    {
                        nextKeptArgIndex++;
                    }
                }
                IRBuilder builder(module);
                builder.setInsertBefore(func);
                for (auto param : paramsToRemove)
                {
                    auto voidVal = builder.getVoidValue();
                    param->replaceUsesWith(voidVal);
                    param->removeAndDeallocate();
                }