diff options
| author | Yong He <yonghe@outlook.com> | 2022-12-07 12:52:20 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-07 12:52:20 -0800 |
| commit | 70714705747f3491c55e14b74f87641010351d6c (patch) | |
| tree | 8b0e3905892da915b731521dbd3dc0c86482b406 /source/slang/slang-ir.cpp | |
| parent | 3a3a8b5f7701109fc413f42692c4de5769870489 (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.cpp | 254 |
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: |
