summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-ir-array-reg-to-mem.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-09-26 23:56:06 -0700
committerGitHub <noreply@github.com>2023-09-27 14:56:06 +0800
commitebe8ddefc48478307d5f206cd3e40c41d28a36e3 (patch)
tree8e13977979909a26394eea532d8b95cd5ad0f6d1 /source/slang/slang-ir-array-reg-to-mem.cpp
parentc5c8cfbb360d9a763f549df48636effde839eacd (diff)
Various SPIRV fixes. (#3231)
* Various SPIRV fixes. - Geometry shader support (WIP). - Fix texture get dimension and load. - Fold global GetElement(MakeArray/MakeVector) insts. - Call spvopt to inline all functions. - Translate OpImageSubscript. - Emit struct member names and global variable names. - Fix lowering of OpBitNot -> OpNot, instead of OpBitReverse. * Fix test. * Fix geometry shader. * Fix geometry shader emit. * Add atomic Image access test. * Fix tests. * don't fail if spirv-opt fails. * Update comments. * Fix test. * Cleanups. * indentation --------- Co-authored-by: Yong He <yhe@nvidia.com> Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com>
Diffstat (limited to 'source/slang/slang-ir-array-reg-to-mem.cpp')
-rw-r--r--source/slang/slang-ir-array-reg-to-mem.cpp87
1 files changed, 87 insertions, 0 deletions
diff --git a/source/slang/slang-ir-array-reg-to-mem.cpp b/source/slang/slang-ir-array-reg-to-mem.cpp
new file mode 100644
index 000000000..6f749f242
--- /dev/null
+++ b/source/slang/slang-ir-array-reg-to-mem.cpp
@@ -0,0 +1,87 @@
+#include "slang-ir-array-reg-to-mem.h"
+
+#include "slang-ir.h"
+#include "slang-ir-insts.h"
+#include "slang-ir-util.h"
+
+namespace Slang
+{
+ bool eliminateArrayTypeParameters(IRFunc* func)
+ {
+ IRBuilder builder(func);
+ bool changed = false;
+ List<UInt> arrayParamIds;
+ UInt idx = 0;
+ List<IRParam*> paramWorkList;
+ for (auto param : func->getParams())
+ {
+ if (auto arrayType = as<IRArrayTypeBase>(param->getFullType()))
+ {
+ paramWorkList.add(param);
+ arrayParamIds.add(idx);
+ }
+ idx++;
+ }
+ for (auto param : paramWorkList)
+ {
+ // We have an array type parameter, so we need to replace it with a pointer to the array
+ // type.
+ //
+ // We will also need to insert a `load` instruction at the start of the function body
+ // to load the actual pointer value from the parameter.
+ //
+ if (auto arrayType = as<IRArrayTypeBase>(param->getFullType()))
+ {
+ changed = true;
+ builder.setInsertBefore(param);
+ auto ptrArrayType = builder.getPtrType(arrayType);
+ auto newParam = builder.emitParam(ptrArrayType);
+ setInsertAfterOrdinaryInst(&builder, param);
+ auto regVal = builder.emitLoad(newParam);
+ param->replaceUsesWith(regVal);
+ param->removeAndDeallocate();
+ }
+ }
+ if (changed)
+ {
+ // The function is modified, we need to also update its type.
+ List<IRType*> paramTypes;
+ for (auto param : func->getParams())
+ {
+ paramTypes.add(param->getFullType());
+ }
+ auto newFuncType = builder.getFuncType((UInt)paramTypes.getCount(), paramTypes.getBuffer(), func->getResultType());
+ func->setFullType(newFuncType);
+
+ // Update all the call sites to pass the arrays by pointer.
+ traverseUses(func, [&](IRUse* use)
+ {
+ if (const auto call = as<IRCall>(use->getUser()))
+ {
+ builder.setInsertBefore(call);
+ for (auto paramId : arrayParamIds)
+ {
+ auto arg = call->getArg(paramId);
+ auto var = builder.emitVar(as<IRPtrTypeBase>(paramTypes[paramId])->getValueType());
+ builder.emitStore(var, arg);
+ call->setArg(paramId, var);
+ }
+ }
+ });
+ }
+ return changed;
+ }
+
+ bool eliminateArrayTypeSSARegisters(IRModule* module)
+ {
+ bool changed = false;
+ for (auto inst : module->getGlobalInsts())
+ {
+ if (auto func = as<IRFunc>(inst))
+ {
+ changed |= eliminateArrayTypeParameters(func);
+ }
+ }
+ return changed;
+ }
+}