summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-emit-cpp.cpp
diff options
context:
space:
mode:
authorEllie Hermaszewska <ellieh@nvidia.com>2024-10-29 14:49:26 +0800
committerGitHub <noreply@github.com>2024-10-29 14:49:26 +0800
commitf65d756bff8d4c5cbc15bd0322a2ae8e6b896a21 (patch)
treeea1d61342cd29368e19135000ec2948813096205 /source/slang/slang-emit-cpp.cpp
parenta729c15e9dce9f5116a38afc66329ab2ca4cea54 (diff)
format
* format * Minor test fixes * enable checking cpp format in ci
Diffstat (limited to 'source/slang/slang-emit-cpp.cpp')
-rw-r--r--source/slang/slang-emit-cpp.cpp761
1 files changed, 402 insertions, 359 deletions
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index 19dc05dcf..63c7dd9a4 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -1,15 +1,13 @@
// slang-emit-cpp.cpp
#include "slang-emit-cpp.h"
-#include "../core/slang-writer.h"
+#include "../compiler-core/slang-artifact-desc-util.h"
#include "../core/slang-token-reader.h"
+#include "../core/slang-writer.h"
#include "slang-emit-source-writer.h"
-#include "slang-mangled-lexer.h"
-
#include "slang-ir-clone.h"
#include "slang-ir-util.h"
-
-#include "../compiler-core/slang-artifact-desc-util.h"
+#include "slang-mangled-lexer.h"
#include <assert.h>
@@ -17,8 +15,8 @@
ABI
---
-In terms of ABI we need to discuss the variety of variables/resources that need to be defined by the host for appropriate execution
-of the output code.
+In terms of ABI we need to discuss the variety of variables/resources that need to be defined by the
+host for appropriate execution of the output code.
https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-variable-syntax
@@ -26,22 +24,23 @@ Broadly we could categorize these as..
1) Varying entry point parameters (or 'varying')
2) Uniform entry point parameters
-3) Uniform globals
+3) Uniform globals
4) Thread shared (such as group shared) or ('thread shared')
5) Thread local ('static')
-If we can invoke a bunch of threads as a single invocation we could effectively have the ThreadShared not part of the ABI, but something
-that is say allocated on the stack before the threads are kicked off. If we kick of threads individually then we would need to pass this
-in as part of ABI. NOTE that it isn't right in so far as memory barriers etc couldn't work, as each thread would run to completion, but
-we aren't going to worry about barriers for now.
+If we can invoke a bunch of threads as a single invocation we could effectively have the
+ThreadShared not part of the ABI, but something that is say allocated on the stack before the
+threads are kicked off. If we kick of threads individually then we would need to pass this in as
+part of ABI. NOTE that it isn't right in so far as memory barriers etc couldn't work, as each thread
+would run to completion, but we aren't going to worry about barriers for now.
-On 1 - there could be potentially input and outputs (perhaps in out?). On CPU I guess that's fine.
+On 1 - there could be potentially input and outputs (perhaps in out?). On CPU I guess that's fine.
-On 2 and 3 they are effectively the same, and so for now 2+3 will be referred to together as 'uniforms'.
-They should be copied into a single structure that has a well known order.
+On 2 and 3 they are effectively the same, and so for now 2+3 will be referred to together as
+'uniforms'. They should be copied into a single structure that has a well known order.
-On 1 these are parameters that vary on an invocation. Thus a caller might call many times with same globals structure
-and different varying entry point parameters.
+On 1 these are parameters that vary on an invocation. Thus a caller might call many times with same
+globals structure and different varying entry point parameters.
On 5 - This would be a global that can be set and then accessed within the context of single thread
@@ -49,20 +48,23 @@ So in order of rate of change
1 : Probably change on every invocation (in the future such an invocation might be behind the API)
2 + 3 : Changes per group of 'threads' executed together
-4 : Does not change between invocations
+4 : Does not change between invocations
5 : Could be placed on the stack, and so not necessarily part of the ABI
-For now we are only going to implement something 'Compute shader'-like. Doing so makes the varying parameter always the same.
+For now we are only going to implement something 'Compute shader'-like. Doing so makes the varying
+parameter always the same.
So for now we would need to pass in
ComputeVaryingInput - Fixed because we are doing compute shader
-Uniform - All the uniform data in a big blob, both from uniform entry point parameters, and uniform globals
+Uniform - All the uniform data in a big blob, both from uniform entry point parameters,
+and uniform globals
When called we can have a structure that holds the thread local variables, and these two pointers.
*/
-namespace Slang {
+namespace Slang
+{
static const char s_xyzwNames[] = "xyzw";
@@ -72,30 +74,32 @@ static const char s_xyzwNames[] = "xyzw";
{
switch (op)
{
- case kIROp_VoidType: return UnownedStringSlice("void");
- case kIROp_BoolType: return UnownedStringSlice("bool");
+ case kIROp_VoidType: return UnownedStringSlice("void");
+ case kIROp_BoolType: return UnownedStringSlice("bool");
- case kIROp_Int8Type: return UnownedStringSlice("int8_t");
- case kIROp_Int16Type: return UnownedStringSlice("int16_t");
- case kIROp_IntType: return UnownedStringSlice("int32_t");
- case kIROp_Int64Type: return UnownedStringSlice("int64_t");
- case kIROp_IntPtrType: return UnownedStringSlice("intptr_t");
+ case kIROp_Int8Type: return UnownedStringSlice("int8_t");
+ case kIROp_Int16Type: return UnownedStringSlice("int16_t");
+ case kIROp_IntType: return UnownedStringSlice("int32_t");
+ case kIROp_Int64Type: return UnownedStringSlice("int64_t");
+ case kIROp_IntPtrType: return UnownedStringSlice("intptr_t");
- case kIROp_UInt8Type: return UnownedStringSlice("uint8_t");
- case kIROp_UInt16Type: return UnownedStringSlice("uint16_t");
- case kIROp_UIntType: return UnownedStringSlice("uint32_t");
- case kIROp_UInt64Type: return UnownedStringSlice("uint64_t");
- case kIROp_UIntPtrType: return UnownedStringSlice("uintptr_t");
+ case kIROp_UInt8Type: return UnownedStringSlice("uint8_t");
+ case kIROp_UInt16Type: return UnownedStringSlice("uint16_t");
+ case kIROp_UIntType: return UnownedStringSlice("uint32_t");
+ case kIROp_UInt64Type: return UnownedStringSlice("uint64_t");
+ case kIROp_UIntPtrType:
+ return UnownedStringSlice("uintptr_t");
- // Not clear just yet how we should handle half... we want all processing as float probly, but when reading/writing to memory converting
+ // Not clear just yet how we should handle half... we want all processing as float
+ // probly, but when reading/writing to memory converting
- case kIROp_HalfType: return UnownedStringSlice("half");
+ case kIROp_HalfType: return UnownedStringSlice("half");
- case kIROp_FloatType: return UnownedStringSlice("float");
- case kIROp_DoubleType: return UnownedStringSlice("double");
- case kIROp_CharType: return UnownedStringSlice("char");
+ case kIROp_FloatType: return UnownedStringSlice("float");
+ case kIROp_DoubleType: return UnownedStringSlice("double");
+ case kIROp_CharType: return UnownedStringSlice("char");
- default: return UnownedStringSlice();
+ default: return UnownedStringSlice();
}
}
@@ -119,42 +123,33 @@ UnownedStringSlice CPPSourceEmitter::_getTypeName(IRType* type)
return m_slicePool.getSlice(handle);
}
-SlangResult CPPSourceEmitter::_calcCPPTextureTypeName(IRTextureTypeBase* texType, StringBuilder& outName)
+SlangResult CPPSourceEmitter::_calcCPPTextureTypeName(
+ IRTextureTypeBase* texType,
+ StringBuilder& outName)
{
switch (texType->getAccess())
{
- case SLANG_RESOURCE_ACCESS_READ:
- break;
- case SLANG_RESOURCE_ACCESS_READ_WRITE:
- outName << "RW";
- break;
- case SLANG_RESOURCE_ACCESS_RASTER_ORDERED:
- outName << "RasterizerOrdered";
- break;
- case SLANG_RESOURCE_ACCESS_APPEND:
- outName << "Append";
- break;
- case SLANG_RESOURCE_ACCESS_CONSUME:
- outName << "Consume";
- break;
- case SLANG_RESOURCE_ACCESS_FEEDBACK:
- outName << "Feedback";
- break;
- default:
- SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unhandled resource access mode");
- return SLANG_FAIL;
+ case SLANG_RESOURCE_ACCESS_READ: break;
+ case SLANG_RESOURCE_ACCESS_READ_WRITE: outName << "RW"; break;
+ case SLANG_RESOURCE_ACCESS_RASTER_ORDERED: outName << "RasterizerOrdered"; break;
+ case SLANG_RESOURCE_ACCESS_APPEND: outName << "Append"; break;
+ case SLANG_RESOURCE_ACCESS_CONSUME: outName << "Consume"; break;
+ case SLANG_RESOURCE_ACCESS_FEEDBACK: outName << "Feedback"; break;
+ default:
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unhandled resource access mode");
+ return SLANG_FAIL;
}
switch (texType->GetBaseShape())
{
- case SLANG_TEXTURE_1D: outName << "Texture1D"; break;
- case SLANG_TEXTURE_2D: outName << "Texture2D"; break;
- case SLANG_TEXTURE_3D: outName << "Texture3D"; break;
- case SLANG_TEXTURE_CUBE: outName << "TextureCube"; break;
- case SLANG_TEXTURE_BUFFER: outName << "Buffer"; break;
- default:
- SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unhandled resource shape");
- return SLANG_FAIL;
+ case SLANG_TEXTURE_1D: outName << "Texture1D"; break;
+ case SLANG_TEXTURE_2D: outName << "Texture2D"; break;
+ case SLANG_TEXTURE_3D: outName << "Texture3D"; break;
+ case SLANG_TEXTURE_CUBE: outName << "TextureCube"; break;
+ case SLANG_TEXTURE_BUFFER: outName << "Buffer"; break;
+ default:
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unhandled resource shape");
+ return SLANG_FAIL;
}
if (texType->isMultisample())
@@ -174,19 +169,28 @@ static UnownedStringSlice _getResourceTypePrefix(IROp op)
{
switch (op)
{
- case kIROp_HLSLStructuredBufferType: return UnownedStringSlice::fromLiteral("StructuredBuffer");
- case kIROp_HLSLRWStructuredBufferType: return UnownedStringSlice::fromLiteral("RWStructuredBuffer");
- case kIROp_HLSLRWByteAddressBufferType: return UnownedStringSlice::fromLiteral("RWByteAddressBuffer");
- case kIROp_HLSLByteAddressBufferType: return UnownedStringSlice::fromLiteral("ByteAddressBuffer");
- case kIROp_SamplerStateType: return UnownedStringSlice::fromLiteral("SamplerState");
- case kIROp_SamplerComparisonStateType: return UnownedStringSlice::fromLiteral("SamplerComparisonState");
- case kIROp_HLSLRasterizerOrderedStructuredBufferType: return UnownedStringSlice::fromLiteral("RasterizerOrderedStructuredBuffer");
- case kIROp_HLSLAppendStructuredBufferType: return UnownedStringSlice::fromLiteral("AppendStructuredBuffer");
- case kIROp_HLSLConsumeStructuredBufferType: return UnownedStringSlice::fromLiteral("ConsumeStructuredBuffer");
- case kIROp_HLSLRasterizerOrderedByteAddressBufferType: return UnownedStringSlice::fromLiteral("RasterizerOrderedByteAddressBuffer");
- case kIROp_RaytracingAccelerationStructureType: return UnownedStringSlice::fromLiteral("RaytracingAccelerationStructure");
-
- default: return UnownedStringSlice();
+ case kIROp_HLSLStructuredBufferType: return UnownedStringSlice::fromLiteral("StructuredBuffer");
+ case kIROp_HLSLRWStructuredBufferType:
+ return UnownedStringSlice::fromLiteral("RWStructuredBuffer");
+ case kIROp_HLSLRWByteAddressBufferType:
+ return UnownedStringSlice::fromLiteral("RWByteAddressBuffer");
+ case kIROp_HLSLByteAddressBufferType:
+ return UnownedStringSlice::fromLiteral("ByteAddressBuffer");
+ case kIROp_SamplerStateType: return UnownedStringSlice::fromLiteral("SamplerState");
+ case kIROp_SamplerComparisonStateType:
+ return UnownedStringSlice::fromLiteral("SamplerComparisonState");
+ case kIROp_HLSLRasterizerOrderedStructuredBufferType:
+ return UnownedStringSlice::fromLiteral("RasterizerOrderedStructuredBuffer");
+ case kIROp_HLSLAppendStructuredBufferType:
+ return UnownedStringSlice::fromLiteral("AppendStructuredBuffer");
+ case kIROp_HLSLConsumeStructuredBufferType:
+ return UnownedStringSlice::fromLiteral("ConsumeStructuredBuffer");
+ case kIROp_HLSLRasterizerOrderedByteAddressBufferType:
+ return UnownedStringSlice::fromLiteral("RasterizerOrderedByteAddressBuffer");
+ case kIROp_RaytracingAccelerationStructureType:
+ return UnownedStringSlice::fromLiteral("RaytracingAccelerationStructure");
+
+ default: return UnownedStringSlice();
}
}
@@ -194,22 +198,22 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S
{
switch (type->getOp())
{
- case kIROp_HalfType:
+ case kIROp_HalfType:
{
// Special case half
- out << getBuiltinTypeName(kIROp_FloatType);
- return SLANG_OK;
+ out << getBuiltinTypeName(kIROp_FloatType);
+ return SLANG_OK;
}
- case kIROp_VectorType:
+ case kIROp_VectorType:
{
auto vecType = static_cast<IRVectorType*>(type);
auto vecCount = int(getIntVal(vecType->getElementCount()));
auto elemType = vecType->getElementType();
out << "Vector<" << _getTypeName(elemType) << ", " << vecCount << ">";
- return SLANG_OK;
+ return SLANG_OK;
}
- case kIROp_MatrixType:
+ case kIROp_MatrixType:
{
auto matType = static_cast<IRMatrixType*>(type);
@@ -217,12 +221,13 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S
const auto rowCount = int(getIntVal(matType->getRowCount()));
const auto colCount = int(getIntVal(matType->getColumnCount()));
- out << "Matrix<" << _getTypeName(elementType) << ", " << rowCount << ", " << colCount << ">";
-
+ out << "Matrix<" << _getTypeName(elementType) << ", " << rowCount << ", " << colCount
+ << ">";
+
return SLANG_OK;
}
- case kIROp_WitnessTableType:
- case kIROp_WitnessTableIDType:
+ case kIROp_WitnessTableType:
+ case kIROp_WitnessTableIDType:
{
// A witness table typed value translates to a pointer to the
// struct of function pointers corresponding to the interface type.
@@ -232,13 +237,13 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S
out << "*";
return SLANG_OK;
}
- case kIROp_RawPointerType:
- case kIROp_RTTIPointerType:
+ case kIROp_RawPointerType:
+ case kIROp_RTTIPointerType:
{
out << "void*";
return SLANG_OK;
}
- case kIROp_AnyValueType:
+ case kIROp_AnyValueType:
{
out << "AnyValue<";
auto anyValueType = static_cast<IRAnyValueType*>(type);
@@ -246,8 +251,8 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S
out << ">";
return SLANG_OK;
}
- case kIROp_ConstantBufferType:
- case kIROp_ParameterBlockType:
+ case kIROp_ConstantBufferType:
+ case kIROp_ParameterBlockType:
{
auto groupType = cast<IRParameterGroupType>(type);
auto elementType = groupType->getElementType();
@@ -256,35 +261,35 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S
out << "*";
return SLANG_OK;
}
- case kIROp_NativePtrType:
- case kIROp_PtrType:
+ case kIROp_NativePtrType:
+ case kIROp_PtrType:
{
auto elementType = (IRType*)type->getOperand(0);
SLANG_RETURN_ON_FAIL(calcTypeName(elementType, target, out));
out << "*";
return SLANG_OK;
}
- case kIROp_RTTIType:
+ case kIROp_RTTIType:
{
out << "TypeInfo";
return SLANG_OK;
}
- case kIROp_RTTIHandleType:
+ case kIROp_RTTIHandleType:
{
out << "TypeInfo*";
return SLANG_OK;
}
- case kIROp_NativeStringType:
+ case kIROp_NativeStringType:
{
out << "const char*";
return SLANG_OK;
}
- case kIROp_StringType:
+ case kIROp_StringType:
{
out << "String";
return SLANG_OK;
}
- case kIROp_ComPtrType:
+ case kIROp_ComPtrType:
{
auto comPtrType = static_cast<IRComPtrType*>(type);
auto baseType = cast<IRType>(comPtrType->getOperand(0));
@@ -294,26 +299,27 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S
out << ">";
return SLANG_OK;
}
- case kIROp_ClassType:
+ case kIROp_ClassType:
{
out << "RefPtr<";
out << getName(type);
out << ">";
return SLANG_OK;
}
- case kIROp_TargetTupleType:
+ case kIROp_TargetTupleType:
{
out << "std::tuple<";
for (UInt i = 0; i < type->getOperandCount(); i++)
{
- if (i > 0) out << ", ";
+ if (i > 0)
+ out << ", ";
auto elementType = (IRType*)type->getOperand(i);
SLANG_RETURN_ON_FAIL(calcTypeName(elementType, target, out));
}
out << ">";
return SLANG_OK;
}
- case kIROp_Specialize:
+ case kIROp_Specialize:
{
auto inner = getResolvedInstForDecorations(type);
if (auto targetIntrinsic = findBestTargetIntrinsicDecoration(inner, getTargetCaps()))
@@ -322,7 +328,8 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S
out << "<";
for (UInt i = 1; i < type->getOperandCount(); i++)
{
- if (i > 1) out << ", ";
+ if (i > 1)
+ out << ", ";
auto elementType = (IRType*)type->getOperand(i);
SLANG_RETURN_ON_FAIL(calcTypeName(elementType, target, out));
}
@@ -331,17 +338,17 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S
}
return SLANG_FAIL;
}
- case kIROp_IntLit:
+ case kIROp_IntLit:
{
auto intLit = as<IRIntLit>(type);
out << intLit->getValue();
return SLANG_OK;
}
- case kIROp_AtomicType:
+ case kIROp_AtomicType:
{
return calcTypeName((IRType*)type->getOperand(0), target, out);
}
- default:
+ default:
{
if (isNominalOp(type->getOp()))
{
@@ -360,7 +367,8 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S
return _calcCPPTextureTypeName(texType, out);
}
- // If _getResourceTypePrefix returns something, we assume can output any specialization after it in order.
+ // If _getResourceTypePrefix returns something, we assume can output any specialization
+ // after it in order.
{
UnownedStringSlice prefix = _getResourceTypePrefix(type->getOp());
if (prefix.getLength() > 0)
@@ -369,7 +377,8 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S
SourceManager* sourceManager = oldWriter->getSourceManager();
// TODO(JS): This is a bit of a hack. We don't want to emit the result here,
- // so we replace the writer, write out the type, grab the contents, and restore the writer
+ // so we replace the writer, write out the type, grab the contents, and restore
+ // the writer
SourceWriter writer(sourceManager, LineDirectiveMode::None, nullptr);
m_writer = &writer;
@@ -417,27 +426,29 @@ void CPPSourceEmitter::useType(IRType* type)
_getTypeName(type);
}
-/* static */CPPSourceEmitter::TypeDimension CPPSourceEmitter::_getTypeDimension(IRType* type, bool vecSwap)
+/* static */ CPPSourceEmitter::TypeDimension CPPSourceEmitter::_getTypeDimension(
+ IRType* type,
+ bool vecSwap)
{
switch (type->getOp())
{
- case kIROp_PtrType:
+ case kIROp_PtrType:
{
type = static_cast<IRPtrType*>(type)->getValueType();
break;
}
- case kIROp_RefType:
- case kIROp_ConstRefType:
+ case kIROp_RefType:
+ case kIROp_ConstRefType:
{
type = static_cast<IRPtrTypeBase*>(type)->getValueType();
break;
}
- default: break;
+ default: break;
}
switch (type->getOp())
{
- case kIROp_VectorType:
+ case kIROp_VectorType:
{
auto vecType = static_cast<IRVectorType*>(type);
@@ -445,9 +456,10 @@ void CPPSourceEmitter::useType(IRType* type)
const BaseType baseType = elemBasicType->getBaseType();
const int elemCount = int(getIntVal(vecType->getElementCount()));
- return (!vecSwap) ? TypeDimension{baseType, 1, elemCount} : TypeDimension{ baseType, elemCount, 1};
+ return (!vecSwap) ? TypeDimension{baseType, 1, elemCount}
+ : TypeDimension{baseType, elemCount, 1};
}
- case kIROp_MatrixType:
+ case kIROp_MatrixType:
{
auto matType = static_cast<IRMatrixType*>(type);
const int colCount = int(getIntVal(matType->getColumnCount()));
@@ -458,7 +470,7 @@ void CPPSourceEmitter::useType(IRType* type)
return TypeDimension{baseType, rowCount, colCount};
}
- default:
+ default:
{
// Assume we don't know the type
BaseType baseType = BaseType::Void;
@@ -474,39 +486,47 @@ void CPPSourceEmitter::useType(IRType* type)
}
}
-void CPPSourceEmitter::_emitAccess(const UnownedStringSlice& name, const TypeDimension& dimension, int row, int col, SourceWriter* writer)
+void CPPSourceEmitter::_emitAccess(
+ const UnownedStringSlice& name,
+ const TypeDimension& dimension,
+ int row,
+ int col,
+ SourceWriter* writer)
{
-
+
writer->emit(name);
const int comb = (dimension.colCount > 1 ? 2 : 0) | (dimension.rowCount > 1 ? 1 : 0);
switch (comb)
{
- case 0:
+ case 0:
{
break;
}
- case 1:
+ case 1:
{
// Vector, row count is biggest
- const UnownedStringSlice* elemNames = getVectorElementNames(dimension.elemType, dimension.rowCount);
+ const UnownedStringSlice* elemNames =
+ getVectorElementNames(dimension.elemType, dimension.rowCount);
writer->emit(".");
const int index = (row > col) ? row : col;
writer->emit(elemNames[index]);
break;
}
- case 2:
+ case 2:
{
// Vector cols biggest dimension
- const UnownedStringSlice* elemNames = getVectorElementNames(dimension.elemType, dimension.colCount);
+ const UnownedStringSlice* elemNames =
+ getVectorElementNames(dimension.elemType, dimension.colCount);
writer->emit(".");
const int index = (row > col) ? row : col;
writer->emit(elemNames[index]);
break;
}
- case 3:
- {
+ case 3:
+ {
// Matrix
- const UnownedStringSlice* elemNames = getVectorElementNames(dimension.elemType, dimension.colCount);
+ const UnownedStringSlice* elemNames =
+ getVectorElementNames(dimension.elemType, dimension.colCount);
writer->emit(".rows[");
writer->emit(row);
@@ -519,17 +539,17 @@ void CPPSourceEmitter::_emitAccess(const UnownedStringSlice& name, const TypeDim
/* !!!!!!!!!!!!!!!!!!!!!! CPPSourceEmitter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-CPPSourceEmitter::CPPSourceEmitter(const Desc& desc):
- Super(desc),
- m_slicePool(StringSlicePool::Style::Default)
+CPPSourceEmitter::CPPSourceEmitter(const Desc& desc)
+ : Super(desc), m_slicePool(StringSlicePool::Style::Default)
{
m_semanticUsedFlags = 0;
- //m_semanticUsedFlags = SemanticUsedFlag::GroupID | SemanticUsedFlag::GroupThreadID | SemanticUsedFlag::DispatchThreadID;
+ // m_semanticUsedFlags = SemanticUsedFlag::GroupID | SemanticUsedFlag::GroupThreadID |
+ // SemanticUsedFlag::DispatchThreadID;
+
-
const auto artifactDesc = ArtifactDescUtil::makeDescForCompileTarget(asExternal(getTarget()));
- // If we have runtime library we can convert to a terminated string slice
+ // If we have runtime library we can convert to a terminated string slice
m_hasString = (artifactDesc.style == ArtifactStyle::Host);
}
@@ -584,7 +604,8 @@ void CPPSourceEmitter::_emitWitnessTableDefinitions()
emitComWitnessTable(witnessTable);
continue;
}
- List<IRWitnessTableEntry*> sortedWitnessTableEntries = getSortedWitnessTableEntries(witnessTable);
+ List<IRWitnessTableEntry*> sortedWitnessTableEntries =
+ getSortedWitnessTableEntries(witnessTable);
m_writer->emit("extern \"C\"\n{\n");
m_writer->indent();
emitGlobalRTTISymbolPrefix();
@@ -613,8 +634,9 @@ void CPPSourceEmitter::_emitWitnessTableDefinitions()
m_writer->emit("&");
m_writer->emit(getName(witnessTableVal));
}
- else if (entry->getSatisfyingVal() &&
- entry->getSatisfyingVal()->getDataType()->getOp() == kIROp_RTTIHandleType)
+ else if (
+ entry->getSatisfyingVal() &&
+ entry->getSatisfyingVal()->getDataType()->getOp() == kIROp_RTTIHandleType)
{
m_writer->emit(",\n");
emitInstExpr(entry->getSatisfyingVal(), getInfo(EmitOp::General));
@@ -795,7 +817,7 @@ bool CPPSourceEmitter::tryEmitGlobalParamImpl(IRGlobalParam* varDecl, IRType* va
switch (varType->getOp())
{
- case kIROp_StructType:
+ case kIROp_StructType:
{
String name = getName(varDecl);
@@ -811,7 +833,9 @@ bool CPPSourceEmitter::tryEmitGlobalParamImpl(IRGlobalParam* varDecl, IRType* va
return false;
}
-void CPPSourceEmitter::emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformParameterGroupType* type)
+void CPPSourceEmitter::emitParameterGroupImpl(
+ IRGlobalParam* varDecl,
+ IRUniformParameterGroupType* type)
{
// Output global parameters
auto varLayout = getVarLayout(varDecl);
@@ -822,8 +846,8 @@ void CPPSourceEmitter::emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformP
switch (type->getOp())
{
- case kIROp_ParameterBlockType:
- case kIROp_ConstantBufferType:
+ case kIROp_ParameterBlockType:
+ case kIROp_ConstantBufferType:
{
UnownedStringSlice typeName = _getTypeName(elementType);
m_writer->emit(typeName);
@@ -832,8 +856,8 @@ void CPPSourceEmitter::emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformP
m_writer->emit(";\n");
break;
}
- default:
- {
+ default:
+ {
emitType(elementType, name);
m_writer->emit(";\n");
break;
@@ -841,31 +865,34 @@ void CPPSourceEmitter::emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformP
}
}
-void CPPSourceEmitter::emitEntryPointAttributesImpl(IRFunc* irFunc, IREntryPointDecoration* entryPointDecor)
+void CPPSourceEmitter::emitEntryPointAttributesImpl(
+ IRFunc* irFunc,
+ IREntryPointDecoration* entryPointDecor)
{
SLANG_UNUSED(entryPointDecor);
- auto profile = m_effectiveProfile;
+ auto profile = m_effectiveProfile;
auto stage = profile.getStage();
switch (stage)
{
- case Stage::Compute:
+ case Stage::Compute:
{
Int numThreads[kThreadGroupAxisCount];
getComputeThreadGroupSize(irFunc, numThreads);
-
+
// TODO(JS): We might want to store this information such that it can be used to execute
m_writer->emit("// [numthreads(");
for (int ii = 0; ii < kThreadGroupAxisCount; ++ii)
{
- if (ii != 0) m_writer->emit(", ");
+ if (ii != 0)
+ m_writer->emit(", ");
m_writer->emit(numThreads[ii]);
}
m_writer->emit(")]\n");
break;
}
- default: break;
+ default: break;
}
m_writer->emit("SLANG_PRELUDE_EXPORT\n");
@@ -877,19 +904,18 @@ bool isPublicOrExportedFunc(IRFunc* func)
{
switch (decor->getOp())
{
- case kIROp_PublicDecoration:
- case kIROp_EntryPointDecoration:
- case kIROp_HLSLExportDecoration:
- case kIROp_DllExportDecoration:
- case kIROp_DllImportDecoration:
- case kIROp_CudaDeviceExportDecoration:
- case kIROp_CudaHostDecoration:
- case kIROp_CudaKernelDecoration:
+ case kIROp_PublicDecoration:
+ case kIROp_EntryPointDecoration:
+ case kIROp_HLSLExportDecoration:
+ case kIROp_DllExportDecoration:
+ case kIROp_DllImportDecoration:
+ case kIROp_CudaDeviceExportDecoration:
+ case kIROp_CudaHostDecoration:
+ case kIROp_CudaKernelDecoration:
{
return true;
}
- default:
- break;
+ default: break;
}
}
return false;
@@ -914,7 +940,8 @@ void CPPSourceEmitter::emitSimpleFuncImpl(IRFunc* func)
}
// We start by emitting the result type and function name.
//
- if (IREntryPointDecoration* const entryPointDecor = func->findDecoration<IREntryPointDecoration>())
+ if (IREntryPointDecoration* const entryPointDecor =
+ func->findDecoration<IREntryPointDecoration>())
{
// Note: we currently emit multiple functions to represent an entry point
// on CPU/CUDA, and these all bottleneck through the actual `IRFunc`
@@ -978,25 +1005,25 @@ void CPPSourceEmitter::emitSimpleValueImpl(IRInst* inst)
IRConstant* constantInst = static_cast<IRConstant*>(inst);
switch (constantInst->getFloatKind())
{
- case IRConstant::FloatKind::Nan:
+ case IRConstant::FloatKind::Nan:
{
- // TODO(JS):
+ // TODO(JS):
// It's not clear this will work on all targets.
- // In particular Visual Studio reports an error with this expression.
+ // In particular Visual Studio reports an error with this expression.
m_writer->emit("(0.0 / 0.0)");
break;
}
- case IRConstant::FloatKind::PositiveInfinity:
+ case IRConstant::FloatKind::PositiveInfinity:
{
m_writer->emit("SLANG_INFINITY");
break;
}
- case IRConstant::FloatKind::NegativeInfinity:
+ case IRConstant::FloatKind::NegativeInfinity:
{
m_writer->emit("(-SLANG_INFINITY)");
break;
}
- default:
+ default:
{
m_writer->emit(constantInst->value.floatVal);
@@ -1041,19 +1068,17 @@ void CPPSourceEmitter::_emitType(IRType* type, DeclaratorInfo* declarator)
{
switch (type->getOp())
{
- default:
- CLikeSourceEmitter::_emitType(type, declarator);
- break;
+ default: CLikeSourceEmitter::_emitType(type, declarator); break;
case kIROp_VectorType:
case kIROp_MatrixType:
- {
- StringBuilder sb;
- calcTypeName(type, m_target, sb);
- m_writer->emit(sb.produceString());
- m_writer->emit(" ");
- emitDeclarator(declarator);
- break;
- }
+ {
+ StringBuilder sb;
+ calcTypeName(type, m_target, sb);
+ m_writer->emit(sb.produceString());
+ m_writer->emit(" ");
+ emitDeclarator(declarator);
+ break;
+ }
case kIROp_PtrType:
case kIROp_InOutType:
case kIROp_OutType:
@@ -1114,10 +1139,10 @@ void CPPSourceEmitter::_emitType(IRType* type, DeclaratorInfo* declarator)
}
void CPPSourceEmitter::emitIntrinsicCallExprImpl(
- IRCall* inst,
- UnownedStringSlice intrinsicDefinition,
- IRInst* intrinsicInst,
- EmitOpInfo const& inOuterPrec)
+ IRCall* inst,
+ UnownedStringSlice intrinsicDefinition,
+ IRInst* intrinsicInst,
+ EmitOpInfo const& inOuterPrec)
{
// TODO: Much of this logic duplicates code that is already
// in `CLikeSourceEmitter::emitIntrinsicCallExpr`. The only
@@ -1130,7 +1155,7 @@ void CPPSourceEmitter::emitIntrinsicCallExprImpl(
Index argCount = Index(inst->getArgCount());
auto args = inst->getArgs();
-
+
auto name = intrinsicDefinition;
// We will special-case some names here, that
@@ -1188,18 +1213,20 @@ void CPPSourceEmitter::emitLoopControlDecorationImpl(IRLoopControlDecoration* de
{
if (decl->getMode() == kIRLoopControl_Unroll)
{
- // This relies on a suitable definition in slang-cpp-prelude.h or defined in C++ compiler invocation.
+ // This relies on a suitable definition in slang-cpp-prelude.h or defined in C++ compiler
+ // invocation.
m_writer->emit("SLANG_UNROLL\n");
}
}
-const UnownedStringSlice* CPPSourceEmitter::getVectorElementNames(BaseType baseType, Index elemCount)
+const UnownedStringSlice* CPPSourceEmitter::getVectorElementNames(
+ BaseType baseType,
+ Index elemCount)
{
SLANG_UNUSED(baseType);
SLANG_UNUSED(elemCount);
- static const UnownedStringSlice elemNames[] =
- {
+ static const UnownedStringSlice elemNames[] = {
UnownedStringSlice::fromLiteral("x"),
UnownedStringSlice::fromLiteral("y"),
UnownedStringSlice::fromLiteral("z"),
@@ -1224,32 +1251,33 @@ bool CPPSourceEmitter::tryEmitInstStmtImpl(IRInst* inst)
switch (inst->getOp())
{
case kIROp_StructuredBufferGetDimensions:
- {
- auto count = _generateUniqueName(UnownedStringSlice("_elementCount"));
- auto stride = _generateUniqueName(UnownedStringSlice("_stride"));
+ {
+ auto count = _generateUniqueName(UnownedStringSlice("_elementCount"));
+ auto stride = _generateUniqueName(UnownedStringSlice("_stride"));
- m_writer->emit("uint ");
- m_writer->emit(count);
- m_writer->emit(";\n");
- m_writer->emit("uint ");
- m_writer->emit(stride);
- m_writer->emit(";\n");
- emitOperand(inst->getOperand(0), leftSide(getInfo(EmitOp::General), getInfo(EmitOp::Postfix)));
- m_writer->emit(".GetDimensions(&");
- m_writer->emit(count);
- m_writer->emit(", &");
- m_writer->emit(stride);
- m_writer->emit(");\n");
- emitInstResultDecl(inst);
- m_writer->emit("uint2(");
- m_writer->emit(count);
- m_writer->emit(", ");
- m_writer->emit(stride);
- m_writer->emit(");\n");
- return true;
- }
- default:
- return false;
+ m_writer->emit("uint ");
+ m_writer->emit(count);
+ m_writer->emit(";\n");
+ m_writer->emit("uint ");
+ m_writer->emit(stride);
+ m_writer->emit(";\n");
+ emitOperand(
+ inst->getOperand(0),
+ leftSide(getInfo(EmitOp::General), getInfo(EmitOp::Postfix)));
+ m_writer->emit(".GetDimensions(&");
+ m_writer->emit(count);
+ m_writer->emit(", &");
+ m_writer->emit(stride);
+ m_writer->emit(");\n");
+ emitInstResultDecl(inst);
+ m_writer->emit("uint2(");
+ m_writer->emit(count);
+ m_writer->emit(", ");
+ m_writer->emit(stride);
+ m_writer->emit(");\n");
+ return true;
+ }
+ default: return false;
}
}
@@ -1257,25 +1285,25 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
{
switch (inst->getOp())
{
- default:
+ default:
{
return false;
}
-
- case kIROp_InOutImplicitCast:
- case kIROp_OutImplicitCast:
+
+ case kIROp_InOutImplicitCast:
+ case kIROp_OutImplicitCast:
{
// We'll just the LValue to be the desired type
m_writer->emit("reinterpret_cast<");
emitType(inst->getDataType());
m_writer->emit(">(");
-
+
emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
m_writer->emit(")");
return true;
}
- case kIROp_MakeVector:
+ case kIROp_MakeVector:
{
IRType* retType = inst->getFullType();
emitType(retType);
@@ -1286,7 +1314,8 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
auto arg = inst->getOperand(i);
if (auto vectorType = as<IRVectorType>(arg->getDataType()))
{
- for (int j = 0; j < cast<IRIntLit>(vectorType->getElementCount())->getValue(); j++)
+ for (int j = 0; j < cast<IRIntLit>(vectorType->getElementCount())->getValue();
+ j++)
{
if (isFirst)
isFirst = false;
@@ -1312,7 +1341,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
return true;
}
- case kIROp_MakeTargetTuple:
+ case kIROp_MakeTargetTuple:
{
m_writer->emit("std::make_tuple(");
for (UInt i = 0; i < inst->getOperandCount(); i++)
@@ -1325,7 +1354,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
m_writer->emit(")");
return true;
}
- case kIROp_GetTargetTupleElement:
+ case kIROp_GetTargetTupleElement:
{
auto outerPrec = getInfo(EmitOp::General);
auto prec = getInfo(EmitOp::Postfix);
@@ -1336,16 +1365,17 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
m_writer->emit(")");
return true;
}
- case kIROp_CastFloatToInt:
- case kIROp_CastIntToFloat:
- case kIROp_FloatCast:
- case kIROp_IntCast:
+ case kIROp_CastFloatToInt:
+ case kIROp_CastIntToFloat:
+ case kIROp_FloatCast:
+ case kIROp_IntCast:
{
if (auto vectorType = as<IRVectorType>(inst->getDataType()))
{
emitType(vectorType);
m_writer->emit("{");
- for (Index i = 0; i < cast<IRIntLit>(vectorType->getElementCount())->getValue(); i++)
+ for (Index i = 0; i < cast<IRIntLit>(vectorType->getElementCount())->getValue();
+ i++)
{
if (i > 0)
m_writer->emit(", ");
@@ -1362,7 +1392,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
}
return false;
}
- case kIROp_VectorReshape:
+ case kIROp_VectorReshape:
{
if (auto vectorType = as<IRVectorType>(inst->getDataType()))
{
@@ -1377,7 +1407,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
}
return false;
}
- case kIROp_GetElement:
+ case kIROp_GetElement:
{
auto getElementInst = static_cast<IRGetElement*>(inst);
@@ -1417,7 +1447,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
}
return false;
}
- case kIROp_GetElementPtr:
+ case kIROp_GetElementPtr:
{
auto getElementInst = static_cast<IRGetElement*>(inst);
@@ -1459,34 +1489,35 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
}
return false;
}
- case kIROp_RWStructuredBufferGetElementPtr:
- {
- m_writer->emit("(&(");
- auto base = inst->getOperand(0);
- auto outerPrec = getInfo(EmitOp::General);
- emitOperand(base, outerPrec);
- m_writer->emit("[");
- emitOperand(inst->getOperand(1), EmitOpInfo());
- m_writer->emit("]))");
- return true;
- }
- case kIROp_swizzle:
+ case kIROp_RWStructuredBufferGetElementPtr:
+ {
+ m_writer->emit("(&(");
+ auto base = inst->getOperand(0);
+ auto outerPrec = getInfo(EmitOp::General);
+ emitOperand(base, outerPrec);
+ m_writer->emit("[");
+ emitOperand(inst->getOperand(1), EmitOpInfo());
+ m_writer->emit("]))");
+ return true;
+ }
+ case kIROp_swizzle:
{
// For C++ we don't need to emit a swizzle function
- // For C we need a construction function
+ // For C we need a construction function
auto swizzleInst = static_cast<IRSwizzle*>(inst);
IRInst* baseInst = swizzleInst->getBase();
IRType* baseType = baseInst->getDataType();
- // If we are swizzling from a built in type,
+ // If we are swizzling from a built in type,
if (as<IRBasicType>(baseType))
{
// We can swizzle a scalar type to be a vector, or just a scalar
IRType* dstType = swizzleInst->getDataType();
if (as<IRBasicType>(dstType))
{
- // If the output is a scalar, then could only have been a .x, which we can just ignore the '.x' part
+ // If the output is a scalar, then could only have been a .x, which we can just
+ // ignore the '.x' part
emitOperand(baseInst, inOuterPrec);
return true;
}
@@ -1496,15 +1527,15 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
const Index elementCount = Index(swizzleInst->getElementCount());
if (elementCount == 1)
{
- // If just one thing is extracted then the . syntax will just work
+ // If just one thing is extracted then the . syntax will just work
defaultEmitInstExpr(inst, inOuterPrec);
return true;
}
}
{
- // 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
+ // 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
const Index elementCount = Index(swizzleInst->getElementCount());
@@ -1549,23 +1580,16 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
}
return true;
}
- case kIROp_FRem:
+ case kIROp_FRem:
{
if (auto basicType = as<IRBasicType>(inst->getDataType()))
{
switch (basicType->getOp())
{
- case kIROp_HalfType:
- m_writer->emit("F16_fmod(");
- break;
- case kIROp_FloatType:
- m_writer->emit("F32_fmod(");
- break;
- case kIROp_DoubleType:
- m_writer->emit("F64_fmod(");
- break;
- default:
- return false;
+ case kIROp_HalfType: m_writer->emit("F16_fmod("); break;
+ case kIROp_FloatType: m_writer->emit("F32_fmod("); break;
+ case kIROp_DoubleType: m_writer->emit("F64_fmod("); break;
+ default: return false;
}
emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
m_writer->emit(", ");
@@ -1575,7 +1599,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
}
return false;
}
- case kIROp_Call:
+ case kIROp_Call:
{
auto funcValue = inst->getOperand(0);
@@ -1585,27 +1609,27 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
// try doing automatically
return false;
}
- case kIROp_LookupWitness:
+ case kIROp_LookupWitness:
{
emitInstExpr(inst->getOperand(0), inOuterPrec);
m_writer->emit("->");
m_writer->emit(getName(inst->getOperand(1)));
return true;
}
- case kIROp_GetSequentialID:
+ case kIROp_GetSequentialID:
{
emitInstExpr(inst->getOperand(0), inOuterPrec);
m_writer->emit("->sequentialID");
return true;
}
- case kIROp_WitnessTable:
+ case kIROp_WitnessTable:
{
m_writer->emit("(&");
m_writer->emit(getName(inst));
m_writer->emit(")");
return true;
}
- case kIROp_GetAddr:
+ case kIROp_GetAddr:
{
// Once we clean up the pointer emitting logic, we can
// just use GetElementAddress instruction in place of
@@ -1615,19 +1639,19 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
m_writer->emit("))");
return true;
}
- case kIROp_RTTIObject:
+ case kIROp_RTTIObject:
{
m_writer->emit(getName(inst));
return true;
}
- case kIROp_Alloca:
+ case kIROp_Alloca:
{
m_writer->emit("alloca(");
emitOperand(inst->getOperand(0), EmitOpInfo::get(EmitOp::Postfix));
m_writer->emit("->typeSize)");
return true;
}
- case kIROp_BitCast:
+ case kIROp_BitCast:
{
m_writer->emit("(slang_bit_cast<");
emitType(inst->getDataType());
@@ -1636,14 +1660,14 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
m_writer->emit("))");
return true;
}
- case kIROp_StringLit:
+ case kIROp_StringLit:
{
auto handler = StringEscapeUtil::getHandler(StringEscapeUtil::Style::Cpp);
StringBuilder buf;
const auto slice = as<IRStringLit>(inst)->getStringSlice();
StringEscapeUtil::appendQuoted(handler, slice, buf);
-
+
if (m_hasString)
{
m_writer->emit("Slang::toTerminatedSlice(");
@@ -1657,7 +1681,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
return true;
}
- case kIROp_PtrLit:
+ case kIROp_PtrLit:
{
auto ptrVal = as<IRPtrLit>(inst)->value.ptrVal;
if (ptrVal == nullptr)
@@ -1674,8 +1698,8 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
}
return true;
}
- case kIROp_MakeExistential:
- case kIROp_MakeExistentialWithRTTI:
+ case kIROp_MakeExistential:
+ case kIROp_MakeExistentialWithRTTI:
{
auto rsType = cast<IRComPtrType>(inst->getDataType());
m_writer->emit("ComPtr<");
@@ -1690,7 +1714,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
m_writer->emit("))");
return true;
}
- case kIROp_GetValueFromBoundInterface:
+ case kIROp_GetValueFromBoundInterface:
{
m_writer->emit("static_cast<");
m_writer->emit(getName(inst->getFullType()));
@@ -1701,7 +1725,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
m_writer->emit(")");
return true;
}
- case kIROp_Select:
+ case kIROp_Select:
{
m_writer->emit("_slang_select(");
emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
@@ -1723,10 +1747,10 @@ void CPPSourceEmitter::emitPreModuleImpl()
// Unfortunately this is a problem if we are just emitting code that is externally available
// and is not only accessible through entry points. So for now we disable
- // that this opens an anonymous scope.
+ // that this opens an anonymous scope.
// The scope is closed in `emitModuleImpl`
- //m_writer->emit("namespace { // anonymous \n\n");
+ // m_writer->emit("namespace { // anonymous \n\n");
// When generating kernel code in C++, put all into an anonymous namespace
// This includes any generated types, and generated intrinsics.
@@ -1767,7 +1791,8 @@ bool CPPSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
if (as<IRVectorType>(inst->getDataType()) || as<IRMatrixType>(inst->getDataType()))
{
// If a vector value is being used in a reshape/cast,
- // we should not fold it because the implementation of cast will have multiple references to it.
+ // we should not fold it because the implementation of cast will have multiple references to
+ // it.
for (auto use = inst->firstUse; use; use = use->nextUse)
{
switch (use->getUser()->getOp())
@@ -1777,10 +1802,8 @@ bool CPPSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
case kIROp_IntCast:
case kIROp_FloatCast:
case kIROp_CastIntToFloat:
- case kIROp_CastFloatToInt:
- return false;
- default:
- break;
+ case kIROp_CastFloatToInt: return false;
+ default: break;
}
}
switch (inst->getOp())
@@ -1790,10 +1813,8 @@ bool CPPSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
case kIROp_IntCast:
case kIROp_FloatCast:
case kIROp_CastIntToFloat:
- case kIROp_CastFloatToInt:
- return false;
- default:
- break;
+ case kIROp_CastFloatToInt: return false;
+ default: break;
}
}
return true;
@@ -1804,8 +1825,7 @@ static bool _isExported(IRInst* inst)
for (auto decoration : inst->getDecorations())
{
const auto op = decoration->getOp();
- if (op == kIROp_PublicDecoration ||
- op == kIROp_HLSLExportDecoration)
+ if (op == kIROp_PublicDecoration || op == kIROp_HLSLExportDecoration)
{
return true;
}
@@ -1847,8 +1867,7 @@ void CPPSourceEmitter::_getExportStyle(IRInst* inst, bool& outIsExport, bool& ou
{
outIsExternC = true;
}
- else if (op == kIROp_PublicDecoration ||
- op == kIROp_HLSLExportDecoration)
+ else if (op == kIROp_PublicDecoration || op == kIROp_HLSLExportDecoration)
{
outIsExport = true;
}
@@ -1861,7 +1880,7 @@ void CPPSourceEmitter::_maybeEmitExportLike(IRInst* inst)
bool isExternC = false;
bool isExported = false;
_getExportStyle(inst, isExternC, isExported);
-
+
// TODO(JS): Currently export *also* implies it's extern "C" and we can't list twice
if (isExported)
{
@@ -1874,7 +1893,7 @@ void CPPSourceEmitter::_maybeEmitExportLike(IRInst* inst)
}
}
-/* virtual */void CPPSourceEmitter::emitFuncDecorationsImpl(IRFunc* func)
+/* virtual */ void CPPSourceEmitter::emitFuncDecorationsImpl(IRFunc* func)
{
_maybeEmitExportLike(func);
@@ -1882,7 +1901,7 @@ void CPPSourceEmitter::_maybeEmitExportLike(IRInst* inst)
Super::emitFuncDecorationsImpl(func);
}
-void CPPSourceEmitter::emitOperandImpl(IRInst* inst, EmitOpInfo const& outerPrec)
+void CPPSourceEmitter::emitOperandImpl(IRInst* inst, EmitOpInfo const& outerPrec)
{
if (shouldFoldInstIntoUseSites(inst))
{
@@ -1892,27 +1911,23 @@ void CPPSourceEmitter::emitOperandImpl(IRInst* inst, EmitOpInfo const& outerPre
switch (inst->getOp())
{
- case kIROp_Var:
- case kIROp_GlobalVar:
- emitVarExpr(inst, outerPrec);
- break;
- default:
- m_writer->emit(getName(inst));
- break;
+ case kIROp_Var:
+ case kIROp_GlobalVar: emitVarExpr(inst, outerPrec); break;
+ default: m_writer->emit(getName(inst)); break;
}
}
-/* static */bool CPPSourceEmitter::_isVariable(IROp op)
+/* static */ bool CPPSourceEmitter::_isVariable(IROp op)
{
switch (op)
{
- case kIROp_GlobalVar:
- case kIROp_GlobalParam:
- //case kIROp_Var:
+ case kIROp_GlobalVar:
+ case kIROp_GlobalParam:
+ // case kIROp_Var:
{
return true;
}
- default: return false;
+ default: return false;
}
}
@@ -1921,10 +1936,13 @@ static bool _isFunction(IROp op)
return op == kIROp_Func;
}
-void CPPSourceEmitter::_emitEntryPointDefinitionStart(IRFunc* func, const String& funcName, const UnownedStringSlice& varyingTypeName)
+void CPPSourceEmitter::_emitEntryPointDefinitionStart(
+ IRFunc* func,
+ const String& funcName,
+ const UnownedStringSlice& varyingTypeName)
{
auto resultType = func->getResultType();
-
+
auto entryPointDecl = func->findDecoration<IREntryPointDecoration>();
SLANG_ASSERT(entryPointDecl);
@@ -1948,20 +1966,27 @@ void CPPSourceEmitter::_emitEntryPointDefinitionEnd(IRFunc* func)
m_writer->emit("}\n");
}
-namespace { // anonymous
+namespace
+{ // anonymous
struct AxisWithSize
{
typedef AxisWithSize ThisType;
- bool operator<(const ThisType& rhs) const { return size < rhs.size || (size == rhs.size && axis < rhs.axis); }
+ bool operator<(const ThisType& rhs) const
+ {
+ return size < rhs.size || (size == rhs.size && axis < rhs.axis);
+ }
int axis;
Int size;
};
-} // anonymous
+} // namespace
-static void _calcAxisOrder(const Int sizeAlongAxis[CLikeSourceEmitter::kThreadGroupAxisCount], bool allowSingle, List<AxisWithSize>& out)
+static void _calcAxisOrder(
+ const Int sizeAlongAxis[CLikeSourceEmitter::kThreadGroupAxisCount],
+ bool allowSingle,
+ List<AxisWithSize>& out)
{
out.clear();
// Add in order z,y,x, so by default (if we don't sort), x will be the inner loop
@@ -1981,7 +2006,9 @@ static void _calcAxisOrder(const Int sizeAlongAxis[CLikeSourceEmitter::kThreadGr
// axes.sort();
}
-void CPPSourceEmitter::_emitEntryPointGroup(const Int sizeAlongAxis[kThreadGroupAxisCount], const String& funcName)
+void CPPSourceEmitter::_emitEntryPointGroup(
+ const Int sizeAlongAxis[kThreadGroupAxisCount],
+ const String& funcName)
{
List<AxisWithSize> axes;
_calcAxisOrder(sizeAlongAxis, false, axes);
@@ -1992,8 +2019,9 @@ void CPPSourceEmitter::_emitEntryPointGroup(const Int sizeAlongAxis[kThreadGroup
{
const auto& axis = axes[i];
builder.clear();
- const char elem[2] = { s_xyzwNames[axis.axis], 0 };
- builder << "for (uint32_t " << elem << " = 0; " << elem << " < " << axis.size << "; ++" << elem << ")\n{\n";
+ const char elem[2] = {s_xyzwNames[axis.axis], 0};
+ builder << "for (uint32_t " << elem << " = 0; " << elem << " < " << axis.size << "; ++"
+ << elem << ")\n{\n";
m_writer->emit(builder);
m_writer->indent();
@@ -2015,7 +2043,9 @@ void CPPSourceEmitter::_emitEntryPointGroup(const Int sizeAlongAxis[kThreadGroup
}
}
-void CPPSourceEmitter::_emitEntryPointGroupRange(const Int sizeAlongAxis[kThreadGroupAxisCount], const String& funcName)
+void CPPSourceEmitter::_emitEntryPointGroupRange(
+ const Int sizeAlongAxis[kThreadGroupAxisCount],
+ const String& funcName)
{
List<AxisWithSize> axes;
_calcAxisOrder(sizeAlongAxis, true, axes);
@@ -2026,9 +2056,10 @@ void CPPSourceEmitter::_emitEntryPointGroupRange(const Int sizeAlongAxis[kThread
{
const auto& axis = axes[i];
builder.clear();
- const char elem[2] = { s_xyzwNames[axis.axis], 0 };
+ const char elem[2] = {s_xyzwNames[axis.axis], 0};
- builder << "for (uint32_t " << elem << " = vi.startGroupID." << elem << "; " << elem << " < vi.endGroupID." << elem << "; ++" << elem << ")\n{\n";
+ builder << "for (uint32_t " << elem << " = vi.startGroupID." << elem << "; " << elem
+ << " < vi.endGroupID." << elem << "; ++" << elem << ")\n{\n";
m_writer->emit(builder);
m_writer->indent();
@@ -2050,7 +2081,10 @@ void CPPSourceEmitter::_emitEntryPointGroupRange(const Int sizeAlongAxis[kThread
m_writer->emit("}\n");
}
}
-void CPPSourceEmitter::_emitInitAxisValues(const Int sizeAlongAxis[kThreadGroupAxisCount], const UnownedStringSlice& mulName, const UnownedStringSlice& addName)
+void CPPSourceEmitter::_emitInitAxisValues(
+ const Int sizeAlongAxis[kThreadGroupAxisCount],
+ const UnownedStringSlice& mulName,
+ const UnownedStringSlice& addName)
{
StringBuilder builder;
@@ -2059,7 +2093,7 @@ void CPPSourceEmitter::_emitInitAxisValues(const Int sizeAlongAxis[kThreadGroupA
for (int i = 0; i < kThreadGroupAxisCount; ++i)
{
builder.clear();
- const char elem[2] = { s_xyzwNames[i], 0 };
+ const char elem[2] = {s_xyzwNames[i], 0};
builder << mulName << "." << elem << " * " << sizeAlongAxis[i];
if (addName.getLength() > 0)
{
@@ -2078,36 +2112,34 @@ void CPPSourceEmitter::_emitInitAxisValues(const Int sizeAlongAxis[kThreadGroupA
void CPPSourceEmitter::_emitForwardDeclarations(const List<EmitAction>& actions)
{
- // Emit forward declarations. Don't emit variables that need to be grouped or function definitions (which will ref those types)
+ // Emit forward declarations. Don't emit variables that need to be grouped or function
+ // definitions (which will ref those types)
for (auto action : actions)
{
switch (action.level)
{
- case EmitAction::Level::ForwardDeclaration:
+ case EmitAction::Level::ForwardDeclaration:
+ {
+ switch (action.inst->getOp())
{
- switch (action.inst->getOp())
- {
- case kIROp_Func:
- case kIROp_StructType:
- case kIROp_InterfaceType:
- emitForwardDeclaration(action.inst);
- break;
- default:
- break;
- }
+ case kIROp_Func:
+ case kIROp_StructType:
+ case kIROp_InterfaceType: emitForwardDeclaration(action.inst); break;
+ default: break;
}
- break;
+ }
+ break;
- case EmitAction::Level::Definition:
- if (_isVariable(action.inst->getOp()) || _isFunction(action.inst->getOp()))
- {
- // Don't emit functions or variables that have to be grouped into structures yet
- }
- else
- {
- emitGlobalInst(action.inst);
- }
- break;
+ case EmitAction::Level::Definition:
+ if (_isVariable(action.inst->getOp()) || _isFunction(action.inst->getOp()))
+ {
+ // Don't emit functions or variables that have to be grouped into structures yet
+ }
+ else
+ {
+ emitGlobalInst(action.inst);
+ }
+ break;
}
}
}
@@ -2118,14 +2150,15 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink)
List<EmitAction> actions;
computeEmitActions(module, actions);
-
+
_emitForwardDeclarations(actions);
{
- // Output all the thread locals
+ // Output all the thread locals
for (auto action : actions)
{
- if (action.level == EmitAction::Level::Definition && action.inst->getOp() == kIROp_GlobalVar)
+ if (action.level == EmitAction::Level::Definition &&
+ action.inst->getOp() == kIROp_GlobalVar)
{
emitGlobalInst(action.inst);
}
@@ -2144,18 +2177,18 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink)
// Emit all witness table definitions.
_emitWitnessTableDefinitions();
- // TODO(JS):
+ // TODO(JS):
// Previously output code was placed in an anonymous namespace
// Now that we can have any function available externally (not just entry points)
- // this doesn't work.
+ // this doesn't work.
- //if (m_target == CodeGenTarget::CPPSource)
+ // if (m_target == CodeGenTarget::CPPSource)
//{
- // Need to close the anonymous namespace when outputting for C++ kernel.
- //m_writer->emit("} // anonymous\n\n");
+ // Need to close the anonymous namespace when outputting for C++ kernel.
+ // m_writer->emit("} // anonymous\n\n");
//}
- // Finally we need to output dll entry points
+ // Finally we need to output dll entry points
for (auto action : actions)
{
@@ -2163,13 +2196,14 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink)
{
IRFunc* func = as<IRFunc>(action.inst);
- IREntryPointDecoration* entryPointDecor = func->findDecoration<IREntryPointDecoration>();
-
+ IREntryPointDecoration* entryPointDecor =
+ func->findDecoration<IREntryPointDecoration>();
+
if (entryPointDecor && entryPointDecor->getProfile().getStage() == Stage::Compute)
{
Int groupThreadSize[kThreadGroupAxisCount];
getComputeThreadGroupSize(func, groupThreadSize);
-
+
String funcName = getName(func);
{
@@ -2178,7 +2212,10 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink)
String threadFuncName = builder;
- _emitEntryPointDefinitionStart(func, threadFuncName, UnownedStringSlice::fromLiteral("ComputeThreadVaryingInput"));
+ _emitEntryPointDefinitionStart(
+ func,
+ threadFuncName,
+ UnownedStringSlice::fromLiteral("ComputeThreadVaryingInput"));
m_writer->emit("_");
m_writer->emit(funcName);
@@ -2195,7 +2232,10 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink)
String groupFuncName = builder;
- _emitEntryPointDefinitionStart(func, groupFuncName, UnownedStringSlice::fromLiteral("ComputeVaryingInput"));
+ _emitEntryPointDefinitionStart(
+ func,
+ groupFuncName,
+ UnownedStringSlice::fromLiteral("ComputeVaryingInput"));
m_writer->emit("ComputeThreadVaryingInput threadInput = {};\n");
m_writer->emit("threadInput.groupID = varyingInput->startGroupID;\n");
@@ -2206,7 +2246,10 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink)
// Emit the main version - which takes a dispatch size
{
- _emitEntryPointDefinitionStart(func, funcName, UnownedStringSlice::fromLiteral("ComputeVaryingInput"));
+ _emitEntryPointDefinitionStart(
+ func,
+ funcName,
+ UnownedStringSlice::fromLiteral("ComputeVaryingInput"));
m_writer->emit("ComputeVaryingInput vi = *varyingInput;\n");
m_writer->emit("ComputeVaryingInput groupVaryingInput = {};\n");