summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-lower-optional-type.cpp
diff options
context:
space:
mode:
authorEllie Hermaszewska <ellieh@nvidia.com>2024-10-29 14:49:26 +0800
committerGitHub <noreply@github.com>2024-10-29 14:49:26 +0800
commitf65d756bff8d4c5cbc15bd0322a2ae8e6b896a21 (patch)
treeea1d61342cd29368e19135000ec2948813096205 /source/slang/slang-ir-lower-optional-type.cpp
parenta729c15e9dce9f5116a38afc66329ab2ca4cea54 (diff)
format
* format * Minor test fixes * enable checking cpp format in ci
Diffstat (limited to 'source/slang/slang-ir-lower-optional-type.cpp')
-rw-r--r--source/slang/slang-ir-lower-optional-type.cpp475
1 files changed, 230 insertions, 245 deletions
diff --git a/source/slang/slang-ir-lower-optional-type.cpp b/source/slang/slang-ir-lower-optional-type.cpp
index 272f04545..e6ae2eea3 100644
--- a/source/slang/slang-ir-lower-optional-type.cpp
+++ b/source/slang/slang-ir-lower-optional-type.cpp
@@ -1,297 +1,282 @@
// slang-ir-lower-optional-type.cpp
#include "slang-ir-lower-optional-type.h"
-#include "slang-ir.h"
+
#include "slang-ir-insts.h"
#include "slang-ir-util.h"
+#include "slang-ir.h"
namespace Slang
{
- struct OptionalTypeLoweringContext
- {
- IRModule* module;
- DiagnosticSink* sink;
+struct OptionalTypeLoweringContext
+{
+ IRModule* module;
+ DiagnosticSink* sink;
- InstWorkList workList;
- InstHashSet workListSet;
+ InstWorkList workList;
+ InstHashSet workListSet;
- IRGeneric* genericOptionalStructType = nullptr;
- IRStructKey* valueKey = nullptr;
- IRStructKey* hasValueKey = nullptr;
+ IRGeneric* genericOptionalStructType = nullptr;
+ IRStructKey* valueKey = nullptr;
+ IRStructKey* hasValueKey = nullptr;
- OptionalTypeLoweringContext(IRModule* inModule)
- :module(inModule), workList(inModule), workListSet(inModule)
- {}
+ OptionalTypeLoweringContext(IRModule* inModule)
+ : module(inModule), workList(inModule), workListSet(inModule)
+ {
+ }
- struct LoweredOptionalTypeInfo : public RefObject
- {
- IRType* optionalType = nullptr;
- IRType* valueType = nullptr;
- IRType* loweredType = nullptr;
- };
- Dictionary<IRInst*, RefPtr<LoweredOptionalTypeInfo>> mapLoweredTypeToOptionalTypeInfo;
- Dictionary<IRInst*, RefPtr<LoweredOptionalTypeInfo>> loweredOptionalTypes;
-
- IRType* maybeLowerOptionalType(IRBuilder* builder, IRType* type)
- {
- if (auto info = getLoweredOptionalType(builder, type))
- return info->loweredType;
- else
- return type;
- }
+ struct LoweredOptionalTypeInfo : public RefObject
+ {
+ IRType* optionalType = nullptr;
+ IRType* valueType = nullptr;
+ IRType* loweredType = nullptr;
+ };
+ Dictionary<IRInst*, RefPtr<LoweredOptionalTypeInfo>> mapLoweredTypeToOptionalTypeInfo;
+ Dictionary<IRInst*, RefPtr<LoweredOptionalTypeInfo>> loweredOptionalTypes;
- IRInst* getOrCreateGenericOptionalStruct()
- {
- if (genericOptionalStructType)
- return genericOptionalStructType;
- IRBuilder builder(module);
- builder.setInsertInto(module->getModuleInst());
-
- valueKey = builder.createStructKey();
- builder.addNameHintDecoration(valueKey, UnownedStringSlice("value"));
- hasValueKey = builder.createStructKey();
- builder.addNameHintDecoration(hasValueKey, UnownedStringSlice("hasValue"));
-
- genericOptionalStructType = builder.emitGeneric();
- builder.addNameHintDecoration(genericOptionalStructType, UnownedStringSlice("_slang_Optional"));
-
- builder.setInsertInto(genericOptionalStructType);
- auto block = builder.emitBlock();
- auto typeParam = builder.emitParam(builder.getTypeKind());
- auto structType = builder.createStructType();
- builder.addNameHintDecoration(structType, UnownedStringSlice("_slang_Optional"));
- builder.createStructField(structType, valueKey, (IRType*)typeParam);
- builder.createStructField(structType, hasValueKey, builder.getBoolType());
- builder.setInsertInto(block);
- builder.emitReturn(structType);
- genericOptionalStructType->setFullType(builder.getTypeKind());
+ IRType* maybeLowerOptionalType(IRBuilder* builder, IRType* type)
+ {
+ if (auto info = getLoweredOptionalType(builder, type))
+ return info->loweredType;
+ else
+ return type;
+ }
+
+ IRInst* getOrCreateGenericOptionalStruct()
+ {
+ if (genericOptionalStructType)
return genericOptionalStructType;
- }
+ IRBuilder builder(module);
+ builder.setInsertInto(module->getModuleInst());
+
+ valueKey = builder.createStructKey();
+ builder.addNameHintDecoration(valueKey, UnownedStringSlice("value"));
+ hasValueKey = builder.createStructKey();
+ builder.addNameHintDecoration(hasValueKey, UnownedStringSlice("hasValue"));
+
+ genericOptionalStructType = builder.emitGeneric();
+ builder.addNameHintDecoration(
+ genericOptionalStructType,
+ UnownedStringSlice("_slang_Optional"));
+
+ builder.setInsertInto(genericOptionalStructType);
+ auto block = builder.emitBlock();
+ auto typeParam = builder.emitParam(builder.getTypeKind());
+ auto structType = builder.createStructType();
+ builder.addNameHintDecoration(structType, UnownedStringSlice("_slang_Optional"));
+ builder.createStructField(structType, valueKey, (IRType*)typeParam);
+ builder.createStructField(structType, hasValueKey, builder.getBoolType());
+ builder.setInsertInto(block);
+ builder.emitReturn(structType);
+ genericOptionalStructType->setFullType(builder.getTypeKind());
+ return genericOptionalStructType;
+ }
- bool typeHasNullValue(IRInst* type)
+ bool typeHasNullValue(IRInst* type)
+ {
+ switch (type->getOp())
{
- switch (type->getOp())
- {
- case kIROp_ComPtrType:
- case kIROp_NativePtrType:
- case kIROp_NativeStringType:
- case kIROp_PtrType:
- case kIROp_ClassType:
- return true;
- case kIROp_InterfaceType:
- return isComInterfaceType((IRType*)type);
- default:
- return false;
- }
+ case kIROp_ComPtrType:
+ case kIROp_NativePtrType:
+ case kIROp_NativeStringType:
+ case kIROp_PtrType:
+ case kIROp_ClassType: return true;
+ case kIROp_InterfaceType: return isComInterfaceType((IRType*)type);
+ default: return false;
}
+ }
- LoweredOptionalTypeInfo* getLoweredOptionalType(IRBuilder* builder, IRInst* type)
+ LoweredOptionalTypeInfo* getLoweredOptionalType(IRBuilder* builder, IRInst* type)
+ {
+ if (auto loweredInfo = loweredOptionalTypes.tryGetValue(type))
+ return loweredInfo->Ptr();
+ if (auto loweredInfo = mapLoweredTypeToOptionalTypeInfo.tryGetValue(type))
+ return loweredInfo->Ptr();
+
+ if (!type)
+ return nullptr;
+ if (type->getOp() != kIROp_OptionalType)
+ return nullptr;
+
+ RefPtr<LoweredOptionalTypeInfo> info = new LoweredOptionalTypeInfo();
+ auto optionalType = cast<IROptionalType>(type);
+ auto valueType = optionalType->getValueType();
+ info->optionalType = (IRType*)type;
+ info->valueType = valueType;
+ if (typeHasNullValue(valueType))
{
- if (auto loweredInfo = loweredOptionalTypes.tryGetValue(type))
- return loweredInfo->Ptr();
- if (auto loweredInfo = mapLoweredTypeToOptionalTypeInfo.tryGetValue(type))
- return loweredInfo->Ptr();
-
- if (!type)
- return nullptr;
- if (type->getOp() != kIROp_OptionalType)
- return nullptr;
-
- RefPtr<LoweredOptionalTypeInfo> info = new LoweredOptionalTypeInfo();
- auto optionalType = cast<IROptionalType>(type);
- auto valueType = optionalType->getValueType();
- info->optionalType = (IRType*)type;
- info->valueType = valueType;
- if (typeHasNullValue(valueType))
- {
- info->loweredType = valueType;
- }
- else
- {
- auto genericType = getOrCreateGenericOptionalStruct();
- IRInst* args[] = { valueType };
- auto specializedType = builder->emitSpecializeInst(builder->getTypeKind(), genericType, 1, args);
- info->loweredType = (IRType*)specializedType;
- }
- mapLoweredTypeToOptionalTypeInfo[info->loweredType] = info;
- loweredOptionalTypes[type] = info;
- return info.Ptr();
+ info->loweredType = valueType;
}
-
- void addToWorkList(
- IRInst* inst)
+ else
{
- if (workListSet.contains(inst))
- return;
-
- workList.add(inst);
- workListSet.add(inst);
+ auto genericType = getOrCreateGenericOptionalStruct();
+ IRInst* args[] = {valueType};
+ auto specializedType =
+ builder->emitSpecializeInst(builder->getTypeKind(), genericType, 1, args);
+ info->loweredType = (IRType*)specializedType;
}
+ mapLoweredTypeToOptionalTypeInfo[info->loweredType] = info;
+ loweredOptionalTypes[type] = info;
+ return info.Ptr();
+ }
- void processMakeOptionalValue(IRMakeOptionalValue* inst)
- {
- IRBuilder builderStorage(module);
- auto builder = &builderStorage;
- builder->setInsertBefore(inst);
+ void addToWorkList(IRInst* inst)
+ {
+ if (workListSet.contains(inst))
+ return;
- auto info = getLoweredOptionalType(builder, inst->getDataType());
- if (info->loweredType != info->valueType)
- {
- List<IRInst*> operands;
- operands.add(inst->getOperand(0));
- operands.add(builder->getBoolValue(true));
- auto makeStruct = builder->emitMakeStruct(info->loweredType, operands);
- inst->replaceUsesWith(makeStruct);
- inst->removeAndDeallocate();
- }
- else
- {
- inst->replaceUsesWith(inst->getOperand(0));
- inst->removeAndDeallocate();
- }
- }
+ workList.add(inst);
+ workListSet.add(inst);
+ }
- void processMakeOptionalNone(IRMakeOptionalNone* inst)
- {
- IRBuilder builderStorage(module);
- auto builder = &builderStorage;
- builder->setInsertBefore(inst);
+ void processMakeOptionalValue(IRMakeOptionalValue* inst)
+ {
+ IRBuilder builderStorage(module);
+ auto builder = &builderStorage;
+ builder->setInsertBefore(inst);
- auto info = getLoweredOptionalType(builder, inst->getDataType());
- if (info->loweredType != info->valueType)
- {
- List<IRInst*> operands;
- operands.add(inst->getDefaultValue());
- operands.add(builder->getBoolValue(false));
- auto makeStruct = builder->emitMakeStruct(info->loweredType, operands);
- inst->replaceUsesWith(makeStruct);
- inst->removeAndDeallocate();
- }
- else
- {
- inst->replaceUsesWith(builder->getNullPtrValue(info->valueType));
- inst->removeAndDeallocate();
- }
+ auto info = getLoweredOptionalType(builder, inst->getDataType());
+ if (info->loweredType != info->valueType)
+ {
+ List<IRInst*> operands;
+ operands.add(inst->getOperand(0));
+ operands.add(builder->getBoolValue(true));
+ auto makeStruct = builder->emitMakeStruct(info->loweredType, operands);
+ inst->replaceUsesWith(makeStruct);
+ inst->removeAndDeallocate();
}
-
- IRInst* getOptionalHasValue(IRBuilder* builder, IRInst* optionalInst)
+ else
{
- auto loweredOptionalTypeInfo = getLoweredOptionalType(builder, optionalInst->getDataType());
- SLANG_ASSERT(loweredOptionalTypeInfo);
- IRInst* result = nullptr;
- if (loweredOptionalTypeInfo->loweredType != loweredOptionalTypeInfo->valueType)
- {
- result = builder->emitFieldExtract(
- builder->getBoolType(),
- optionalInst,
- hasValueKey);
- }
- else
- {
- result = builder->emitCastPtrToBool(optionalInst);
- }
- return result;
+ inst->replaceUsesWith(inst->getOperand(0));
+ inst->removeAndDeallocate();
}
+ }
- void processGetOptionalHasValue(IROptionalHasValue* inst)
- {
- IRBuilder builderStorage(module);
- auto builder = &builderStorage;
- builder->setInsertBefore(inst);
+ void processMakeOptionalNone(IRMakeOptionalNone* inst)
+ {
+ IRBuilder builderStorage(module);
+ auto builder = &builderStorage;
+ builder->setInsertBefore(inst);
- auto optionalValue = inst->getOptionalOperand();
- auto hasVal = getOptionalHasValue(builder, optionalValue);
- inst->replaceUsesWith(hasVal);
+ auto info = getLoweredOptionalType(builder, inst->getDataType());
+ if (info->loweredType != info->valueType)
+ {
+ List<IRInst*> operands;
+ operands.add(inst->getDefaultValue());
+ operands.add(builder->getBoolValue(false));
+ auto makeStruct = builder->emitMakeStruct(info->loweredType, operands);
+ inst->replaceUsesWith(makeStruct);
inst->removeAndDeallocate();
}
-
- void processGetOptionalValue(IRGetOptionalValue* inst)
+ else
{
- IRBuilder builderStorage(module);
- auto builder = &builderStorage;
- builder->setInsertBefore(inst);
-
- auto base = inst->getOptionalOperand();
- auto loweredOptionalTypeInfo = getLoweredOptionalType(builder, base->getDataType());
- if (loweredOptionalTypeInfo->loweredType != loweredOptionalTypeInfo->valueType)
- {
- SLANG_ASSERT(loweredOptionalTypeInfo);
- auto getElement = builder->emitFieldExtract(
- loweredOptionalTypeInfo->valueType,
- base,
- valueKey);
- inst->replaceUsesWith(getElement);
- }
- else
- {
- inst->replaceUsesWith(base);
- }
+ inst->replaceUsesWith(builder->getNullPtrValue(info->valueType));
inst->removeAndDeallocate();
}
+ }
- void processOptionalType(IROptionalType* inst)
+ IRInst* getOptionalHasValue(IRBuilder* builder, IRInst* optionalInst)
+ {
+ auto loweredOptionalTypeInfo = getLoweredOptionalType(builder, optionalInst->getDataType());
+ SLANG_ASSERT(loweredOptionalTypeInfo);
+ IRInst* result = nullptr;
+ if (loweredOptionalTypeInfo->loweredType != loweredOptionalTypeInfo->valueType)
+ {
+ result = builder->emitFieldExtract(builder->getBoolType(), optionalInst, hasValueKey);
+ }
+ else
{
- IRBuilder builderStorage(module);
- auto builder = &builderStorage;
- builder->setInsertBefore(inst);
+ result = builder->emitCastPtrToBool(optionalInst);
+ }
+ return result;
+ }
+
+ void processGetOptionalHasValue(IROptionalHasValue* inst)
+ {
+ IRBuilder builderStorage(module);
+ auto builder = &builderStorage;
+ builder->setInsertBefore(inst);
+
+ auto optionalValue = inst->getOptionalOperand();
+ auto hasVal = getOptionalHasValue(builder, optionalValue);
+ inst->replaceUsesWith(hasVal);
+ inst->removeAndDeallocate();
+ }
- auto loweredOptionalTypeInfo = getLoweredOptionalType(builder, inst);
+ void processGetOptionalValue(IRGetOptionalValue* inst)
+ {
+ IRBuilder builderStorage(module);
+ auto builder = &builderStorage;
+ builder->setInsertBefore(inst);
+
+ auto base = inst->getOptionalOperand();
+ auto loweredOptionalTypeInfo = getLoweredOptionalType(builder, base->getDataType());
+ if (loweredOptionalTypeInfo->loweredType != loweredOptionalTypeInfo->valueType)
+ {
SLANG_ASSERT(loweredOptionalTypeInfo);
- SLANG_UNUSED(loweredOptionalTypeInfo);
+ auto getElement =
+ builder->emitFieldExtract(loweredOptionalTypeInfo->valueType, base, valueKey);
+ inst->replaceUsesWith(getElement);
}
-
- void processInst(IRInst* inst)
+ else
{
- switch (inst->getOp())
- {
- case kIROp_MakeOptionalValue:
- processMakeOptionalValue((IRMakeOptionalValue*)inst);
- break;
- case kIROp_MakeOptionalNone:
- processMakeOptionalNone((IRMakeOptionalNone*)inst);
- break;
- case kIROp_OptionalHasValue:
- processGetOptionalHasValue((IROptionalHasValue*)inst);
- break;
- case kIROp_GetOptionalValue:
- processGetOptionalValue((IRGetOptionalValue*)inst);
- break;
- case kIROp_OptionalType:
- processOptionalType((IROptionalType*)inst);
- break;
- default:
- break;
- }
+ inst->replaceUsesWith(base);
}
+ inst->removeAndDeallocate();
+ }
- void processModule()
+ void processOptionalType(IROptionalType* inst)
+ {
+ IRBuilder builderStorage(module);
+ auto builder = &builderStorage;
+ builder->setInsertBefore(inst);
+
+ auto loweredOptionalTypeInfo = getLoweredOptionalType(builder, inst);
+ SLANG_ASSERT(loweredOptionalTypeInfo);
+ SLANG_UNUSED(loweredOptionalTypeInfo);
+ }
+
+ void processInst(IRInst* inst)
+ {
+ switch (inst->getOp())
{
- addToWorkList(module->getModuleInst());
+ case kIROp_MakeOptionalValue: processMakeOptionalValue((IRMakeOptionalValue*)inst); break;
+ case kIROp_MakeOptionalNone: processMakeOptionalNone((IRMakeOptionalNone*)inst); break;
+ case kIROp_OptionalHasValue: processGetOptionalHasValue((IROptionalHasValue*)inst); break;
+ case kIROp_GetOptionalValue: processGetOptionalValue((IRGetOptionalValue*)inst); break;
+ case kIROp_OptionalType: processOptionalType((IROptionalType*)inst); break;
+ default: break;
+ }
+ }
- while (workList.getCount() != 0)
- {
- IRInst* inst = workList.getLast();
- workList.removeLast();
- workListSet.remove(inst);
+ void processModule()
+ {
+ addToWorkList(module->getModuleInst());
- processInst(inst);
+ while (workList.getCount() != 0)
+ {
+ IRInst* inst = workList.getLast();
+ workList.removeLast();
+ workListSet.remove(inst);
- for (auto child = inst->getLastChild(); child; child = child->getPrevInst())
- {
- addToWorkList(child);
- }
- }
+ processInst(inst);
- // Replace all optional types with lowered struct types.
- for (const auto& [key, value] : loweredOptionalTypes)
- key->replaceUsesWith(value->loweredType);
+ for (auto child = inst->getLastChild(); child; child = child->getPrevInst())
+ {
+ addToWorkList(child);
+ }
}
- };
-
- void lowerOptionalType(IRModule* module, DiagnosticSink* sink)
- {
- OptionalTypeLoweringContext context(module);
- context.sink = sink;
- context.processModule();
+
+ // Replace all optional types with lowered struct types.
+ for (const auto& [key, value] : loweredOptionalTypes)
+ key->replaceUsesWith(value->loweredType);
}
+};
+
+void lowerOptionalType(IRModule* module, DiagnosticSink* sink)
+{
+ OptionalTypeLoweringContext context(module);
+ context.sink = sink;
+ context.processModule();
}
+} // namespace Slang