summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-lower-optional-type.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-08-22 14:17:56 -0700
committerGitHub <noreply@github.com>2022-08-22 14:17:56 -0700
commit4bd3e6e02324f913e8927fe69d32c0aafe9fc831 (patch)
tree1f6ff8449feb49d00dee2bc527f7dc531a07c196 /source/slang/slang-ir-lower-optional-type.cpp
parent393185196ed65a9eeaf9502edbf3dcce87337d81 (diff)
Make Optional<PointerType> lower to PointerType instead of a struct. (#2373)
Diffstat (limited to 'source/slang/slang-ir-lower-optional-type.cpp')
-rw-r--r--source/slang/slang-ir-lower-optional-type.cpp95
1 files changed, 66 insertions, 29 deletions
diff --git a/source/slang/slang-ir-lower-optional-type.cpp b/source/slang/slang-ir-lower-optional-type.cpp
index 79be4e042..96f8353bb 100644
--- a/source/slang/slang-ir-lower-optional-type.cpp
+++ b/source/slang/slang-ir-lower-optional-type.cpp
@@ -3,6 +3,7 @@
#include "slang-ir-lower-optional-type.h"
#include "slang-ir.h"
#include "slang-ir-insts.h"
+#include "slang-ir-util.h"
namespace Slang
{
@@ -35,6 +36,23 @@ namespace Slang
return type;
}
+ bool typeHasNullValue(IRInst* type)
+ {
+ 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;
+ }
+ }
+
LoweredOptionalTypeInfo* getLoweredOptionalType(IRBuilder* builder, IRInst* type)
{
if (auto loweredInfo = loweredOptionalTypes.TryGetValue(type))
@@ -48,25 +66,30 @@ namespace Slang
return nullptr;
RefPtr<LoweredOptionalTypeInfo> info = new LoweredOptionalTypeInfo();
- info->optionalType = (IRType*)type;
auto optionalType = cast<IROptionalType>(type);
auto valueType = optionalType->getValueType();
+ info->optionalType = (IRType*)type;
info->valueType = valueType;
-
- auto structType = builder->createStructType();
- info->loweredType = structType;
- builder->addNameHintDecoration(structType, UnownedStringSlice("OptionalType"));
-
- info->valueType = valueType;
- auto valueKey = builder->createStructKey();
- builder->addNameHintDecoration(valueKey, UnownedStringSlice("value"));
- info->valueField = builder->createStructField(structType, valueKey, (IRType*)valueType);
-
- auto boolType = builder->getBoolType();
- auto hasValueKey = builder->createStructKey();
- builder->addNameHintDecoration(hasValueKey, UnownedStringSlice("hasValue"));
- info->hasValueField = builder->createStructField(structType, hasValueKey, (IRType*)boolType);
-
+ if (typeHasNullValue(valueType))
+ {
+ info->loweredType = valueType;
+ }
+ else
+ {
+ auto structType = builder->createStructType();
+ info->loweredType = structType;
+ builder->addNameHintDecoration(structType, UnownedStringSlice("OptionalType"));
+
+ info->valueType = valueType;
+ auto valueKey = builder->createStructKey();
+ builder->addNameHintDecoration(valueKey, UnownedStringSlice("value"));
+ info->valueField = builder->createStructField(structType, valueKey, (IRType*)valueType);
+
+ auto boolType = builder->getBoolType();
+ auto hasValueKey = builder->createStructKey();
+ builder->addNameHintDecoration(hasValueKey, UnownedStringSlice("hasValue"));
+ info->hasValueField = builder->createStructField(structType, hasValueKey, (IRType*)boolType);
+ }
mapLoweredTypeToOptionalTypeInfo[info->loweredType] = info;
loweredOptionalTypes[type] = info;
return info.Ptr();
@@ -123,12 +146,19 @@ namespace Slang
{
auto loweredOptionalTypeInfo = getLoweredOptionalType(builder, optionalInst->getDataType());
SLANG_ASSERT(loweredOptionalTypeInfo);
-
- auto value = builder->emitFieldExtract(
- builder->getBoolType(),
- optionalInst,
- loweredOptionalTypeInfo->hasValueField->getKey());
- return value;
+ IRInst* result = nullptr;
+ if (loweredOptionalTypeInfo->loweredType != loweredOptionalTypeInfo->valueType)
+ {
+ result = builder->emitFieldExtract(
+ builder->getBoolType(),
+ optionalInst,
+ loweredOptionalTypeInfo->hasValueField->getKey());
+ }
+ else
+ {
+ result = builder->emitCastPtrToBool(optionalInst);
+ }
+ return result;
}
void processGetOptionalHasValue(IROptionalHasValue* inst)
@@ -151,13 +181,20 @@ namespace Slang
auto base = inst->getOptionalOperand();
auto loweredOptionalTypeInfo = getLoweredOptionalType(builder, base->getDataType());
- SLANG_ASSERT(loweredOptionalTypeInfo);
- SLANG_ASSERT(loweredOptionalTypeInfo->valueField);
- auto getElement = builder->emitFieldExtract(
- loweredOptionalTypeInfo->valueType,
- base,
- loweredOptionalTypeInfo->valueField->getKey());
- inst->replaceUsesWith(getElement);
+ if (loweredOptionalTypeInfo->loweredType != loweredOptionalTypeInfo->valueType)
+ {
+ SLANG_ASSERT(loweredOptionalTypeInfo);
+ SLANG_ASSERT(loweredOptionalTypeInfo->valueField);
+ auto getElement = builder->emitFieldExtract(
+ loweredOptionalTypeInfo->valueType,
+ base,
+ loweredOptionalTypeInfo->valueField->getKey());
+ inst->replaceUsesWith(getElement);
+ }
+ else
+ {
+ inst->replaceUsesWith(base);
+ }
inst->removeAndDeallocate();
}