diff options
| author | Yong He <yonghe@outlook.com> | 2022-08-10 15:37:19 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-10 15:37:19 -0700 |
| commit | a083a37ee58dc48d92cf2b844466a295eb3e643e (patch) | |
| tree | 69028f3d9f92fa7e2085c76bc234e1949ef645c5 /source/slang/slang-ir-cleanup-void.cpp | |
| parent | 88f04c29244af23c1cdd472d8d1ae3e5a650494e (diff) | |
Add `none` literal that is convertible to `Optional`. (#2356)
* Add `none` literal that is convertible to `Optional`.
* Fix cpu code gen.
* Include vk and cpu test for is-as operator test.
* Inline comparison operators.
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-ir-cleanup-void.cpp')
| -rw-r--r-- | source/slang/slang-ir-cleanup-void.cpp | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/source/slang/slang-ir-cleanup-void.cpp b/source/slang/slang-ir-cleanup-void.cpp new file mode 100644 index 000000000..ac520c1d5 --- /dev/null +++ b/source/slang/slang-ir-cleanup-void.cpp @@ -0,0 +1,159 @@ +// slang-ir-cleanup-void.cpp + +#include "slang-ir-cleanup-void.h" +#include "slang-ir.h" +#include "slang-ir-insts.h" + +namespace Slang +{ + struct CleanUpVoidContext + { + IRModule* module; + + SharedIRBuilder sharedBuilderStorage; + + List<IRInst*> workList; + HashSet<IRInst*> workListSet; + + void addToWorkList( + IRInst* inst) + { + for (auto ii = inst->getParent(); ii; ii = ii->getParent()) + { + if (as<IRGeneric>(ii)) + return; + } + + if (workListSet.Contains(inst)) + return; + + workList.add(inst); + workListSet.Add(inst); + } + + void processInst(IRInst* inst) + { + switch (inst->getOp()) + { + case kIROp_Call: + { + // Remove void argument. + auto call = as<IRCall>(inst); + List<IRInst*> newArgs; + for (UInt i = 0; i < call->getArgCount(); i++) + { + auto arg = call->getArg(i); + if (arg->getDataType() && arg->getDataType()->getOp() == kIROp_VoidType) + { + continue; + } + newArgs.add(arg); + } + if (newArgs.getCount() != (Index)call->getArgCount()) + { + IRBuilder builder(&sharedBuilderStorage); + builder.setInsertBefore(call); + auto newCall = builder.emitCallInst(call->getFullType(), call->getCallee(), newArgs); + call->replaceUsesWith(newCall); + call->removeAndDeallocate(); + inst = newCall; + } + } + break; + case kIROp_Func: + { + // Remove void parameter. + List<IRParam*> paramsToRemove; + auto func = as<IRFunc>(inst); + for (auto param : func->getParams()) + { + if (param->getDataType()->getOp() == kIROp_VoidType) + { + paramsToRemove.add(param); + } + } + IRBuilder builder(&sharedBuilderStorage); + builder.setInsertBefore(func); + for (auto param : paramsToRemove) + { + auto voidVal = builder.getVoidValue(); + param->replaceUsesWith(voidVal); + param->removeAndDeallocate(); + } + } + break; + case kIROp_FuncType: + { + auto funcType = as<IRFuncType>(inst); + List<IRInst*> newOperands; + for (UInt i = 1; i < funcType->getOperandCount(); i++) + { + auto operand = funcType->getOperand(i); + if (operand->getOp() == kIROp_VoidType) + { + continue; + } + newOperands.add(operand); + } + if (newOperands.getCount() != (Index)funcType->getParamCount()) + { + IRBuilder builder(&sharedBuilderStorage); + builder.setInsertBefore(funcType); + auto newFuncType = builder.getFuncType(newOperands.getCount(), (IRType**)newOperands.getBuffer(), funcType->getResultType()); + if (newFuncType != funcType) + { + funcType->replaceUsesWith(newFuncType); + funcType->removeAndDeallocate(); + } + inst = newFuncType; + } + } + break; + case kIROp_StructType: + { + // TODO: cleanup void fields. + } + break; + default: + break; + } + + // TODO: If inst has void type, all uses of it should be replaced with void val. + // We should do this only for a subset of opcodes known to be safe. + + } + + void processModule() + { + SharedIRBuilder* sharedBuilder = &sharedBuilderStorage; + sharedBuilder->init(module); + + // Deduplicate equivalent types. + sharedBuilder->deduplicateAndRebuildGlobalNumberingMap(); + + addToWorkList(module->getModuleInst()); + + while (workList.getCount() != 0) + { + IRInst* inst = workList.getLast(); + + workList.removeLast(); + workListSet.Remove(inst); + + processInst(inst); + + for (auto child = inst->getLastChild(); child; child = child->getPrevInst()) + { + addToWorkList(child); + } + } + } + }; + + void cleanUpVoidType(IRModule* module) + { + CleanUpVoidContext context; + context.module = module; + context.processModule(); + } +} |
