summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-emit-cpp.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2020-03-11 08:50:38 -0700
committerGitHub <noreply@github.com>2020-03-11 08:50:38 -0700
commit935768c6a00c258bf5122a2d04b84064a1eee67d (patch)
tree68dac944da274a21acb8c8bf651401c26e289f4c /source/slang/slang-emit-cpp.cpp
parentb380b1af6ba6f5f58e3841c2a5b14db7ee8c372d (diff)
Clean-ups related to expanded standard library coverage (#1269)
This change continues the work already started in moving the definitions of many built-in functions to the standard library. The main focus in this change was reducing the number of operations that had to be special-cased on the CPU and CUDA targets by making sure that the scalar cases of built-in functions map to the proper names in the prelude (e.g., `F32_sin()`) via the ordinary `__target_intrinsic` mechanism. In some cases this cleanup meant that special-case logic that was constructing definitions for those functions using C++ code could be scrapped. Additional changes made along the way: * A few scalar functions that were missing in the CPU/CUDA preludes got added: `round`, hyperbolic trigonometric functions, `frexp`, `modf`, and `fma` * The floating-point `min()` and `max()` definitions in the preludes were changed to use intrinsic operations on the target (which are likely to follow IEEE semantics, while our definitions did not) * For the CUDA target, many of the functions had their names translated during code emit from, e.g., `sin` to `sinf`. This change makes the CUDA target more closely match the C++/CPU target in using names like `F32_sin` consistently. * For the CUDA target, a few additional functions have intrinsics that don't exist (portably) on CPU: `sincos()` and `rsqrt()`. * For the Slang stdlib definitions to work, a new `$P` replacement was defined for `__targert_intrinsic` that expands to a type based on the first operand of the function (e.g., `F32` for `float`). * I removed the dedicated opcodes for matrix-matrix, matrix-vector, and vector-matrix multiplication, and instead turned them into ordinary functions with definitions and `__target_intrinsic` modifiers to map them appropriately for HLSL and GLSL. This is realistically how we would have implemented these if we'd had `__target_intrinsic` from the start. Notes about possible follow-on work: * The `ldexp` function is still left in the Slang stdlib because it has to account for a floating-point exponent and the `math.h` version only handles integers for the exponent. It is possible that we can/should define another overload for `ldexp` (and `frexp`) that uses an integer for exponent, and then have that one be a built-in on CPU/CUDA, with the HLSL `frexp` being defined in the stdlib to delegate to the correct `frexp` for those targets. * The `firstbithigh` and related functions are missing for our CPU and CUDA targets, and will need to be added. It is worth nothing that `firstbithigh` apparently has some very odd functionality around signed integer arguments (which are supported, despite MSDN being unclear on that point). General cleanup will be required for those functions. * Maxing the various matrix and vector products no longer be intrinsic ops might affect how we emit code for them as sub-expressions (both whether we fold them into use sites and how we parenthize them). This doesn't seem to affect any of our existing tests, but we could consider marking these functions with `[__readNone]` to ensure they can be folded, and then also adding whatever modifier(s) we might invent to control precdence and parentheses insertion during emit.
Diffstat (limited to 'source/slang/slang-emit-cpp.cpp')
-rw-r--r--source/slang/slang-emit-cpp.cpp176
1 files changed, 0 insertions, 176 deletions
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index 7fb04c33b..bece6c2d0 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -901,56 +901,6 @@ void CPPSourceEmitter::_emitSignature(const UnownedStringSlice& funcName, const
writer->emit(")");
}
-void CPPSourceEmitter::_emitVecMatMulDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
-{
- IRFuncType* funcType = specOp->signatureType;
- SLANG_ASSERT(funcType->getParamCount() == 2);
- IRType* paramType0 = funcType->getParamType(0);
- IRType* paramType1 = funcType->getParamType(1);
- IRType* retType = specOp->returnType;
-
- SourceWriter* writer = getSourceWriter();
-
- _emitSignature(funcName, specOp);
-
- writer->emit("\n{\n");
- writer->indent();
-
- emitType(retType);
- writer->emit(" r;\n");
-
- TypeDimension dimA = _getTypeDimension(paramType0, false);
- TypeDimension dimB = _getTypeDimension(paramType1, true);
- TypeDimension resultDim = _getTypeDimension(retType, paramType1->op == kIROp_VectorType);
-
- for (int i = 0; i < resultDim.rowCount; ++i)
- {
- for (int j = 0; j < resultDim.colCount; ++j)
- {
- _emitAccess(UnownedStringSlice::fromLiteral("r"), resultDim, i, j, writer);
- writer->emit(" = ");
-
- for (int k = 0; k < dimA.colCount; k++)
- {
- if (k > 0)
- {
- writer->emit(" + ");
- }
- _emitAccess(UnownedStringSlice::fromLiteral("a"), dimA, i, k, writer);
- writer->emit(" * ");
- _emitAccess(UnownedStringSlice::fromLiteral("b"), dimB, k, j, writer);
- }
-
- writer->emit(";\n");
- }
- }
-
- writer->emit("return r;\n");
-
- writer->dedent();
- writer->emit("}\n\n");
-}
-
UnownedStringSlice CPPSourceEmitter::_getAndEmitSpecializedOperationDefinition(HLSLIntrinsic::Op op, IRType*const* argTypes, Int argCount, IRType* retType)
{
HLSLIntrinsic intrinsic;
@@ -960,38 +910,6 @@ UnownedStringSlice CPPSourceEmitter::_getAndEmitSpecializedOperationDefinition(H
return _getFuncName(specOp);
}
-void CPPSourceEmitter::_emitLengthDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
-{
- SourceWriter* writer = getSourceWriter();
-
- IRFuncType* funcType = specOp->signatureType;
- SLANG_ASSERT(funcType->getParamCount() == 1);
- IRType* paramType0 = funcType->getParamType(0);
-
- SLANG_ASSERT(paramType0->op == kIROp_VectorType);
-
- IRBasicType* elementType = as<IRBasicType>(static_cast<IRVectorType*>(paramType0)->getElementType());
-
- IRType* dotArgs[] = { paramType0, paramType0 };
- UnownedStringSlice dotFuncName = _getAndEmitSpecializedOperationDefinition(HLSLIntrinsic::Op::Dot, dotArgs, SLANG_COUNT_OF(dotArgs), elementType);
-
- UnownedStringSlice sqrtName = _getScalarFuncName(HLSLIntrinsic::Op::Sqrt, elementType);
-
- _emitSignature(funcName, specOp);
-
- writer->emit("\n{\n");
- writer->indent();
-
- writer->emit("return ");
- writer->emit(sqrtName);
- writer->emit("(");
- writer->emit(dotFuncName);
- writer->emit("(a, a));\n");
-
- writer->dedent();
- writer->emit("}\n\n");
-}
-
void CPPSourceEmitter::_emitGetAtDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
{
SourceWriter* writer = getSourceWriter();
@@ -1049,47 +967,6 @@ void CPPSourceEmitter::_emitGetAtDefinition(const UnownedStringSlice& funcName,
}
}
-void CPPSourceEmitter::_emitNormalizeDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
-{
- SourceWriter* writer = getSourceWriter();
-
- IRFuncType* funcType = specOp->signatureType;
- SLANG_ASSERT(funcType->getParamCount() == 1);
- IRType* paramType0 = funcType->getParamType(0);
-
- SLANG_ASSERT(paramType0->op == kIROp_VectorType);
-
- IRBasicType* elementType = as<IRBasicType>(static_cast<IRVectorType*>(paramType0)->getElementType());
-
- IRType* dotArgs[] = { paramType0, paramType0 };
- 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(HLSLIntrinsic::Op::Mul, vecMulScalarArgs, SLANG_COUNT_OF(vecMulScalarArgs), paramType0);
-
- TypeDimension dimA = _getTypeDimension(paramType0, false);
-
- // Assumes C++
-
- _emitSignature(funcName, specOp);
-
- writer->emit("\n{\n");
- writer->indent();
-
- writer->emit("return ");
-
- // Assumes C++ here
- writer->emit("a * ");
- writer->emit(rsqrtName);
- writer->emit("(");
- writer->emit(dotFuncName);
- writer->emit("(a, a));\n");
-
- writer->dedent();
- writer->emit("}\n\n");
-}
-
-
void CPPSourceEmitter::_emitConstructConvertDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
{
SourceWriter* writer = getSourceWriter();
@@ -1329,42 +1206,6 @@ void CPPSourceEmitter::_emitConstructFromScalarDefinition(const UnownedStringSli
writer->emit("}\n\n");
}
-void CPPSourceEmitter::_emitReflectDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp)
-{
- SourceWriter* writer = getSourceWriter();
-
- IRFuncType* funcType = specOp->signatureType;
- SLANG_ASSERT(funcType->getParamCount() == 2);
- IRType* paramType0 = funcType->getParamType(0);
-
- SLANG_ASSERT(paramType0->op == kIROp_VectorType);
-
- IRBasicType* elementType = as<IRBasicType>(static_cast<IRVectorType*>(paramType0)->getElementType());
-
- // Make sure we have all these functions defined before emitting
- IRType* dotArgs[] = { paramType0, paramType0 };
- UnownedStringSlice dotFuncName = _getAndEmitSpecializedOperationDefinition(HLSLIntrinsic::Op::Dot, dotArgs, SLANG_COUNT_OF(dotArgs), elementType);
-
- IRType* subArgs[] = { paramType0, paramType0};
- UnownedStringSlice subFuncName = _getAndEmitSpecializedOperationDefinition(HLSLIntrinsic::Op::Sub, subArgs, SLANG_COUNT_OF(subArgs), paramType0);
-
- IRType* vecMulScalarArgs[] = { paramType0, elementType };
- UnownedStringSlice vecMulScalarFuncName = _getAndEmitSpecializedOperationDefinition(HLSLIntrinsic::Op::Mul, vecMulScalarArgs, SLANG_COUNT_OF(vecMulScalarArgs), paramType0);
-
- // Assumes C++
-
- _emitSignature(funcName, specOp);
- writer->emit("\n{\n");
- writer->indent();
-
- writer->emit("return a - b * 2.0 * ");
- writer->emit(dotFuncName);
- writer->emit("(a, b);\n");
-
- writer->dedent();
- writer->emit("}\n\n");
-}
-
void CPPSourceEmitter::_maybeEmitSpecializedOperationDefinition(const HLSLIntrinsic* specOp)
{
// Check if it's been emitted already, if not add it.
@@ -1385,28 +1226,11 @@ void CPPSourceEmitter::emitSpecializedOperationDefinition(const HLSLIntrinsic* s
{
return _emitInitDefinition(_getFuncName(specOp), specOp);
}
- case Op::VecMatMul:
- case Op::Dot:
- {
- return _emitVecMatMulDefinition(_getFuncName(specOp), specOp);
- }
case Op::Any:
case Op::All:
{
return _emitAnyAllDefinition(_getFuncName(specOp), specOp);
}
- case Op::Normalize:
- {
- return _emitNormalizeDefinition(_getFuncName(specOp), specOp);
- }
- case Op::Length:
- {
- return _emitLengthDefinition(_getFuncName(specOp), specOp);
- }
- case Op::Reflect:
- {
- return _emitReflectDefinition(_getFuncName(specOp), specOp);
- }
case Op::ConstructConvert:
{
return _emitConstructConvertDefinition(_getFuncName(specOp), specOp);