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 | |
| parent | 3a3a8b5f7701109fc413f42692c4de5769870489 (diff) | |
Remove `construct` IR op. (#2555)
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source')
22 files changed, 322 insertions, 110 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 17af354ca..55e6706ec 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -1012,7 +1012,7 @@ for( int C = 2; C <= 4; ++C ) for( int cc = C; cc <= 4; ++cc ) { if(rr == R && cc == C) continue; - sb << "__intrinsic_op(" << int(kIROp_MatrixTruncate) << ") __init(matrix<T," << rr << "," << cc << "> value);\n"; + sb << "__intrinsic_op(" << int(kIROp_MatrixReshape) << ") __init(matrix<T," << rr << "," << cc << "> value);\n"; } sb << "}\n"; } diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index fa5e9a821..662c89f3b 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -1776,11 +1776,11 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO emitSimpleValue(inst); break; - case kIROp_Construct: case kIROp_makeVector: case kIROp_MakeMatrix: case kIROp_MakeMatrixFromScalar: - case kIROp_MatrixTruncate: + case kIROp_MatrixReshape: + case kIROp_VectorReshape: case kIROp_CastFloatToInt: case kIROp_CastIntToFloat: case kIROp_IntCast: diff --git a/source/slang/slang-emit-cuda.cpp b/source/slang/slang-emit-cuda.cpp index cbeddcb13..24462594f 100644 --- a/source/slang/slang-emit-cuda.cpp +++ b/source/slang/slang-emit-cuda.cpp @@ -25,25 +25,6 @@ void CUDAExtensionTracker::finalize() } } -static bool _isSingleNameBasicType(IROp op) -{ - switch (op) - { - case kIROp_Int64Type: - case kIROp_UInt8Type: - case kIROp_UInt16Type: - case kIROp_UIntType: - case kIROp_UInt64Type: - case kIROp_IntPtrType: - case kIROp_UIntPtrType: - { - return false; - } - default: return true; - - } -} - UnownedStringSlice CUDASourceEmitter::getBuiltinTypeName(IROp op) { switch (op) @@ -547,7 +528,6 @@ void CUDASourceEmitter::_emitInitializerListValue(IRType* dstType, IRInst* value switch (value->getOp()) { - case kIROp_Construct: case kIROp_MakeMatrix: case kIROp_makeVector: { @@ -734,22 +714,6 @@ bool CUDASourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu } break; } - case kIROp_Construct: - { - // Simple constructor call - // On CUDA some of the built in types can't be used as constructors directly - - IRType* type = inst->getDataType(); - if (auto basicType = as<IRBasicType>(type) && !_isSingleNameBasicType(type->getOp())) - { - m_writer->emit("("); - emitType(inst->getDataType()); - m_writer->emit(")"); - emitArgs(inst); - return true; - } - break; - } case kIROp_makeArray: { IRType* dataType = inst->getDataType(); diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp index b4db75616..d98c69430 100644 --- a/source/slang/slang-emit-hlsl.cpp +++ b/source/slang/slang-emit-hlsl.cpp @@ -433,7 +433,6 @@ bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu { switch (inst->getOp()) { - case kIROp_Construct: case kIROp_makeVector: case kIROp_MakeMatrix: { diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index c0431cbeb..8027cb2d5 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -1601,11 +1601,13 @@ struct SPIRVEmitContext return emitStore(parent, as<IRStore>(inst)); case kIROp_swizzle: return emitSwizzle(parent, as<IRSwizzle>(inst)); - case kIROp_Construct: case kIROp_IntCast: case kIROp_FloatCast: case kIROp_CastIntToFloat: case kIROp_CastFloatToInt: + case kIROp_MatrixReshape: + case kIROp_VectorReshape: + // TODO: break emitConstruct into separate functions for each opcode. return emitConstruct(parent, inst); case kIROp_BitCast: return emitInst( diff --git a/source/slang/slang-hlsl-intrinsic-set.cpp b/source/slang/slang-hlsl-intrinsic-set.cpp index 8d5944112..01c558a48 100644 --- a/source/slang/slang-hlsl-intrinsic-set.cpp +++ b/source/slang/slang-hlsl-intrinsic-set.cpp @@ -262,7 +262,6 @@ SlangResult HLSLIntrinsicSet::makeIntrinsic(IRInst* inst, HLSLIntrinsic& out) calcIntrinsic(Op::ConstructFromScalar, inst, 1, out); return SLANG_OK; } - case kIROp_Construct: case kIROp_IntCast: case kIROp_FloatCast: case kIROp_CastIntToFloat: @@ -299,6 +298,7 @@ SlangResult HLSLIntrinsicSet::makeIntrinsic(IRInst* inst, HLSLIntrinsic& out) return SLANG_FAIL; } case kIROp_makeVector: + case kIROp_VectorReshape: { if (inst->getOperandCount() == 1 && as<IRBasicType>(inst->getOperand(0)->getDataType())) { @@ -312,7 +312,7 @@ SlangResult HLSLIntrinsicSet::makeIntrinsic(IRInst* inst, HLSLIntrinsic& out) return SLANG_OK; } case kIROp_MakeMatrix: - case kIROp_MatrixTruncate: + case kIROp_MatrixReshape: { // We only emit as if it has one operand, but we can tell how many it actually has from the return type calcIntrinsic(Op::Init, inst, inst->getOperandCount(), out); diff --git a/source/slang/slang-ir-any-value-marshalling.cpp b/source/slang/slang-ir-any-value-marshalling.cpp index 446d8faf0..de8fd4dd5 100644 --- a/source/slang/slang-ir-any-value-marshalling.cpp +++ b/source/slang/slang-ir-any-value-marshalling.cpp @@ -289,7 +289,7 @@ namespace Slang { srcVal = builder->emitBitCast(builder->getType(kIROp_UInt16Type), srcVal); } - srcVal = builder->emitConstructorInst(builder->getType(kIROp_UIntType), 1, &srcVal); + srcVal = builder->emitCast(builder->getType(kIROp_UIntType), srcVal); auto dstAddr = builder->emitFieldAddress( uintPtrType, anyValueVar, @@ -340,7 +340,7 @@ namespace Slang { auto srcVal = builder->emitLoad(concreteVar); auto uint64Val = builder->emitBitCast(builder->getUInt64Type(), srcVal); - auto lowBits = builder->emitConstructorInst(builder->getUIntType(), 1, &uint64Val); + auto lowBits = builder->emitCast(builder->getUIntType(), uint64Val); auto shiftedBits = builder->emitShr( builder->getUInt64Type(), uint64Val, @@ -468,11 +468,11 @@ namespace Slang } if (dataType->getOp() == kIROp_Int16Type) { - srcVal = builder->emitConstructorInst(builder->getType(kIROp_Int16Type), 1, &srcVal); + srcVal = builder->emitCast(builder->getType(kIROp_Int16Type), srcVal); } else { - srcVal = builder->emitConstructorInst(builder->getType(kIROp_UInt16Type), 1, &srcVal); + srcVal = builder->emitCast(builder->getType(kIROp_UInt16Type), srcVal); } if (dataType->getOp() == kIROp_HalfType) { diff --git a/source/slang/slang-ir-autodiff-fwd.cpp b/source/slang/slang-ir-autodiff-fwd.cpp index 8a9fdaf6f..4708d071f 100644 --- a/source/slang/slang-ir-autodiff-fwd.cpp +++ b/source/slang/slang-ir-autodiff-fwd.cpp @@ -1587,7 +1587,8 @@ InstPair ForwardDerivativeTranscriber::transcribeInst(IRBuilder* builder, IRInst case kIROp_makeVector: case kIROp_MakeMatrix: case kIROp_MakeMatrixFromScalar: - case kIROp_MatrixTruncate: + case kIROp_MatrixReshape: + case kIROp_VectorReshape: case kIROp_IntCast: case kIROp_FloatCast: return transcribeConstruct(builder, origInst); diff --git a/source/slang/slang-ir-constexpr.cpp b/source/slang/slang-ir-constexpr.cpp index 8a772485f..a099d37e1 100644 --- a/source/slang/slang-ir-constexpr.cpp +++ b/source/slang/slang-ir-constexpr.cpp @@ -89,11 +89,12 @@ bool opCanBeConstExpr(IROp op) case kIROp_Lsh: case kIROp_Rsh: case kIROp_Select: - case kIROp_Construct: case kIROp_constructVectorFromScalar: case kIROp_makeVector: case kIROp_MakeMatrix: case kIROp_MakeMatrixFromScalar: + case kIROp_MatrixReshape: + case kIROp_VectorReshape: case kIROp_CastFloatToInt: case kIROp_CastIntToFloat: case kIROp_IntCast: diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp index fd256c68c..0dcd437fe 100644 --- a/source/slang/slang-ir-glsl-legalize.cpp +++ b/source/slang/slang-ir-glsl-legalize.cpp @@ -45,7 +45,7 @@ void legalizeImageSubscriptStoreForGLSL(IRBuilder& builder, IRInst* storeInst) auto legalizedCoord = imageSubscript->getCoord(); if (coordType != imageSubscript->getCoord()->getDataType()) { - legalizedCoord = builder.emitConstructorInst(coordType, 1, &legalizedCoord); + legalizedCoord = builder.emitCast(coordType, legalizedCoord); } switch (storeInst->getOp()) { @@ -55,11 +55,10 @@ void legalizeImageSubscriptStoreForGLSL(IRBuilder& builder, IRInst* storeInst) if (getIRVectorElementSize(imageElementType) != 4) { auto vectorBaseType = getIRVectorBaseType(imageElementType); - newValue = builder.emitConstructorInst( + newValue = builder.emitVectorReshape( builder.getVectorType( vectorBaseType, builder.getIntValue(builder.getIntType(), 4)), - 1, - &newValue); + newValue); } auto imageStore = builder.emitImageStore( builder.getVoidType(), @@ -95,11 +94,10 @@ void legalizeImageSubscriptStoreForGLSL(IRBuilder& builder, IRInst* storeInst) if (getIRVectorElementSize(imageElementType) != 4) { auto vectorBaseType = getIRVectorBaseType(imageElementType); - newValue = builder.emitConstructorInst( + newValue = builder.emitVectorReshape( builder.getVectorType( vectorBaseType, builder.getIntValue(builder.getIntType(), 4)), - 1, - &newValue); + newValue); } auto imageStore = builder.emitImageStore( builder.getVoidType(), imageSubscript->getImage(), legalizedCoord, newValue); @@ -1332,10 +1330,9 @@ ScalarizedVal adaptType( IRType* /*fromType*/) { // TODO: actually consider what needs to go on here... - return ScalarizedVal::value(builder->emitConstructorInst( + return ScalarizedVal::value(builder->emitCast( toType, - 1, - &val)); + val)); } ScalarizedVal adaptType( @@ -1602,7 +1599,7 @@ IRInst* materializeTupleValue( // so we can simply materialize the elements and then // construct a value of that type. // - // TODO: this should be using a `makeStruct` instruction. + SLANG_RELEASE_ASSERT(as<IRStructType>(type)); List<IRInst*> elementVals; for( Index ee = 0; ee < elementCount; ++ee ) @@ -1611,7 +1608,7 @@ IRInst* materializeTupleValue( elementVals.add(elementVal); } - return builder->emitConstructorInst( + return builder->emitMakeStruct( tupleVal->type, elementVals.getCount(), elementVals.getBuffer()); diff --git a/source/slang/slang-ir-hoist-constants.cpp b/source/slang/slang-ir-hoist-constants.cpp index 87d3487a3..b3908f60f 100644 --- a/source/slang/slang-ir-hoist-constants.cpp +++ b/source/slang/slang-ir-hoist-constants.cpp @@ -60,9 +60,34 @@ struct HoistConstantPass : InstPassBase case kIROp_BitCast: case kIROp_Lsh: case kIROp_Rsh: - case kIROp_Construct: + case kIROp_MatrixReshape: + case kIROp_VectorReshape: case kIROp_makeVector: case kIROp_MakeMatrix: + case kIROp_MakeMatrixFromScalar: + case kIROp_constructVectorFromScalar: + case kIROp_MakeOptionalNone: + case kIROp_MakeOptionalValue: + case kIROp_MakeDifferentialPair: + case kIROp_MakeExistential: + case kIROp_ExtractExistentialType: + case kIROp_ExtractExistentialValue: + case kIROp_ExtractExistentialWitnessTable: + case kIROp_WrapExistential: + case kIROp_WitnessTableType: + case kIROp_AttributedType: + case kIROp_MatrixType: + case kIROp_OptionalHasValue: + case kIROp_GetOptionalValue: + case kIROp_IntCast: + case kIROp_FloatCast: + case kIROp_CastIntToFloat: + case kIROp_CastFloatToInt: + case kIROp_CastPtrToBool: + case kIROp_CastPtrToInt: + case kIROp_CastIntToPtr: + case kIROp_CastToVoid: + case kIROp_Reinterpret: case kIROp_swizzle: case kIROp_IntLit: case kIROp_BoolLit: diff --git a/source/slang/slang-ir-inline.cpp b/source/slang/slang-ir-inline.cpp index 36eea8c54..ef01de47e 100644 --- a/source/slang/slang-ir-inline.cpp +++ b/source/slang/slang-ir-inline.cpp @@ -249,7 +249,7 @@ struct InliningPassBase for (UInt i = 0; i < call->getArgCount(); i++) args.add(call->getArg(i)); auto op = intrinsicOpDecor->getIntrinsicOp(); - if (op == 0) + if (op == kIROp_Nop) { SLANG_RELEASE_ASSERT(call->getArgCount() >= 1); call->replaceUsesWith(call->getArg(0)); diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index e5df5fc5c..cb1241bc2 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -283,15 +283,14 @@ INST(lookup_interface_method, lookup_interface_method, 2, 0) INST(GetSequentialID, GetSequentialID, 1, 0) INST(lookup_witness_table, lookup_witness_table, 2, 0) INST(BindGlobalGenericParam, bind_global_generic_param, 2, 0) -INST(Construct, construct, 0, 0) INST(AllocObj, allocObj, 0, 0) INST(makeUInt64, makeUInt64, 2, 0) INST(makeVector, makeVector, 0, 0) INST(MakeMatrix, makeMatrix, 0, 0) INST(MakeMatrixFromScalar, makeMatrixFromScalar, 1, 0) -INST(MatrixTruncate, matrixTrunc, 1, 0) - +INST(MatrixReshape, matrixReshape, 1, 0) +INST(VectorReshape, vectorReshape, 1, 0) INST(makeArray, makeArray, 0, 0) INST(makeStruct, makeStruct, 0, 0) INST(MakeTuple, makeTuple, 0, 0) diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index ae6516ed0..050a1be2d 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -2695,10 +2695,16 @@ public: UInt argCount, IRInst* const* args); - IRInst* emitConstructorInst( - IRType* type, - UInt argCount, - IRInst* const* args); + /// Emits appropriate inst for constructing a default value of `type`. + /// If `fallback` is true, will emit `DefaultConstruct` inst on unknown types. + /// Otherwise, returns nullptr if we can't materialize the inst. + IRInst* emitDefaultConstruct(IRType* type, bool fallback = true); + + IRInst* emitCast( + IRType* type, + IRInst* value); + + IRInst* emitVectorReshape(IRType* type, IRInst* value); IRInst* emitMakeUInt64(IRInst* low, IRInst* high); diff --git a/source/slang/slang-ir-legalize-types.cpp b/source/slang/slang-ir-legalize-types.cpp index e3f99fa49..51244edbb 100644 --- a/source/slang/slang-ir-legalize-types.cpp +++ b/source/slang/slang-ir-legalize-types.cpp @@ -1609,21 +1609,6 @@ static LegalVal legalizeMakeStruct( } } -static LegalVal legalizeConstruct(IRTypeLegalizationContext* context, - LegalType type) -{ - switch (type.flavor) - { - case LegalType::Flavor::none: - return LegalVal(); - case LegalType::Flavor::simple: - return LegalVal::simple(context->builder->emitConstructorInst(type.getSimple(), 0, nullptr)); - default: - SLANG_UNEXPECTED("unhandled legalization case for construct inst."); - UNREACHABLE_RETURN(LegalVal()); - } -} - static LegalVal legalizeInst( IRTypeLegalizationContext* context, IRInst* inst, @@ -1663,8 +1648,6 @@ static LegalVal legalizeInst( type, args, inst->getOperandCount()); - case kIROp_Construct: - return legalizeConstruct(context, type); case kIROp_undefined: return LegalVal(); case kIROp_GpuForeach: diff --git a/source/slang/slang-ir-liveness.cpp b/source/slang/slang-ir-liveness.cpp index 4a39dc612..86dc9381d 100644 --- a/source/slang/slang-ir-liveness.cpp +++ b/source/slang/slang-ir-liveness.cpp @@ -1025,10 +1025,6 @@ bool LivenessContext::_isAccessTerminator(IRTerminatorInst* terminator) // Strip construct switch (val->getOp()) { - case kIROp_Construct: - if (val->getOperandCount() == 1) - val = val->getOperand(0); - break; case kIROp_CastIntToFloat: case kIROp_CastFloatToInt: case kIROp_IntCast: diff --git a/source/slang/slang-ir-lower-result-type.cpp b/source/slang/slang-ir-lower-result-type.cpp index 07124d0d6..623583c7a 100644 --- a/source/slang/slang-ir-lower-result-type.cpp +++ b/source/slang/slang-ir-lower-result-type.cpp @@ -152,7 +152,7 @@ namespace Slang if (info->valueField) { List<IRInst*> operands; - operands.add(builder->emitConstructorInst(info->valueType, 0, nullptr)); + operands.add(builder->emitDefaultConstruct(info->valueType)); operands.add(inst->getErrorValue()); auto makeStruct = builder->emitMakeStruct(info->loweredType, operands); inst->replaceUsesWith(makeStruct); diff --git a/source/slang/slang-ir-marshal-native-call.cpp b/source/slang/slang-ir-marshal-native-call.cpp index 215e6001b..4074a5c67 100644 --- a/source/slang/slang-ir-marshal-native-call.cpp +++ b/source/slang/slang-ir-marshal-native-call.cpp @@ -286,7 +286,7 @@ namespace Slang auto intErr = err; if (err->getDataType()->getOp() != kIROp_IntType) { - intErr = builder.emitConstructorInst(builder.getIntType(), 1, &err); + intErr = builder.emitCast(builder.getIntType(),err); } auto errIsError = builder.emitLess(intErr, builder.getIntValue(builder.getIntType(), 0)); IRBlock *trueBlock, *falseBlock, *afterBlock; diff --git a/source/slang/slang-ir-peephole.cpp b/source/slang/slang-ir-peephole.cpp index a39f50dca..eb2eadb83 100644 --- a/source/slang/slang-ir-peephole.cpp +++ b/source/slang/slang-ir-peephole.cpp @@ -223,6 +223,19 @@ struct PeepholeContext : InstPassBase } } break; + case kIROp_DefaultConstruct: + { + IRBuilder builder(&sharedBuilderStorage); + builder.setInsertBefore(inst); + // See if we can replace the default construct inst with concrete values. + if (auto newCtor = builder.emitDefaultConstruct(inst->getFullType(), false)) + { + inst->replaceUsesWith(newCtor); + inst->removeAndDeallocate(); + changed = true; + } + } + break; default: break; } diff --git a/source/slang/slang-ir-specialize-dispatch.cpp b/source/slang/slang-ir-specialize-dispatch.cpp index 88e2497be..21ba1dee6 100644 --- a/source/slang/slang-ir-specialize-dispatch.cpp +++ b/source/slang/slang-ir-specialize-dispatch.cpp @@ -157,7 +157,7 @@ IRFunc* specializeDispatchFunction(SharedGenericsLoweringContext* sharedContext, } else { - auto defaultValue = builder->emitConstructorInst(callInst->getDataType(), 0, nullptr); + auto defaultValue = builder->emitDefaultConstruct(callInst->getDataType()); builder->emitReturn(defaultValue); } } 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: diff --git a/source/slang/slang-stdlib.cpp b/source/slang/slang-stdlib.cpp index 352d4ee27..17fb3d28b 100644 --- a/source/slang/slang-stdlib.cpp +++ b/source/slang/slang-stdlib.cpp @@ -198,9 +198,9 @@ namespace Slang BaseTypeConversionInfo const& fromInfo) { if (toInfo.tag == fromInfo.tag) - return (IROp)0; + return kIROp_Nop; - IROp intrinsicOpCode = (IROp)0; + IROp intrinsicOpCode = kIROp_Nop; auto toStyle = getTypeStyle(toInfo.tag); auto fromStyle = getTypeStyle(fromInfo.tag); if (toStyle == kIROp_BoolType) toStyle = kIROp_IntType; |
