summaryrefslogtreecommitdiffstats
path: root/source
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
parent3a3a8b5f7701109fc413f42692c4de5769870489 (diff)
Remove `construct` IR op. (#2555)
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source')
-rw-r--r--source/slang/core.meta.slang2
-rw-r--r--source/slang/slang-emit-c-like.cpp4
-rw-r--r--source/slang/slang-emit-cuda.cpp36
-rw-r--r--source/slang/slang-emit-hlsl.cpp1
-rw-r--r--source/slang/slang-emit-spirv.cpp4
-rw-r--r--source/slang/slang-hlsl-intrinsic-set.cpp4
-rw-r--r--source/slang/slang-ir-any-value-marshalling.cpp8
-rw-r--r--source/slang/slang-ir-autodiff-fwd.cpp3
-rw-r--r--source/slang/slang-ir-constexpr.cpp3
-rw-r--r--source/slang/slang-ir-glsl-legalize.cpp21
-rw-r--r--source/slang/slang-ir-hoist-constants.cpp27
-rw-r--r--source/slang/slang-ir-inline.cpp2
-rw-r--r--source/slang/slang-ir-inst-defs.h5
-rw-r--r--source/slang/slang-ir-insts.h14
-rw-r--r--source/slang/slang-ir-legalize-types.cpp17
-rw-r--r--source/slang/slang-ir-liveness.cpp4
-rw-r--r--source/slang/slang-ir-lower-result-type.cpp2
-rw-r--r--source/slang/slang-ir-marshal-native-call.cpp2
-rw-r--r--source/slang/slang-ir-peephole.cpp13
-rw-r--r--source/slang/slang-ir-specialize-dispatch.cpp2
-rw-r--r--source/slang/slang-ir.cpp254
-rw-r--r--source/slang/slang-stdlib.cpp4
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;