summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2022-12-07 12:52:20 -0800
committerGitHub <noreply@github.com>2022-12-07 12:52:20 -0800
commit70714705747f3491c55e14b74f87641010351d6c (patch)
tree8b0e3905892da915b731521dbd3dc0c86482b406 /source/slang/slang-ir.cpp
parent3a3a8b5f7701109fc413f42692c4de5769870489 (diff)
Remove `construct` IR op. (#2555)
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang/slang-ir.cpp')
-rw-r--r--source/slang/slang-ir.cpp254
1 files changed, 240 insertions, 14 deletions
diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp
index fcf821b69..5340f7179 100644
--- a/source/slang/slang-ir.cpp
+++ b/source/slang/slang-ir.cpp
@@ -1,6 +1,7 @@
// slang-ir.cpp
#include "slang-ir.h"
#include "slang-ir-insts.h"
+#include "slang-ir-util.h"
#include "../core/slang-basic.h"
@@ -3300,19 +3301,244 @@ namespace Slang
return inst;
}
- IRInst* IRBuilder::emitConstructorInst(
- IRType* type,
- UInt argCount,
- IRInst* const* args)
+ IRInst* IRBuilder::emitDefaultConstruct(IRType* type, bool fallback)
{
- auto inst = createInstWithTrailingArgs<IRInst>(
- this,
- kIROp_Construct,
- type,
- argCount,
- args);
- addInst(inst);
- return inst;
+ IRType* actualType = type;
+ for (;;)
+ {
+ if (auto attr = as<IRAttributedType>(actualType))
+ actualType = attr->getBaseType();
+ else if (auto rateQualified = as<IRRateQualifiedType>(actualType))
+ actualType = rateQualified->getValueType();
+ else
+ break;
+ }
+ switch (actualType->getOp())
+ {
+ case kIROp_Int8Type:
+ case kIROp_Int16Type:
+ case kIROp_IntType:
+ case kIROp_IntPtrType:
+ case kIROp_Int64Type:
+ case kIROp_UInt8Type:
+ case kIROp_UInt16Type:
+ case kIROp_UIntType:
+ case kIROp_UIntPtrType:
+ case kIROp_UInt64Type:
+ case kIROp_CharType:
+ return getIntValue(type, 0);
+ case kIROp_BoolType:
+ return getBoolValue(false);
+ case kIROp_FloatType:
+ case kIROp_HalfType:
+ case kIROp_DoubleType:
+ return getFloatValue(type, 0.0);
+ case kIROp_VoidType:
+ return getVoidValue();
+ case kIROp_StringType:
+ return getStringValue(UnownedStringSlice());
+ case kIROp_PtrType:
+ case kIROp_InOutType:
+ case kIROp_OutType:
+ case kIROp_RawPointerType:
+ case kIROp_RefType:
+ case kIROp_ComPtrType:
+ case kIROp_NativePtrType:
+ case kIROp_NativeStringType:
+ return getNullPtrValue(type);
+ case kIROp_OptionalType:
+ {
+ auto inner = emitDefaultConstruct(as<IROptionalType>(actualType)->getValueType(), fallback);
+ if (!inner)
+ return nullptr;
+ return emitMakeOptionalNone(type, inner);
+ }
+ case kIROp_TupleType:
+ {
+ List<IRInst*> elements;
+ auto tupleType = as<IRTupleType>(actualType);
+ for (UInt i = 0; i < tupleType->getOperandCount(); i++)
+ {
+ auto operand = tupleType->getOperand(i);
+ if (as<IRAttr>(operand))
+ break;
+ auto inner = emitDefaultConstruct((IRType*)operand, fallback);
+ if (!inner)
+ return nullptr;
+ elements.add(inner);
+ }
+ return emitMakeTuple(type, elements);
+ }
+ case kIROp_StructType:
+ {
+ List<IRInst*> elements;
+ auto structType = as<IRStructType>(actualType);
+ for (auto field : structType->getFields())
+ {
+ auto fieldType = field->getFieldType();
+ auto inner = emitDefaultConstruct(fieldType, fallback);
+ if (!inner)
+ return nullptr;
+ elements.add(inner);
+ }
+ return emitMakeStruct(type, elements);
+ }
+ case kIROp_ArrayType:
+ {
+ auto arrayType = as<IRArrayType>(actualType);
+ if (auto count = as<IRIntLit>(arrayType->getElementCount()))
+ {
+ auto element = emitDefaultConstruct(arrayType->getElementType(), fallback);
+ if (!element)
+ return nullptr;
+ List<IRInst*> elements;
+ constexpr int maxCount = 4096;
+ if (count->getValue() > maxCount)
+ break;
+ for (IRIntegerValue i = 0; i < count->getValue(); i++)
+ {
+ elements.add(element);
+ }
+ return emitMakeArray(type, elements.getCount(), elements.getBuffer());
+ }
+ break;
+ }
+ case kIROp_VectorType:
+ {
+ auto inner = emitDefaultConstruct(as<IRVectorType>(actualType)->getElementType(), fallback);
+ if (!inner)
+ return nullptr;
+ return emitIntrinsicInst(type, kIROp_constructVectorFromScalar, 1, &inner);
+ }
+ case kIROp_MatrixType:
+ {
+ auto inner = emitDefaultConstruct(as<IRMatrixType>(actualType)->getElementType(), fallback);
+ if (!inner)
+ return nullptr;
+ return emitIntrinsicInst(type, kIROp_MakeMatrixFromScalar, 1, &inner);
+ }
+ default:
+ break;
+ }
+ if (fallback)
+ {
+ return emitIntrinsicInst(type, kIROp_DefaultConstruct, 0, nullptr);
+ }
+ return nullptr;
+ }
+
+ static int _getTypeStyleId(IRType* type)
+ {
+ if (auto vectorType = as<IRVectorType>(type))
+ {
+ return _getTypeStyleId(vectorType->getElementType());
+ }
+ if(auto matrixType = as<IRMatrixType>(type))
+ {
+ return _getTypeStyleId(matrixType->getElementType());
+ }
+ auto style = getTypeStyle(type->getOp());
+ switch (style)
+ {
+ case kIROp_IntType:
+ return 0;
+ case kIROp_FloatType:
+ return 1;
+ case kIROp_BoolType:
+ return 2;
+ case kIROp_PtrType:
+ case kIROp_InOutType:
+ case kIROp_OutType:
+ case kIROp_RawPointerType:
+ case kIROp_RefType:
+ return 3;
+ case kIROp_VoidType:
+ return 4;
+ default:
+ return -1;
+ }
+ }
+
+ IRInst* IRBuilder::emitCast(IRType* type, IRInst* value)
+ {
+ if (isTypeEqual(type, value->getDataType()))
+ return value;
+
+ auto toStyle = _getTypeStyleId(type);
+ auto fromStyle = _getTypeStyleId(value->getDataType());
+
+ if (fromStyle == kIROp_VoidType)
+ {
+ // We shouldn't be casting from void to other types.
+ SLANG_UNREACHABLE("cast from void type");
+ }
+
+ SLANG_RELEASE_ASSERT(toStyle != -1);
+ SLANG_RELEASE_ASSERT(fromStyle != -1);
+
+ struct OpSeq
+ {
+ IROp op0, op1;
+ OpSeq(IROp op)
+ {
+ op0 = op; op1 = kIROp_Nop;
+ }
+ OpSeq(IROp op, IROp inOp1)
+ {
+ op0 = op; op1 = inOp1;
+ }
+ };
+
+ static const OpSeq opMap[4][5] =
+ {
+ /* To: Int, Float, Bool, Ptr, Void*/
+ /* From Int */ {kIROp_IntCast, kIROp_CastIntToFloat, kIROp_IntCast, kIROp_CastIntToPtr, kIROp_CastToVoid },
+ /* From Float */ {kIROp_CastFloatToInt, kIROp_FloatCast, {kIROp_CastFloatToInt, kIROp_IntCast}, {kIROp_CastFloatToInt, kIROp_CastIntToPtr}, kIROp_CastToVoid},
+ /* From Bool */ {kIROp_IntCast, kIROp_CastIntToFloat, kIROp_Nop, kIROp_CastIntToPtr, kIROp_CastToVoid},
+ /* From Ptr */ {kIROp_CastPtrToInt, {kIROp_CastPtrToInt, kIROp_CastIntToFloat}, kIROp_CastPtrToBool, kIROp_BitCast, kIROp_CastToVoid},
+ };
+
+ auto op = opMap[fromStyle][toStyle];
+ if (op.op0 == kIROp_Nop)
+ return value;
+ auto t = type;
+ if (op.op1 != kIROp_Nop)
+ {
+ t = getUInt64Type();
+ }
+ auto result = emitIntrinsicInst(t, op.op0, 1, &value);
+ if (op.op1 != kIROp_Nop)
+ {
+ result = emitIntrinsicInst(type, op.op1, 1, &result);
+ }
+ return result;
+ }
+
+ IRInst* IRBuilder::emitVectorReshape(IRType* type, IRInst* value)
+ {
+ auto targetVectorType = as<IRVectorType>(type);
+ auto sourceVectorType = as<IRVectorType>(value->getDataType());
+ if (!targetVectorType)
+ {
+ if (!sourceVectorType)
+ return emitCast(targetVectorType, value);
+ else
+ {
+ UInt index = 0;
+ return emitCast(type, emitSwizzle(sourceVectorType->getElementType(), value, 1, &index));
+ }
+ }
+ if (targetVectorType->getElementCount() != sourceVectorType->getElementCount())
+ {
+ auto reshape = emitIntrinsicInst(
+ getVectorType(
+ sourceVectorType->getElementType(), targetVectorType->getElementCount()),
+ kIROp_VectorReshape,
+ 1,
+ &value);
+ return emitCast(type, reshape);
+ }
+ return value;
}
IRInst* IRBuilder::emitMakeUInt64(IRInst* low, IRInst* high)
@@ -6315,12 +6541,12 @@ namespace Slang
case kIROp_GetSequentialID:
case kIROp_getAddr:
case kIROp_GetValueFromBoundInterface:
- case kIROp_Construct:
case kIROp_makeUInt64:
case kIROp_makeVector:
case kIROp_MakeMatrix:
case kIROp_MakeMatrixFromScalar:
- case kIROp_MatrixTruncate:
+ case kIROp_MatrixReshape:
+ case kIROp_VectorReshape:
case kIROp_makeArray:
case kIROp_makeStruct:
case kIROp_makeString: