summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-lower-reinterpret.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2021-09-09 11:39:04 -0700
committerGitHub <noreply@github.com>2021-09-09 11:39:04 -0700
commit28adf8917e53953dbfebd746410a427a55eed814 (patch)
treeb575bcdcc7860d64065e538d3fbf1d0466803aa3 /source/slang/slang-ir-lower-reinterpret.cpp
parentcc075b76ee25876135584d31ec650776fcb69166 (diff)
`reinterpret` and 16-bit value packing. (#1933)
* `reinterpret` and 16-bit value packing. * Update `half-texture` cross-compile test reference result. * Revert inadvertent reformatting of slang-ir-inst-defs.h Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-ir-lower-reinterpret.cpp')
-rw-r--r--source/slang/slang-ir-lower-reinterpret.cpp109
1 files changed, 109 insertions, 0 deletions
diff --git a/source/slang/slang-ir-lower-reinterpret.cpp b/source/slang/slang-ir-lower-reinterpret.cpp
new file mode 100644
index 000000000..a140bacad
--- /dev/null
+++ b/source/slang/slang-ir-lower-reinterpret.cpp
@@ -0,0 +1,109 @@
+#include "slang-ir-lower-reinterpret.h"
+#include "slang-ir.h"
+#include "slang-ir-insts.h"
+#include "slang-ir-layout.h"
+#include "slang-ir-any-value-marshalling.h"
+
+namespace Slang
+{
+
+struct ReinterpretLoweringContext
+{
+ TargetRequest* targetReq;
+ DiagnosticSink* sink;
+ IRModule* module;
+ SharedIRBuilder sharedBuilderStorage;
+ OrderedHashSet<IRInst*> workList;
+
+ void addToWorkList(IRInst* inst)
+ {
+ for (auto ii = inst->getParent(); ii; ii = ii->getParent())
+ {
+ if (as<IRGeneric>(ii))
+ return;
+ }
+
+ if (workList.Contains(inst))
+ return;
+
+ workList.Add(inst);
+ }
+
+ void processInst(IRInst* inst)
+ {
+ switch (inst->getOp())
+ {
+ case kIROp_Reinterpret:
+ processReinterpret(inst);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void processModule()
+ {
+ SharedIRBuilder* sharedBuilder = &sharedBuilderStorage;
+ sharedBuilder->module = module;
+ sharedBuilder->session = module->session;
+
+ // Deduplicate equivalent types.
+ sharedBuilder->deduplicateAndRebuildGlobalNumberingMap();
+
+ addToWorkList(module->getModuleInst());
+
+ while (workList.Count() != 0)
+ {
+ IRInst* inst = workList.getLast();
+
+ workList.removeLast();
+
+ processInst(inst);
+
+ for (auto child = inst->getLastChild(); child; child = child->getPrevInst())
+ {
+ addToWorkList(child);
+ }
+ }
+ }
+
+ void processReinterpret(IRInst* inst)
+ {
+ auto operand = inst->getOperand(0);
+ auto fromType = operand->getDataType();
+ auto toType = inst->getDataType();
+ SlangInt fromTypeSize = getAnyValueSize(fromType);
+ if (fromTypeSize < 0)
+ {
+ sink->diagnose(inst->sourceLoc, Slang::Diagnostics::typeCannotBePackedIntoAnyValue, fromType);
+ }
+ SlangInt toTypeSize = getAnyValueSize(toType);
+ if (toTypeSize < 0)
+ {
+ sink->diagnose(inst->sourceLoc, Slang::Diagnostics::typeCannotBePackedIntoAnyValue, toType);
+ }
+ SlangInt anyValueSize = Math::Max(fromTypeSize, toTypeSize);
+
+ IRBuilder builder;
+ builder.sharedBuilder = &sharedBuilderStorage;
+ builder.setInsertBefore(inst);
+ auto anyValueType = builder.getAnyValueType(builder.getIntValue(builder.getUIntType(), anyValueSize));
+ auto packInst = builder.emitPackAnyValue(
+ anyValueType,
+ operand);
+ auto unpackInst = builder.emitUnpackAnyValue(toType, packInst);
+ inst->replaceUsesWith(unpackInst);
+ inst->removeAndDeallocate();
+ }
+};
+
+void lowerReinterpret(TargetRequest* targetReq, IRModule* module, DiagnosticSink* sink)
+{
+ ReinterpretLoweringContext context;
+ context.module = module;
+ context.targetReq = targetReq;
+ context.sink = sink;
+ context.processModule();
+}
+
+}