summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-emit-cpp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-emit-cpp.cpp')
-rw-r--r--source/slang/slang-emit-cpp.cpp498
1 files changed, 142 insertions, 356 deletions
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index 46eeee5bd..0d5d1d293 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -168,12 +168,6 @@ static UnownedStringSlice _getCTypeVecPostFix(IROp op)
/* !!!!!!!!!!!!!!!!!!!!!!!! CPPEmitHandler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-static const CPPSourceEmitter::OperationInfo s_operationInfos[] =
-{
-#define SLANG_CPP_INTRINSIC_OP_INFO(x, funcName, numOperands) { UnownedStringSlice::fromLiteral(#x), UnownedStringSlice::fromLiteral(funcName), int8_t(numOperands) },
- SLANG_CPP_INTRINSIC_OP(SLANG_CPP_INTRINSIC_OP_INFO)
-};
-
/* static */ UnownedStringSlice CPPSourceEmitter::getBuiltinTypeName(IROp op)
{
switch (op)
@@ -201,62 +195,6 @@ static const CPPSourceEmitter::OperationInfo s_operationInfos[] =
}
}
-
-/* static */const CPPSourceEmitter::OperationInfo& CPPSourceEmitter::getOperationInfo(IntrinsicOp op)
-{
- return s_operationInfos[int(op)];
-}
-
-/* static */CPPSourceEmitter::IntrinsicOp CPPSourceEmitter::getOperation(IROp op)
-{
- switch (op)
- {
- case kIROp_Add: return IntrinsicOp::Add;
- case kIROp_Mul: return IntrinsicOp::Mul;
- case kIROp_Sub: return IntrinsicOp::Sub;
- case kIROp_Div: return IntrinsicOp::Div;
- case kIROp_Lsh: return IntrinsicOp::Lsh;
- case kIROp_Rsh: return IntrinsicOp::Rsh;
- case kIROp_IRem: return IntrinsicOp::IRem;
- case kIROp_FRem: return IntrinsicOp::FRem;
-
- case kIROp_Eql: return IntrinsicOp::Eql;
- case kIROp_Neq: return IntrinsicOp::Neq;
- case kIROp_Greater: return IntrinsicOp::Greater;
- case kIROp_Less: return IntrinsicOp::Less;
- case kIROp_Geq: return IntrinsicOp::Geq;
- case kIROp_Leq: return IntrinsicOp::Leq;
-
- case kIROp_BitAnd: return IntrinsicOp::BitAnd;
- case kIROp_BitXor: return IntrinsicOp::BitXor;
- case kIROp_BitOr: return IntrinsicOp::BitOr;
-
- case kIROp_And: return IntrinsicOp::And;
- case kIROp_Or: return IntrinsicOp::Or;
-
- case kIROp_Neg: return IntrinsicOp::Neg;
- case kIROp_Not: return IntrinsicOp::Not;
- case kIROp_BitNot: return IntrinsicOp::BitNot;
-
- default: return IntrinsicOp::Invalid;
- }
-}
-
-CPPSourceEmitter::IntrinsicOp CPPSourceEmitter::getOperationByName(const UnownedStringSlice& slice)
-{
- Index index = m_slicePool.findIndex(slice);
- if (index >= 0 && index < m_intrinsicOpMap.getCount())
- {
- IntrinsicOp op = m_intrinsicOpMap[index];
- if (op != IntrinsicOp::Invalid)
- {
- return op;
- }
- }
-
- return IntrinsicOp::Invalid;
-}
-
void CPPSourceEmitter::emitTypeDefinition(IRType* inType)
{
if (m_target == CodeGenTarget::CPPSource)
@@ -704,9 +642,9 @@ static bool _isOperator(const UnownedStringSlice& funcName)
return false;
}
-void CPPSourceEmitter::_emitAryDefinition(const SpecializedIntrinsic& specOp)
+void CPPSourceEmitter::_emitAryDefinition(const HLSLIntrinsic* specOp)
{
- auto info = getOperationInfo(specOp.op);
+ auto info = HLSLIntrinsic::getInfo(specOp->op);
auto funcName = info.funcName;
SLANG_ASSERT(funcName.size() > 0);
@@ -714,7 +652,7 @@ void CPPSourceEmitter::_emitAryDefinition(const SpecializedIntrinsic& specOp)
SourceWriter* writer = getSourceWriter();
- IRFuncType* funcType = specOp.signatureType;
+ IRFuncType* funcType = specOp->signatureType;
const int numParams = int(funcType->getParamCount());
SLANG_ASSERT(numParams <= 3);
@@ -732,7 +670,7 @@ void CPPSourceEmitter::_emitAryDefinition(const SpecializedIntrinsic& specOp)
return;
}
- IRType* retType = specOp.returnType;
+ IRType* retType = specOp->returnType;
TypeDimension retDim = _getTypeDimension(retType, false);
UnownedStringSlice scalarFuncName(funcName);
@@ -745,7 +683,7 @@ void CPPSourceEmitter::_emitAryDefinition(const SpecializedIntrinsic& specOp)
}
else
{
- scalarFuncName = _getScalarFuncName(specOp.op, _getElementType(funcType->getParamType(0)));
+ scalarFuncName = _getScalarFuncName(specOp->op, _getElementType(funcType->getParamType(0)));
_emitSignature(funcName, specOp);
}
@@ -808,9 +746,9 @@ void CPPSourceEmitter::_emitAryDefinition(const SpecializedIntrinsic& specOp)
writer->emit("}\n\n");
}
-void CPPSourceEmitter::_emitAnyAllDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp)
+void CPPSourceEmitter::_emitAnyAllDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
{
- IRFuncType* funcType = specOp.signatureType;
+ IRFuncType* funcType = specOp->signatureType;
SLANG_ASSERT(funcType->getParamCount() == 1);
IRType* paramType0 = funcType->getParamType(0);
@@ -818,7 +756,7 @@ void CPPSourceEmitter::_emitAnyAllDefinition(const UnownedStringSlice& funcName,
IRType* elementType = _getElementType(paramType0);
SLANG_ASSERT(elementType);
- IRType* retType = specOp.returnType;
+ IRType* retType = specOp->returnType;
auto retTypeName = _getTypeName(retType);
IROp style = _getTypeStyle(elementType->op);
@@ -837,7 +775,7 @@ void CPPSourceEmitter::_emitAnyAllDefinition(const UnownedStringSlice& funcName,
{
if (i > 0 || j > 0)
{
- if (specOp.op == IntrinsicOp::All)
+ if (specOp->op == HLSLIntrinsic::Op::All)
{
writer->emit(" && ");
}
@@ -878,11 +816,11 @@ void CPPSourceEmitter::_emitAnyAllDefinition(const UnownedStringSlice& funcName,
writer->emit("}\n\n");
}
-void CPPSourceEmitter::_emitSignature(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp)
+void CPPSourceEmitter::_emitSignature(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
{
- IRFuncType* funcType = specOp.signatureType;
+ IRFuncType* funcType = specOp->signatureType;
const int paramsCount = int(funcType->getParamCount());
- IRType* retType = specOp.returnType;
+ IRType* retType = specOp->returnType;
SourceWriter* writer = getSourceWriter();
@@ -924,13 +862,13 @@ void CPPSourceEmitter::_emitSignature(const UnownedStringSlice& funcName, const
writer->emit(")");
}
-void CPPSourceEmitter::_emitVecMatMulDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp)
+void CPPSourceEmitter::_emitVecMatMulDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
{
- IRFuncType* funcType = specOp.signatureType;
+ IRFuncType* funcType = specOp->signatureType;
SLANG_ASSERT(funcType->getParamCount() == 2);
IRType* paramType0 = funcType->getParamType(0);
IRType* paramType1 = funcType->getParamType(1);
- IRType* retType = specOp.returnType;
+ IRType* retType = specOp->returnType;
SourceWriter* writer = getSourceWriter();
@@ -974,7 +912,7 @@ void CPPSourceEmitter::_emitVecMatMulDefinition(const UnownedStringSlice& funcNa
writer->emit("}\n\n");
}
-void CPPSourceEmitter::_emitCrossDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp)
+void CPPSourceEmitter::_emitCrossDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
{
_emitSignature(funcName, specOp);
@@ -984,32 +922,27 @@ void CPPSourceEmitter::_emitCrossDefinition(const UnownedStringSlice& funcName,
writer->indent();
writer->emit("return ");
- emitType(specOp.returnType);
+ emitType(specOp->returnType);
writer->emit("{ a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x }; \n");
writer->dedent();
writer->emit("}\n\n");
}
-UnownedStringSlice CPPSourceEmitter::_getAndEmitSpecializedOperationDefinition(IntrinsicOp op, IRType*const* argTypes, Int argCount, IRType* retType)
+UnownedStringSlice CPPSourceEmitter::_getAndEmitSpecializedOperationDefinition(HLSLIntrinsic::Op op, IRType*const* argTypes, Int argCount, IRType* retType)
{
- // Use the type sets builder...
- IRBuilder& builder = m_typeSet.getBuilder();
-
- SpecializedIntrinsic specOp;
- specOp.op = op;
- specOp.returnType = retType;
- specOp.signatureType = builder.getFuncType(argCount, argTypes, builder.getVoidType());
-
+ HLSLIntrinsic intrinsic;
+ m_intrinsicSet.calcIntrinsic(op, retType, argTypes, argCount, intrinsic);
+ auto specOp = m_intrinsicSet.add(intrinsic);
emitSpecializedOperationDefinition(specOp);
return _getFuncName(specOp);
}
-void CPPSourceEmitter::_emitLengthDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp)
+void CPPSourceEmitter::_emitLengthDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
{
SourceWriter* writer = getSourceWriter();
- IRFuncType* funcType = specOp.signatureType;
+ IRFuncType* funcType = specOp->signatureType;
SLANG_ASSERT(funcType->getParamCount() == 1);
IRType* paramType0 = funcType->getParamType(0);
@@ -1018,9 +951,9 @@ void CPPSourceEmitter::_emitLengthDefinition(const UnownedStringSlice& funcName,
IRBasicType* elementType = as<IRBasicType>(static_cast<IRVectorType*>(paramType0)->getElementType());
IRType* dotArgs[] = { paramType0, paramType0 };
- UnownedStringSlice dotFuncName = _getAndEmitSpecializedOperationDefinition(IntrinsicOp::Dot, dotArgs, SLANG_COUNT_OF(dotArgs), elementType);
+ UnownedStringSlice dotFuncName = _getAndEmitSpecializedOperationDefinition(HLSLIntrinsic::Op::Dot, dotArgs, SLANG_COUNT_OF(dotArgs), elementType);
- UnownedStringSlice sqrtName = _getScalarFuncName(IntrinsicOp::Sqrt, elementType);
+ UnownedStringSlice sqrtName = _getScalarFuncName(HLSLIntrinsic::Op::Sqrt, elementType);
_emitSignature(funcName, specOp);
@@ -1037,16 +970,16 @@ void CPPSourceEmitter::_emitLengthDefinition(const UnownedStringSlice& funcName,
writer->emit("}\n\n");
}
-void CPPSourceEmitter::_emitGetAtDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp)
+void CPPSourceEmitter::_emitGetAtDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
{
SourceWriter* writer = getSourceWriter();
- IRFuncType* funcType = specOp.signatureType;
+ IRFuncType* funcType = specOp->signatureType;
SLANG_ASSERT(funcType->getParamCount() == 2);
IRType* srcType = funcType->getParamType(0);
- IRType* retType = specOp.returnType;
+ IRType* retType = specOp->returnType;
emitType(retType);
m_writer->emit("& ");
@@ -1073,11 +1006,11 @@ void CPPSourceEmitter::_emitGetAtDefinition(const UnownedStringSlice& funcName,
writer->emit("}\n\n");
}
-void CPPSourceEmitter::_emitNormalizeDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp)
+void CPPSourceEmitter::_emitNormalizeDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
{
SourceWriter* writer = getSourceWriter();
- IRFuncType* funcType = specOp.signatureType;
+ IRFuncType* funcType = specOp->signatureType;
SLANG_ASSERT(funcType->getParamCount() == 1);
IRType* paramType0 = funcType->getParamType(0);
@@ -1086,10 +1019,10 @@ void CPPSourceEmitter::_emitNormalizeDefinition(const UnownedStringSlice& funcNa
IRBasicType* elementType = as<IRBasicType>(static_cast<IRVectorType*>(paramType0)->getElementType());
IRType* dotArgs[] = { paramType0, paramType0 };
- UnownedStringSlice dotFuncName = _getAndEmitSpecializedOperationDefinition(IntrinsicOp::Dot, dotArgs, SLANG_COUNT_OF(dotArgs), elementType);
- UnownedStringSlice rsqrtName = _getScalarFuncName(IntrinsicOp::RecipSqrt, elementType);
+ UnownedStringSlice dotFuncName = _getAndEmitSpecializedOperationDefinition(HLSLIntrinsic::Op::Dot, dotArgs, SLANG_COUNT_OF(dotArgs), elementType);
+ UnownedStringSlice rsqrtName = _getScalarFuncName(HLSLIntrinsic::Op::RecipSqrt, elementType);
IRType* vecMulScalarArgs[] = { paramType0, elementType };
- UnownedStringSlice vecMulScalarName = _getAndEmitSpecializedOperationDefinition(IntrinsicOp::Mul, vecMulScalarArgs, SLANG_COUNT_OF(vecMulScalarArgs), paramType0);
+ UnownedStringSlice vecMulScalarName = _getAndEmitSpecializedOperationDefinition(HLSLIntrinsic::Op::Mul, vecMulScalarArgs, SLANG_COUNT_OF(vecMulScalarArgs), paramType0);
TypeDimension dimA = _getTypeDimension(paramType0, false);
@@ -1113,15 +1046,15 @@ void CPPSourceEmitter::_emitNormalizeDefinition(const UnownedStringSlice& funcNa
writer->emit("}\n\n");
}
-void CPPSourceEmitter::_emitConstructConvertDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp)
+void CPPSourceEmitter::_emitConstructConvertDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
{
SourceWriter* writer = getSourceWriter();
- IRFuncType* funcType = specOp.signatureType;
+ IRFuncType* funcType = specOp->signatureType;
SLANG_ASSERT(funcType->getParamCount() == 2);
IRType* srcType = funcType->getParamType(1);
- IRType* retType = specOp.returnType;
+ IRType* retType = specOp->returnType;
emitType(retType);
writer->emit(" ");
@@ -1179,15 +1112,15 @@ void CPPSourceEmitter::_emitConstructConvertDefinition(const UnownedStringSlice&
writer->emit("}\n\n");
}
-void CPPSourceEmitter::_emitConstructFromScalarDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp)
+void CPPSourceEmitter::_emitConstructFromScalarDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
{
SourceWriter* writer = getSourceWriter();
- IRFuncType* funcType = specOp.signatureType;
+ IRFuncType* funcType = specOp->signatureType;
SLANG_ASSERT(funcType->getParamCount() == 2);
IRType* srcType = funcType->getParamType(1);
- IRType* retType = specOp.returnType;
+ IRType* retType = specOp->returnType;
emitType(retType);
writer->emit(" ");
@@ -1237,11 +1170,11 @@ void CPPSourceEmitter::_emitConstructFromScalarDefinition(const UnownedStringSli
writer->emit("}\n\n");
}
-void CPPSourceEmitter::_emitReflectDefinition(const UnownedStringSlice& funcName, const SpecializedIntrinsic& specOp)
+void CPPSourceEmitter::_emitReflectDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
{
SourceWriter* writer = getSourceWriter();
- IRFuncType* funcType = specOp.signatureType;
+ IRFuncType* funcType = specOp->signatureType;
SLANG_ASSERT(funcType->getParamCount() == 2);
IRType* paramType0 = funcType->getParamType(0);
@@ -1249,15 +1182,15 @@ void CPPSourceEmitter::_emitReflectDefinition(const UnownedStringSlice& funcName
IRBasicType* elementType = as<IRBasicType>(static_cast<IRVectorType*>(paramType0)->getElementType());
- // Make sure we have all these functions defined before emtting
+ // Make sure we have all these functions defined before emitting
IRType* dotArgs[] = { paramType0, paramType0 };
- UnownedStringSlice dotFuncName = _getAndEmitSpecializedOperationDefinition(IntrinsicOp::Dot, dotArgs, SLANG_COUNT_OF(dotArgs), elementType);
+ UnownedStringSlice dotFuncName = _getAndEmitSpecializedOperationDefinition(HLSLIntrinsic::Op::Dot, dotArgs, SLANG_COUNT_OF(dotArgs), elementType);
IRType* subArgs[] = { paramType0, paramType0};
- UnownedStringSlice subFuncName = _getAndEmitSpecializedOperationDefinition(IntrinsicOp::Sub, subArgs, SLANG_COUNT_OF(subArgs), paramType0);
+ UnownedStringSlice subFuncName = _getAndEmitSpecializedOperationDefinition(HLSLIntrinsic::Op::Sub, subArgs, SLANG_COUNT_OF(subArgs), paramType0);
IRType* vecMulScalarArgs[] = { paramType0, elementType };
- UnownedStringSlice vecMulScalarFuncName = _getAndEmitSpecializedOperationDefinition(IntrinsicOp::Mul, vecMulScalarArgs, SLANG_COUNT_OF(vecMulScalarArgs), paramType0);
+ UnownedStringSlice vecMulScalarFuncName = _getAndEmitSpecializedOperationDefinition(HLSLIntrinsic::Op::Mul, vecMulScalarArgs, SLANG_COUNT_OF(vecMulScalarArgs), paramType0);
// Assumes C++
@@ -1273,58 +1206,60 @@ void CPPSourceEmitter::_emitReflectDefinition(const UnownedStringSlice& funcName
writer->emit("}\n\n");
}
-void CPPSourceEmitter::emitSpecializedOperationDefinition(const SpecializedIntrinsic& specOp)
+void CPPSourceEmitter::emitSpecializedOperationDefinition(const HLSLIntrinsic* specOp)
{
+ typedef HLSLIntrinsic::Op Op;
+
// Check if it's been emitted already, if not add it.
if (!m_intrinsicEmittedMap.AddIfNotExists(specOp, true))
{
return;
}
- switch (specOp.op)
+ switch (specOp->op)
{
- case IntrinsicOp::VecMatMul:
- case IntrinsicOp::Dot:
+ case Op::VecMatMul:
+ case Op::Dot:
{
return _emitVecMatMulDefinition(_getFuncName(specOp), specOp);
}
- case IntrinsicOp::Any:
- case IntrinsicOp::All:
+ case Op::Any:
+ case Op::All:
{
return _emitAnyAllDefinition(_getFuncName(specOp), specOp);
}
- case IntrinsicOp::Cross:
+ case Op::Cross:
{
return _emitCrossDefinition(_getFuncName(specOp), specOp);
}
- case IntrinsicOp::Normalize:
+ case Op::Normalize:
{
return _emitNormalizeDefinition(_getFuncName(specOp), specOp);
}
- case IntrinsicOp::Length:
+ case Op::Length:
{
return _emitLengthDefinition(_getFuncName(specOp), specOp);
}
- case IntrinsicOp::Reflect:
+ case Op::Reflect:
{
return _emitReflectDefinition(_getFuncName(specOp), specOp);
}
- case IntrinsicOp::ConstructConvert:
+ case Op::ConstructConvert:
{
return _emitConstructConvertDefinition(_getFuncName(specOp), specOp);
}
- case IntrinsicOp::ConstructFromScalar:
+ case Op::ConstructFromScalar:
{
return _emitConstructFromScalarDefinition(_getFuncName(specOp), specOp);
}
- case IntrinsicOp::GetAt:
+ case Op::GetAt:
{
return _emitGetAtDefinition(_getFuncName(specOp), specOp);
}
default:
{
- const auto& info = getOperationInfo(specOp.op);
- const int paramCount = (info.numOperands < 0) ? int(specOp.signatureType->getParamCount()) : info.numOperands;
+ const auto& info = HLSLIntrinsic::getInfo(specOp->op);
+ const int paramCount = (info.numOperands < 0) ? int(specOp->signatureType->getParamCount()) : info.numOperands;
if (paramCount >= 1 && paramCount <= 3)
{
@@ -1337,44 +1272,24 @@ void CPPSourceEmitter::emitSpecializedOperationDefinition(const SpecializedIntri
SLANG_ASSERT(!"Unhandled");
}
-CPPSourceEmitter::SpecializedIntrinsic CPPSourceEmitter::getSpecializedOperation(IntrinsicOp op, IRType*const* inArgTypes, int argTypesCount, IRType* retType)
+void CPPSourceEmitter::emitCall(const HLSLIntrinsic* specOp, IRInst* inst, const IRUse* operands, int numOperands, const EmitOpInfo& inOuterPrec)
{
- SpecializedIntrinsic specOp;
- specOp.op = op;
-
- List<IRType*> argTypes;
- argTypes.setCount(argTypesCount);
-
- for (int i = 0; i < argTypesCount; ++i)
- {
- argTypes[i] = m_typeSet.getType(inArgTypes[i]->getCanonicalType());
- }
-
- specOp.returnType = m_typeSet.getType(retType);
-
- // Use the typesets builder
- IRBuilder& builder = m_typeSet.getBuilder();
- specOp.signatureType = builder.getFuncType(argTypes, builder.getBasicType(BaseType::Void));
-
- return specOp;
-}
+ typedef HLSLIntrinsic::Op Op;
-void CPPSourceEmitter::emitCall(const SpecializedIntrinsic& specOp, IRInst* inst, const IRUse* operands, int numOperands, const EmitOpInfo& inOuterPrec)
-{
SLANG_UNUSED(inOuterPrec);
SourceWriter* writer = getSourceWriter();
// Getting the name means that this op is registered as used
- switch (specOp.op)
+ switch (specOp->op)
{
- case IntrinsicOp::Init:
+ case Op::Init:
{
// For C++ we don't need an init function
// For C we'll need the construct function for the return type
//UnownedStringSlice name = _getFuncName(specOp);
- IRType* retType = specOp.returnType;
+ IRType* retType = specOp->returnType;
switch (retType->op)
{
@@ -1440,7 +1355,7 @@ void CPPSourceEmitter::emitCall(const SpecializedIntrinsic& specOp, IRInst* inst
}
break;
}
- case IntrinsicOp::Swizzle:
+ case Op::Swizzle:
{
// Currently only works for C++ (we use {} constuction) - which means we don't need to generate a function.
// For C we need to generate suitable construction function
@@ -1448,7 +1363,7 @@ void CPPSourceEmitter::emitCall(const SpecializedIntrinsic& specOp, IRInst* inst
const Index elementCount = Index(swizzleInst->getElementCount());
// TODO(JS): Not 100% sure this is correct on the parens handling front
- IRType* retType = specOp.returnType;
+ IRType* retType = specOp->returnType;
emitType(retType);
writer->emit("{");
@@ -1480,16 +1395,30 @@ void CPPSourceEmitter::emitCall(const SpecializedIntrinsic& specOp, IRInst* inst
}
default:
{
- const auto& info = getOperationInfo(specOp.op);
+ const auto& info = HLSLIntrinsic::getInfo(specOp->op);
// Make sure that the return type is available
bool isOperator = _isOperator(info.funcName);
UnownedStringSlice funcName = _getFuncName(specOp);
- useType(specOp.returnType);
+ switch (specOp->op)
+ {
+ case Op::ConstructFromScalar:
+ {
+ // We need to special case, because this may have come from a swizzle from a built in
+ // type, in that case the only parameter we want is the first one
+ numOperands = 1;
+ break;
+ }
+
+ default: break;
+ }
+
// add that we want a function
SLANG_ASSERT(info.numOperands < 0 || numOperands == info.numOperands);
+ useType(specOp->returnType);
+
if (isOperator)
{
// Just do the default output
@@ -1516,19 +1445,19 @@ void CPPSourceEmitter::emitCall(const SpecializedIntrinsic& specOp, IRInst* inst
}
}
-StringSlicePool::Handle CPPSourceEmitter::_calcScalarFuncName(IntrinsicOp op, IRBasicType* type)
+StringSlicePool::Handle CPPSourceEmitter::_calcScalarFuncName(HLSLIntrinsic::Op op, IRBasicType* type)
{
StringBuilder builder;
- builder << _getTypePrefix(type->op) << "_" << getOperationInfo(op).funcName;
+ builder << _getTypePrefix(type->op) << "_" << HLSLIntrinsic::getInfo(op).funcName;
return m_slicePool.add(builder);
}
-UnownedStringSlice CPPSourceEmitter::_getScalarFuncName(IntrinsicOp op, IRBasicType* type)
+UnownedStringSlice CPPSourceEmitter::_getScalarFuncName(HLSLIntrinsic::Op op, IRBasicType* type)
{
return m_slicePool.getSlice(_calcScalarFuncName(op, type));
}
-UnownedStringSlice CPPSourceEmitter::_getFuncName(const SpecializedIntrinsic& specOp)
+UnownedStringSlice CPPSourceEmitter::_getFuncName(const HLSLIntrinsic* specOp)
{
StringSlicePool::Handle handle = StringSlicePool::kNullHandle;
if (m_intrinsicNameMap.TryGetValue(specOp, handle))
@@ -1543,23 +1472,25 @@ UnownedStringSlice CPPSourceEmitter::_getFuncName(const SpecializedIntrinsic& sp
return m_slicePool.getSlice(handle);
}
-StringSlicePool::Handle CPPSourceEmitter::_calcFuncName(const SpecializedIntrinsic& specOp)
+StringSlicePool::Handle CPPSourceEmitter::_calcFuncName(const HLSLIntrinsic* specOp)
{
- if (specOp.isScalar())
+ typedef HLSLIntrinsic::Op Op;
+
+ if (specOp->isScalar())
{
- IRType* paramType = specOp.signatureType->getParamType(0);
+ IRType* paramType = specOp->signatureType->getParamType(0);
IRBasicType* basicType = as<IRBasicType>(paramType);
SLANG_ASSERT(basicType);
- return _calcScalarFuncName(specOp.op, basicType);
+ return _calcScalarFuncName(specOp->op, basicType);
}
else
{
- switch (specOp.op)
+ switch (specOp->op)
{
- case IntrinsicOp::ConstructConvert:
+ case Op::ConstructConvert:
{
// Work out the function name
- IRFuncType* signatureType = specOp.signatureType;
+ IRFuncType* signatureType = specOp->signatureType;
SLANG_ASSERT(signatureType->getParamCount() == 2);
IRType* dstType = signatureType->getParamType(0);
@@ -1574,10 +1505,10 @@ StringSlicePool::Handle CPPSourceEmitter::_calcFuncName(const SpecializedIntrins
}
return m_slicePool.add(builder);
}
- case IntrinsicOp::ConstructFromScalar:
+ case Op::ConstructFromScalar:
{
// Work out the function name
- IRFuncType* signatureType = specOp.signatureType;
+ IRFuncType* signatureType = specOp->signatureType;
SLANG_ASSERT(signatureType->getParamCount() == 2);
IRType* dstType = signatureType->getParamType(0);
@@ -1591,18 +1522,18 @@ StringSlicePool::Handle CPPSourceEmitter::_calcFuncName(const SpecializedIntrins
}
return m_slicePool.add(builder);
}
- case IntrinsicOp::GetAt:
+ case Op::GetAt:
{
return m_slicePool.add(UnownedStringSlice::fromLiteral("getAt"));
}
- case IntrinsicOp::SetAt:
+ case Op::SetAt:
{
return m_slicePool.add(UnownedStringSlice::fromLiteral("setAt"));
}
default: break;
}
- const auto& info = getOperationInfo(specOp.op);
+ const auto& info = HLSLIntrinsic::getInfo(specOp->op);
if (info.funcName.size())
{
if (!_isOperator(info.funcName))
@@ -1614,98 +1545,17 @@ StringSlicePool::Handle CPPSourceEmitter::_calcFuncName(const SpecializedIntrins
}
}
-void CPPSourceEmitter::emitOperationCall(IntrinsicOp op, IRInst* inst, IRUse* operands, int operandCount, IRType* retType, const EmitOpInfo& inOuterPrec)
-{
- switch (op)
- {
- case IntrinsicOp::ConstructFromScalar:
- {
- SLANG_ASSERT(operandCount == 1);
- IRType* dstType = inst->getDataType();
- IRType* srcType = _getElementType(dstType);
- IRType* argTypes[2] = { dstType, srcType };
-
- SpecializedIntrinsic specOp = getSpecializedOperation(op, argTypes, 2, retType);
-
- emitCall(specOp, inst, operands, operandCount, inOuterPrec);
- return;
- }
- case IntrinsicOp::ConstructConvert:
- {
- SLANG_ASSERT(inst->getOperandCount() == 1);
- IRType* argTypes[2] = {inst->getDataType(), inst->getOperand(0)->getDataType() };
-
- SpecializedIntrinsic specOp = getSpecializedOperation(op, argTypes, 2, retType);
-
- IRFuncType* signatureType = specOp.signatureType;
- SLANG_UNUSED(signatureType);
-
- SLANG_ASSERT(signatureType->getParamType(0) != signatureType->getParamType(1));
-
- emitCall(specOp, inst, operands, operandCount, inOuterPrec);
- return;
- }
- default: break;
- }
-
- if (operandCount > 8)
- {
- List<IRType*> argTypes;
- argTypes.setCount(operandCount);
- for (int i = 0; i < operandCount; ++i)
- {
- // Hmm.. I'm assuming here that the operands exactly match the usage (ie no casting)
- argTypes[i] = operands[i].get()->getDataType();
- }
- SpecializedIntrinsic specOp = getSpecializedOperation(op, argTypes.getBuffer(), operandCount, retType);
- emitCall(specOp, inst, operands, operandCount, inOuterPrec);
- }
- else
- {
- IRType* argTypes[8];
- for (int i = 0; i < operandCount; ++i)
- {
- // Hmm.. I'm assuming here that the operands exactly match the usage (ie no casting)
- argTypes[i] = operands[i].get()->getDataType();
- }
- SpecializedIntrinsic specOp = getSpecializedOperation(op, argTypes, operandCount, retType);
- emitCall(specOp, inst, operands, operandCount, inOuterPrec);
- }
-}
-
/* !!!!!!!!!!!!!!!!!!!!!! CPPSourceEmitter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
CPPSourceEmitter::CPPSourceEmitter(const Desc& desc):
Super(desc),
m_slicePool(StringSlicePool::Style::Default),
- m_typeSet(desc.compileRequest->getSession())
+ m_typeSet(desc.compileRequest->getSession()),
+ m_opLookup(new HLSLIntrinsicOpLookup),
+ m_intrinsicSet(&m_typeSet, m_opLookup)
{
m_semanticUsedFlags = 0;
//m_semanticUsedFlags = SemanticUsedFlag::GroupID | SemanticUsedFlag::GroupThreadID | SemanticUsedFlag::DispatchThreadID;
-
- // Add all the operations with names (not ops like -, / etc) to the lookup map
- for (int i = 0; i < SLANG_COUNT_OF(s_operationInfos); ++i)
- {
- const auto& info = s_operationInfos[i];
- UnownedStringSlice slice = info.funcName;
-
- if (slice.size() > 0 && slice[0] >= 'a' && slice[0] <= 'z')
- {
- auto handle = m_slicePool.add(slice);
- Index index = Index(handle);
- // Make sure there is space
- if (index >= m_intrinsicOpMap.getCount())
- {
- Index oldSize = m_intrinsicOpMap.getCount();
- m_intrinsicOpMap.setCount(index + 1);
- for (Index j = oldSize; j < index; j++)
- {
- m_intrinsicOpMap[j] = IntrinsicOp::Invalid;
- }
- }
- m_intrinsicOpMap[index] = IntrinsicOp(i);
- }
- }
}
void CPPSourceEmitter::_emitInOutParamType(IRType* type, String const& name, IRType* valueType)
@@ -1936,6 +1786,8 @@ void CPPSourceEmitter::emitIntrinsicCallExpr(
IRTargetIntrinsicDecoration* targetIntrinsic,
EmitOpInfo const& inOuterPrec)
{
+ typedef HLSLIntrinsic::Op Op;
+
// TODO: Much of this logic duplicates code that is already
// in `CLikeSourceEmitter::emitIntrinsicCallExpr`. The only
// real difference is that when things bottom out on an ordinary
@@ -1994,11 +1846,17 @@ void CPPSourceEmitter::emitIntrinsicCallExpr(
}
else
{
- IntrinsicOp op = getOperationByName(name);
- if (op != IntrinsicOp::Invalid)
+ Op op = m_opLookup->getOpByName(name);
+ if (op != Op::Invalid)
{
IRUse* operands = inst->getOperands() + operandIndex;
- emitOperationCall(op, inst, operands, int(operandCount - operandIndex), inst->getDataType(), inOuterPrec);
+
+ // Work out the intrinsic used
+ HLSLIntrinsic intrinsic;
+ m_intrinsicSet.calcIntrinsic(op, inst->getDataType(), operands, int(operandCount - operandIndex), intrinsic);
+ HLSLIntrinsic* specOp = m_intrinsicSet.add(intrinsic);
+
+ emitCall(specOp, inst, operands, int(operandCount - operandIndex), inOuterPrec);
return;
}
}
@@ -2016,67 +1874,32 @@ void CPPSourceEmitter::emitIntrinsicCallExpr(
maybeCloseParens(needClose);
}
-bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec)
+bool CPPSourceEmitter::_tryEmitInstExprAsIntrinsic(IRInst* inst, const EmitOpInfo& inOuterPrec)
{
- SLANG_UNUSED(inOuterPrec);
-
- switch (inst->op)
+ HLSLIntrinsic* specOp = m_intrinsicSet.add(inst);
+ if (specOp)
{
- case kIROp_constructVectorFromScalar:
+ if (inst->op == kIROp_Call)
{
- SLANG_ASSERT(inst->getOperandCount() == 1);
- IRType* dstType = inst->getDataType();
-
- // Check it's a vector
- SLANG_ASSERT(dstType->op == kIROp_VectorType);
- // Source must be a scalar
- SLANG_ASSERT(as<IRBasicType>(inst->getOperand(0)->getDataType()));
-
- emitOperationCall(IntrinsicOp::ConstructFromScalar, inst, inst->getOperands(), int(inst->getOperandCount()), dstType, inOuterPrec);
- return true;
- }
- case kIROp_Construct:
- {
- IRType* dstType = inst->getDataType();
- IRType* srcType = inst->getOperand(0)->getDataType();
-
- if ((dstType->op == kIROp_VectorType || dstType->op == kIROp_MatrixType) &&
- inst->getOperandCount() == 1)
- {
- if (as<IRBasicType>(srcType))
- {
- emitOperationCall(IntrinsicOp::ConstructFromScalar, inst, inst->getOperands(), int(inst->getOperandCount()), dstType, inOuterPrec);
- }
- else
- {
- SLANG_ASSERT(_getElementType(dstType) != _getElementType(srcType));
- // If it's constructed from a type conversion
- emitOperationCall(IntrinsicOp::ConstructConvert, inst, inst->getOperands(), int(inst->getOperandCount()), dstType, inOuterPrec);
- }
- }
- else
- {
- emitOperationCall(IntrinsicOp::Init, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), inOuterPrec);
- }
- return true;
+ IRCall* call = static_cast<IRCall*>(inst);
+ emitCall(specOp, inst, call->getArgs(), int(call->getArgCount()), inOuterPrec);
}
- case kIROp_makeVector:
- case kIROp_MakeMatrix:
- {
- emitOperationCall(IntrinsicOp::Init, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), inOuterPrec);
- return true;
- }
- case kIROp_Mul_Matrix_Matrix:
- case kIROp_Mul_Matrix_Vector:
- case kIROp_Mul_Vector_Matrix:
+ else
{
- emitOperationCall(IntrinsicOp::VecMatMul, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), inOuterPrec);
- return true;
+ emitCall(specOp, inst, inst->getOperands(), int(inst->getOperandCount()), inOuterPrec);
}
- case kIROp_Dot:
+ return true;
+ }
+ return false;
+}
+
+bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOuterPrec)
+{
+ switch (inst->op)
+ {
+ default:
{
- emitOperationCall(IntrinsicOp::Dot, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), inOuterPrec);
- return true;
+ return _tryEmitInstExprAsIntrinsic(inst, inOuterPrec);
}
case kIROp_swizzle:
{
@@ -2096,11 +1919,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
{
// If the output is a scalar, then could only have been a .x, which we can just ignore the '.x' part
emitOperand(baseInst, inOuterPrec);
- }
- else
- {
- SLANG_ASSERT(dstType->op == kIROp_VectorType);
- emitOperationCall(IntrinsicOp::ConstructFromScalar, inst, inst->getOperands(), 1, dstType, inOuterPrec);
+ return true;
}
}
else
@@ -2110,15 +1929,11 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
{
// If just one thing is extracted then the . syntax will just work
defaultEmitInstExpr(inst, inOuterPrec);
- }
- else
- {
- // Will need to generate a swizzle method
- emitOperationCall(IntrinsicOp::Swizzle, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), inOuterPrec);
+ return true;
}
}
-
- return true;
+ // try doing automatically
+ return _tryEmitInstExprAsIntrinsic(inst, inOuterPrec);
}
case kIROp_Call:
{
@@ -2127,37 +1942,8 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
// Does this function declare any requirements.
handleCallExprDecorationsImpl(funcValue);
- // We want to detect any call to an intrinsic operation,
- // that we can emit it directly without mangling, etc.
- if(auto targetIntrinsic = findTargetIntrinsicDecoration(funcValue))
- {
- emitIntrinsicCallExpr(static_cast<IRCall*>(inst), targetIntrinsic, inOuterPrec);
- return true;
- }
-
- return false;
- }
- case kIROp_getElement:
- case kIROp_getElementPtr:
- {
- IRInst* target = inst->getOperand(0);
- if (target->getDataType()->op == kIROp_VectorType)
- {
- // Specially handle this
- emitOperationCall(IntrinsicOp::GetAt, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), inOuterPrec);
- return true;
- }
- return false;
- }
- default:
- {
- IntrinsicOp op = getOperation(inst->op);
- if (op != IntrinsicOp::Invalid)
- {
- emitOperationCall(op, inst, inst->getOperands(), int(inst->getOperandCount()), inst->getDataType(), inOuterPrec);
- return true;
- }
- return false;
+ // try doing automatically
+ return _tryEmitInstExprAsIntrinsic(inst, inOuterPrec);
}
}
}