summaryrefslogtreecommitdiff
path: root/source/slang/slang-emit-c-like.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-c-like.cpp
parenta729c15e9dce9f5116a38afc66329ab2ca4cea54 (diff)
format
* format * Minor test fixes * enable checking cpp format in ci
Diffstat (limited to 'source/slang/slang-emit-c-like.cpp')
-rw-r--r--source/slang/slang-emit-c-like.cpp1657
1 files changed, 811 insertions, 846 deletions
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index 417d454fb..8b0794ef2 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -1,101 +1,98 @@
// slang-emit-c-like.cpp
#include "slang-emit-c-like.h"
-#include "../core/slang-writer.h"
#include "../compiler-core/slang-name.h"
#include "../core/slang-stable-hash.h"
-
+#include "../core/slang-writer.h"
+#include "slang-emit-source-writer.h"
+#include "slang-intrinsic-expand.h"
#include "slang-ir-bind-existentials.h"
#include "slang-ir-dce.h"
#include "slang-ir-entry-point-uniforms.h"
#include "slang-ir-glsl-legalize.h"
-
#include "slang-ir-link.h"
#include "slang-ir-restructure-scoping.h"
-#include "slang-ir-specialize.h"
#include "slang-ir-specialize-resources.h"
+#include "slang-ir-specialize.h"
#include "slang-ir-ssa.h"
#include "slang-ir-util.h"
#include "slang-ir-validate.h"
#include "slang-legalize-types.h"
#include "slang-lower-to-ir.h"
#include "slang-mangle.h"
-
+#include "slang-mangled-lexer.h"
#include "slang-syntax.h"
#include "slang-type-layout.h"
#include "slang-visitor.h"
-
-#include "slang-intrinsic-expand.h"
-
-#include "slang-emit-source-writer.h"
-#include "slang-mangled-lexer.h"
#include "slang/slang-ir.h"
+
#include <assert.h>
-namespace Slang {
+namespace Slang
+{
bool isCPUTarget(TargetRequest* targetReq);
bool isCUDATarget(TargetRequest* targetReq);
struct CLikeSourceEmitter::ComputeEmitActionsContext
{
- IRInst* moduleInst;
- InstHashSet openInsts;
+ IRInst* moduleInst;
+ InstHashSet openInsts;
Dictionary<IRInst*, EmitAction::Level> mapInstToLevel;
- List<EmitAction>* actions;
+ List<EmitAction>* actions;
};
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!! CLikeSourceEmitter !!!!!!!!!!!!!!!!!!!!!!!!!! */
-/* static */SourceLanguage CLikeSourceEmitter::getSourceLanguage(CodeGenTarget target)
+/* static */ SourceLanguage CLikeSourceEmitter::getSourceLanguage(CodeGenTarget target)
{
switch (target)
{
- default:
- case CodeGenTarget::Unknown:
- case CodeGenTarget::None:
+ default:
+ case CodeGenTarget::Unknown:
+ case CodeGenTarget::None:
{
return SourceLanguage::Unknown;
}
- case CodeGenTarget::GLSL:
+ case CodeGenTarget::GLSL:
{
return SourceLanguage::GLSL;
}
- case CodeGenTarget::HLSL:
+ case CodeGenTarget::HLSL:
{
return SourceLanguage::HLSL;
}
- case CodeGenTarget::PTX:
- case CodeGenTarget::SPIRV:
- case CodeGenTarget::SPIRVAssembly:
- case CodeGenTarget::DXBytecode:
- case CodeGenTarget::DXBytecodeAssembly:
- case CodeGenTarget::DXIL:
- case CodeGenTarget::DXILAssembly:
- case CodeGenTarget::MetalLib:
- case CodeGenTarget::MetalLibAssembly:
+ case CodeGenTarget::PTX:
+ case CodeGenTarget::SPIRV:
+ case CodeGenTarget::SPIRVAssembly:
+ case CodeGenTarget::DXBytecode:
+ case CodeGenTarget::DXBytecodeAssembly:
+ case CodeGenTarget::DXIL:
+ case CodeGenTarget::DXILAssembly:
+ case CodeGenTarget::MetalLib:
+ case CodeGenTarget::MetalLibAssembly:
{
return SourceLanguage::Unknown;
}
- case CodeGenTarget::CSource:
+ case CodeGenTarget::CSource:
{
return SourceLanguage::C;
}
- case CodeGenTarget::CPPSource:
- case CodeGenTarget::HostCPPSource:
- case CodeGenTarget::PyTorchCppBinding:
+ case CodeGenTarget::CPPSource:
+ case CodeGenTarget::HostCPPSource:
+ case CodeGenTarget::PyTorchCppBinding:
{
return SourceLanguage::CPP;
}
- case CodeGenTarget::CUDASource:
+ case CodeGenTarget::CUDASource:
{
return SourceLanguage::CUDA;
}
- case CodeGenTarget::Metal:
+ case CodeGenTarget::Metal:
{
return SourceLanguage::Metal;
}
- case CodeGenTarget::WGSL:
+ case CodeGenTarget::WGSL:
{
return SourceLanguage::WGSL;
}
@@ -133,8 +130,8 @@ void CLikeSourceEmitter::emitPreModuleImpl()
}
}
void CLikeSourceEmitter::emitPostModuleImpl()
-{
- if(m_requiredAfter.requireComputeDerivatives.getLength() > 0)
+{
+ if (m_requiredAfter.requireComputeDerivatives.getLength() > 0)
{
m_writer->emit(m_requiredAfter.requireComputeDerivatives);
m_writer->emit("\n");
@@ -147,7 +144,8 @@ void CLikeSourceEmitter::emitPostModuleImpl()
void CLikeSourceEmitter::ensureTypePrelude(IRType* type)
{
- if (auto requirePreludeDecor = as<IRRequirePreludeDecoration>(findBestTargetDecoration<IRRequirePreludeDecoration>(type)))
+ if (auto requirePreludeDecor = as<IRRequirePreludeDecoration>(
+ findBestTargetDecoration<IRRequirePreludeDecoration>(type)))
{
auto preludeTextInst = as<IRStringLit>(requirePreludeDecor->getOperand(1));
if (preludeTextInst)
@@ -157,7 +155,8 @@ void CLikeSourceEmitter::ensureTypePrelude(IRType* type)
void CLikeSourceEmitter::emitDeclaratorImpl(DeclaratorInfo* declarator)
{
- if (!declarator) return;
+ if (!declarator)
+ return;
m_writer->emit(" ");
@@ -175,7 +174,7 @@ void CLikeSourceEmitter::emitDeclaratorImpl(DeclaratorInfo* declarator)
auto arrayDeclarator = (SizedArrayDeclaratorInfo*)declarator;
emitDeclarator(arrayDeclarator->next);
m_writer->emit("[");
- if(auto elementCount = arrayDeclarator->elementCount)
+ if (auto elementCount = arrayDeclarator->elementCount)
{
emitVal(elementCount, getInfo(EmitOp::General));
}
@@ -226,16 +225,14 @@ void CLikeSourceEmitter::emitDeclaratorImpl(DeclaratorInfo* declarator)
{
auto attributedDeclarator = (AttributedDeclaratorInfo*)declarator;
auto instWithAttributes = attributedDeclarator->instWithAttributes;
- for(auto attr : instWithAttributes->getAllAttrs())
+ for (auto attr : instWithAttributes->getAllAttrs())
{
_emitPostfixTypeAttr(attr);
}
emitDeclarator(attributedDeclarator->next);
}
break;
- default:
- SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unknown declarator flavor");
- break;
+ default: SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unknown declarator flavor"); break;
}
}
@@ -248,33 +245,35 @@ void CLikeSourceEmitter::emitSimpleType(IRType* type)
{
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("int");
- 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("int");
+ 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("uint");
- 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("uint");
+ case kIROp_UInt64Type: return UnownedStringSlice("uint64_t");
+ case kIROp_UIntPtrType: return UnownedStringSlice("uintptr_t");
- 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_FloatType: return UnownedStringSlice("float");
+ case kIROp_DoubleType: return UnownedStringSlice("double");
- case kIROp_CharType: return UnownedStringSlice("uint8_t");
- default: return UnownedStringSlice();
+ case kIROp_CharType: return UnownedStringSlice("uint8_t");
+ default: return UnownedStringSlice();
}
}
-/* static */IRNumThreadsDecoration* CLikeSourceEmitter::getComputeThreadGroupSize(IRFunc* func, Int outNumThreads[kThreadGroupAxisCount])
+/* static */ IRNumThreadsDecoration* CLikeSourceEmitter::getComputeThreadGroupSize(
+ IRFunc* func,
+ Int outNumThreads[kThreadGroupAxisCount])
{
IRNumThreadsDecoration* decor = func->findDecoration<IRNumThreadsDecoration>();
for (int i = 0; i < 3; ++i)
@@ -284,7 +283,9 @@ void CLikeSourceEmitter::emitSimpleType(IRType* type)
return decor;
}
-/* static */IRWaveSizeDecoration* CLikeSourceEmitter::getComputeWaveSize(IRFunc* func, Int* outWaveSize)
+/* static */ IRWaveSizeDecoration* CLikeSourceEmitter::getComputeWaveSize(
+ IRFunc* func,
+ Int* outWaveSize)
{
IRWaveSizeDecoration* decor = func->findDecoration<IRWaveSizeDecoration>();
if (decor)
@@ -294,7 +295,8 @@ void CLikeSourceEmitter::emitSimpleType(IRType* type)
return decor;
}
-List<IRWitnessTableEntry*> CLikeSourceEmitter::getSortedWitnessTableEntries(IRWitnessTable* witnessTable)
+List<IRWitnessTableEntry*> CLikeSourceEmitter::getSortedWitnessTableEntries(
+ IRWitnessTable* witnessTable)
{
List<IRWitnessTableEntry*> sortedWitnessTableEntries;
auto interfaceType = cast<IRInterfaceType>(witnessTable->getConformanceType());
@@ -355,9 +357,7 @@ void CLikeSourceEmitter::_emitType(IRType* type, DeclaratorInfo* declarator)
{
switch (type->getOp())
{
- default:
- emitSimpleTypeAndDeclarator(type, declarator);
- break;
+ default: emitSimpleTypeAndDeclarator(type, declarator); break;
case kIROp_RateQualifiedType:
{
@@ -385,7 +385,7 @@ void CLikeSourceEmitter::_emitType(IRType* type, DeclaratorInfo* declarator)
case kIROp_AttributedType:
{
auto attributedType = cast<IRAttributedType>(type);
- for(auto attr : attributedType->getAllAttrs())
+ for (auto attr : attributedType->getAllAttrs())
{
_emitPrefixTypeAttr(attr);
}
@@ -420,7 +420,7 @@ void CLikeSourceEmitter::_emitSwizzleStorePerElement(IRInst* inst)
UInt elementIndex = (UInt)irConst->value.intVal;
SLANG_RELEASE_ASSERT(elementIndex < 4);
- char const* kComponents[] = { "x", "y", "z", "w" };
+ char const* kComponents[] = {"x", "y", "z", "w"};
m_writer->emit(kComponents[elementIndex]);
maybeCloseParens(needCloseSubscript);
@@ -511,7 +511,9 @@ void CLikeSourceEmitter::defaultEmitInstStmt(IRInst* inst)
m_writer->emit("uint ");
m_writer->emit(stride);
m_writer->emit(";\n");
- emitOperand(inst->getOperand(0), leftSide(getInfo(EmitOp::General), getInfo(EmitOp::Postfix)));
+ emitOperand(
+ inst->getOperand(0),
+ leftSide(getInfo(EmitOp::General), getInfo(EmitOp::Postfix)));
m_writer->emit(".GetDimensions(");
m_writer->emit(count);
m_writer->emit(", ");
@@ -525,11 +527,8 @@ void CLikeSourceEmitter::defaultEmitInstStmt(IRInst* inst)
m_writer->emit(");\n");
}
break;
- case kIROp_discard:
- m_writer->emit("discard;\n");
- break;
- default:
- diagnoseUnhandledInst(inst);
+ case kIROp_discard: m_writer->emit("discard;\n"); break;
+ default: diagnoseUnhandledInst(inst);
}
}
@@ -576,7 +575,7 @@ void CLikeSourceEmitter::emitType(IRType* type, Name* name, SourceLoc const& nam
StringSliceLoc nameAndLoc;
nameAndLoc.loc = nameLoc;
nameAndLoc.name = name->text.getUnownedSlice();
-
+
emitType(type, &nameAndLoc);
}
@@ -588,7 +587,7 @@ void CLikeSourceEmitter::emitType(IRType* type, NameLoc const& nameAndLoc)
void CLikeSourceEmitter::emitLivenessImpl(IRInst* inst)
{
-
+
auto liveMarker = as<IRLiveRangeMarker>(inst);
if (!liveMarker)
{
@@ -601,17 +600,17 @@ void CLikeSourceEmitter::emitLivenessImpl(IRInst* inst)
UnownedStringSlice text;
switch (inst->getOp())
{
- case kIROp_LiveRangeStart:
+ case kIROp_LiveRangeStart:
{
text = UnownedStringSlice::fromLiteral("SLANG_LIVE_START");
break;
}
- case kIROp_LiveRangeEnd:
+ case kIROp_LiveRangeEnd:
{
text = UnownedStringSlice::fromLiteral("SLANG_LIVE_END");
break;
}
- default: break;
+ default: break;
}
m_writer->emit(text);
@@ -628,40 +627,44 @@ void CLikeSourceEmitter::emitLivenessImpl(IRInst* inst)
bool CLikeSourceEmitter::maybeEmitParens(EmitOpInfo& outerPrec, const EmitOpInfo& prec)
{
- bool needParens = (prec.leftPrecedence <= outerPrec.leftPrecedence)
- || (prec.rightPrecedence <= outerPrec.rightPrecedence);
+ bool needParens = (prec.leftPrecedence <= outerPrec.leftPrecedence) ||
+ (prec.rightPrecedence <= outerPrec.rightPrecedence);
// While Slang correctly removes some of parentheses, many compilers print warnings
// for common mistakes when parentheses are not used with certain combinations
// of the operations. We emit parentheses to avoid the warnings.
//
// a | b & c => a | (b & c)
- if (prec.leftPrecedence == EPrecedence::kEPrecedence_BitAnd_Left
- && outerPrec.leftPrecedence == EPrecedence::kEPrecedence_BitOr_Right)
+ if (prec.leftPrecedence == EPrecedence::kEPrecedence_BitAnd_Left &&
+ outerPrec.leftPrecedence == EPrecedence::kEPrecedence_BitOr_Right)
{
needParens = true;
}
// a & b | c => (a & b) | c
- else if (prec.rightPrecedence == EPrecedence::kEPrecedence_BitAnd_Right
- && outerPrec.rightPrecedence == EPrecedence::kEPrecedence_BitOr_Left)
+ else if (
+ prec.rightPrecedence == EPrecedence::kEPrecedence_BitAnd_Right &&
+ outerPrec.rightPrecedence == EPrecedence::kEPrecedence_BitOr_Left)
{
needParens = true;
}
// a << b + c => a << (b + c)
- else if (prec.leftPrecedence == EPrecedence::kEPrecedence_Additive_Left
- && outerPrec.leftPrecedence == EPrecedence::kEPrecedence_Shift_Right)
+ else if (
+ prec.leftPrecedence == EPrecedence::kEPrecedence_Additive_Left &&
+ outerPrec.leftPrecedence == EPrecedence::kEPrecedence_Shift_Right)
{
needParens = true;
}
// a + b << c => (a + b) << c
- else if (prec.rightPrecedence == EPrecedence::kEPrecedence_Additive_Right
- && outerPrec.rightPrecedence == EPrecedence::kEPrecedence_Shift_Left)
+ else if (
+ prec.rightPrecedence == EPrecedence::kEPrecedence_Additive_Right &&
+ outerPrec.rightPrecedence == EPrecedence::kEPrecedence_Shift_Left)
{
needParens = true;
}
// a + b & c => (a + b) & c
- else if (prec.rightPrecedence == EPrecedence::kEPrecedence_Additive_Right
- && outerPrec.rightPrecedence == EPrecedence::kEPrecedence_BitAnd_Left)
+ else if (
+ prec.rightPrecedence == EPrecedence::kEPrecedence_Additive_Right &&
+ outerPrec.rightPrecedence == EPrecedence::kEPrecedence_BitAnd_Left)
{
needParens = true;
}
@@ -677,7 +680,8 @@ bool CLikeSourceEmitter::maybeEmitParens(EmitOpInfo& outerPrec, const EmitOpInfo
void CLikeSourceEmitter::maybeCloseParens(bool needClose)
{
- if(needClose) m_writer->emit(")");
+ if (needClose)
+ m_writer->emit(")");
}
void CLikeSourceEmitter::emitStringLiteral(String const& value)
@@ -688,12 +692,10 @@ void CLikeSourceEmitter::emitStringLiteral(String const& value)
// TODO: This needs a more complete implementation,
// especially if we want to support Unicode.
- char buffer[] = { c, 0 };
+ char buffer[] = {c, 0};
switch (c)
{
- default:
- m_writer->emit(buffer);
- break;
+ default: m_writer->emit(buffer); break;
case '\"': m_writer->emit("\\\""); break;
case '\'': m_writer->emit("\\\'"); break;
@@ -708,7 +710,7 @@ void CLikeSourceEmitter::emitStringLiteral(String const& value)
void CLikeSourceEmitter::emitVal(IRInst* val, EmitOpInfo const& outerPrec)
{
- if(auto type = as<IRType>(val))
+ if (auto type = as<IRType>(val))
{
emitType(type);
}
@@ -718,7 +720,9 @@ void CLikeSourceEmitter::emitVal(IRInst* val, EmitOpInfo const& outerPrec)
}
}
-UInt CLikeSourceEmitter::getBindingOffsetForKinds(EmitVarChain* chain, LayoutResourceKindFlags kindFlags)
+UInt CLikeSourceEmitter::getBindingOffsetForKinds(
+ EmitVarChain* chain,
+ LayoutResourceKindFlags kindFlags)
{
UInt offset = 0;
for (auto cc = chain; cc; cc = cc->next)
@@ -738,7 +742,9 @@ UInt CLikeSourceEmitter::getBindingOffsetForKinds(EmitVarChain* chain, LayoutRes
Index findRegisterSpaceResourceInfo(IRVarLayout* layout);
-UInt CLikeSourceEmitter::getBindingSpaceForKinds(EmitVarChain* chain, LayoutResourceKindFlags kindFlags)
+UInt CLikeSourceEmitter::getBindingSpaceForKinds(
+ EmitVarChain* chain,
+ LayoutResourceKindFlags kindFlags)
{
UInt space = 0;
@@ -767,7 +773,8 @@ UInt CLikeSourceEmitter::getBindingSpaceForKinds(EmitVarChain* chain, LayoutReso
}
else
{
- if (auto resInfo = varLayout->findOffsetAttr(LayoutResourceKind::SubElementRegisterSpace))
+ if (auto resInfo =
+ varLayout->findOffsetAttr(LayoutResourceKind::SubElementRegisterSpace))
{
space += resInfo->getOffset();
}
@@ -780,9 +787,9 @@ UInt CLikeSourceEmitter::getBindingOffset(EmitVarChain* chain, LayoutResourceKin
{
UInt offset = 0;
- for(auto cc = chain; cc; cc = cc->next)
+ for (auto cc = chain; cc; cc = cc->next)
{
- if(auto resInfo = cc->varLayout->findOffsetAttr(kind))
+ if (auto resInfo = cc->varLayout->findOffsetAttr(kind))
{
offset += resInfo->getOffset();
}
@@ -794,10 +801,10 @@ UInt CLikeSourceEmitter::getBindingSpace(EmitVarChain* chain, LayoutResourceKind
{
UInt space = 0;
bool useSubElementSpace = false;
- for(auto cc = chain; cc; cc = cc->next)
+ for (auto cc = chain; cc; cc = cc->next)
{
auto varLayout = cc->varLayout;
- if(auto resInfo = varLayout->findOffsetAttr(kind))
+ if (auto resInfo = varLayout->findOffsetAttr(kind))
{
space += resInfo->getSpace();
}
@@ -812,7 +819,8 @@ UInt CLikeSourceEmitter::getBindingSpace(EmitVarChain* chain, LayoutResourceKind
}
else
{
- if (auto resInfo = varLayout->findOffsetAttr(LayoutResourceKind::SubElementRegisterSpace))
+ if (auto resInfo =
+ varLayout->findOffsetAttr(LayoutResourceKind::SubElementRegisterSpace))
{
space += resInfo->getOffset();
}
@@ -850,21 +858,21 @@ void CLikeSourceEmitter::appendScrubbedName(const UnownedStringSlice& name, Stri
const char dummyChar = 'U';
// Special case a name that is the empty string, just in case.
- if(name.getLength() == 0)
+ if (name.getLength() == 0)
{
out.appendChar(dummyChar);
return;
}
-
+
// Otherwise, we are going to walk over the name byte by byte
// and write some legal characters to the output as we go.
-
- if(getSourceLanguage() == SourceLanguage::GLSL)
+
+ if (getSourceLanguage() == SourceLanguage::GLSL)
{
// GLSL reserves all names that start with `gl_`,
// so if we are in danger of collision, then make
// our name start with a dummy character instead.
- if(name.startsWith("gl_"))
+ if (name.startsWith("gl_"))
{
out.appendChar(dummyChar);
}
@@ -873,7 +881,7 @@ void CLikeSourceEmitter::appendScrubbedName(const UnownedStringSlice& name, Stri
// We will also detect user-defined names that
// might overlap with our convention for mangled names,
// to avoid an possible collision.
- if(name.startsWith("_S"))
+ if (name.startsWith("_S"))
{
out.appendChar(dummyChar);
}
@@ -888,7 +896,7 @@ void CLikeSourceEmitter::appendScrubbedName(const UnownedStringSlice& name, Stri
// order to detect consecutive underscores for GLSL.
int prevChar = -1;
- for(auto c : name)
+ for (auto c : name)
{
// We will treat a dot character or any path separator
// just like an underscore for the purposes of producing
@@ -902,35 +910,31 @@ void CLikeSourceEmitter::appendScrubbedName(const UnownedStringSlice& name, Stri
// a `_` in the original name, and will be properly
// scrubbed for GLSL output.
//
- switch(c)
+ switch (c)
{
- default:
- break;
+ default: break;
case '.':
case '\\':
- case '/':
- c = '_';
- break;
+ case '/': c = '_'; break;
}
- if(((c >= 'a') && (c <= 'z'))
- || ((c >= 'A') && (c <= 'Z')))
+ if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')))
{
// Ordinary ASCII alphabetic characters are assumed
// to always be okay.
}
- else if((c >= '0') && (c <= '9'))
+ else if ((c >= '0') && (c <= '9'))
{
// We don't want to allow a digit as the first
// byte in a name, since the result wouldn't
// be a valid identifier in many target languages.
- if(prevChar == -1)
+ if (prevChar == -1)
{
out.appendChar(dummyChar);
}
}
- else if(c == '_')
+ else if (c == '_')
{
// We will collapse any consecutive sequence of `_`
// characters into a single one (this means that
@@ -938,7 +942,7 @@ void CLikeSourceEmitter::appendScrubbedName(const UnownedStringSlice& name, Stri
// code might not resolve to unique names after
// scrubbing, but that was true in general).
- if(prevChar == '_')
+ if (prevChar == '_')
{
// Skip this underscore, so we don't output
// more than one in a row.
@@ -955,7 +959,7 @@ void CLikeSourceEmitter::appendScrubbedName(const UnownedStringSlice& name, Stri
// emit `x` and then the hexadecimal version of
// the byte we were given.
out.appendChar('x');
- out.append(uint32_t((unsigned char) c), 16);
+ out.append(uint32_t((unsigned char)c), 16);
// We don't want to apply the default handling below,
// so skip to the top of the loop now.
@@ -969,7 +973,8 @@ void CLikeSourceEmitter::appendScrubbedName(const UnownedStringSlice& name, Stri
if (getSourceLanguage() == SourceLanguage::GLSL)
{
- // It looks like the default glslang name limit is 1024, but let's go a little less so there is some wiggle room
+ // It looks like the default glslang name limit is 1024, but let's go a little less so there
+ // is some wiggle room
const Index maxTokenLength = 1024 - 8;
const Index length = out.getLength();
@@ -979,9 +984,10 @@ void CLikeSourceEmitter::appendScrubbedName(const UnownedStringSlice& name, Stri
// We are going to output with a prefix and a hash of the full name
const auto hash = getStableHashCode64(out.getBuffer(), length);
// Two hex chars per byte
- const Index hashSize = sizeof(hash) * 2;
+ const Index hashSize = sizeof(hash) * 2;
- // Work out a size that is within range taking into account the hash size and extra chars
+ // Work out a size that is within range taking into account the hash size and extra
+ // chars
Index reducedBaseLength = maxTokenLength - hashSize - 1;
// If it has a trailing _ remove it.
// We know because of scrubbing there can only be single _
@@ -1027,7 +1033,7 @@ String CLikeSourceEmitter::_generateUniqueName(const UnownedStringSlice& name)
// Except that we will "scrub" the name first,
// and we will omit the underscore if the (scrubbed)
// name hint already ends with one.
-
+
StringBuilder sb;
appendScrubbedName(name, sb);
@@ -1039,7 +1045,7 @@ String CLikeSourceEmitter::_generateUniqueName(const UnownedStringSlice& name)
}
String key = sb.produceString();
-
+
UInt& countRef = m_uniqueNameCounters.getOrAddValue(key, 0);
const UInt count = countRef;
countRef = count + 1;
@@ -1055,7 +1061,7 @@ String CLikeSourceEmitter::generateName(IRInst* inst)
// then use that name instead.
UnownedStringSlice intrinsicDef;
IRInst* intrinsicInst = nullptr;
- if(findTargetIntrinsicDefinition(inst, intrinsicDef, intrinsicInst))
+ if (findTargetIntrinsicDefinition(inst, intrinsicDef, intrinsicInst))
{
return String(intrinsicDef);
}
@@ -1067,7 +1073,7 @@ String CLikeSourceEmitter::generateName(IRInst* inst)
// or directly `#include`d version of those declarations during
// downstream compilation.
//
- if(auto nvapiDecor = inst->findDecoration<IRNVAPIMagicDecoration>())
+ if (auto nvapiDecor = inst->findDecoration<IRNVAPIMagicDecoration>())
{
return String(nvapiDecor->getName());
}
@@ -1109,16 +1115,16 @@ String CLikeSourceEmitter::generateName(IRInst* inst)
// Just use the linkages mangled name directly.
return externCppDecoration->getName();
}
-
+
// If we have a name hint on the instruction, then we will try to use that
// to provide the basis for the actual name in the output code.
- if(auto nameHintDecoration = inst->findDecoration<IRNameHintDecoration>())
+ if (auto nameHintDecoration = inst->findDecoration<IRNameHintDecoration>())
{
return _generateUniqueName(nameHintDecoration->getName());
}
- // If the instruction has a linkage decoration, just use that.
- if(auto linkageDecoration = inst->findDecoration<IRLinkageDecoration>())
+ // If the instruction has a linkage decoration, just use that.
+ if (auto linkageDecoration = inst->findDecoration<IRLinkageDecoration>())
{
// Just use the linkages mangled name directly.
return linkageDecoration->getMangledName();
@@ -1134,8 +1140,7 @@ String CLikeSourceEmitter::generateName(IRInst* inst)
sb << "_" << Int32(getID(inst));
return sb.produceString();
}
- default:
- break;
+ default: break;
}
// Otherwise fall back to a construct temporary name
// for the instruction.
@@ -1149,7 +1154,7 @@ String CLikeSourceEmitter::generateName(IRInst* inst)
String CLikeSourceEmitter::getName(IRInst* inst)
{
String name;
- if(!m_mapInstToName.tryGetValue(inst, name))
+ if (!m_mapInstToName.tryGetValue(inst, name))
{
name = generateName(inst);
m_mapInstToName.add(inst, name);
@@ -1166,114 +1171,112 @@ String CLikeSourceEmitter::getUnmangledName(IRInst* inst)
void CLikeSourceEmitter::emitSimpleValueImpl(IRInst* inst)
{
- switch(inst->getOp())
+ switch (inst->getOp())
{
case kIROp_IntLit:
- {
- auto litInst = static_cast<IRConstant*>(inst);
-
- IRBasicType* type = as<IRBasicType>(inst->getDataType());
- if (type)
{
- switch (type->getBaseType())
+ auto litInst = static_cast<IRConstant*>(inst);
+
+ IRBasicType* type = as<IRBasicType>(inst->getDataType());
+ if (type)
{
+ switch (type->getBaseType())
+ {
default:
-
+
case BaseType::Int8:
- {
- m_writer->emit("int8_t(");
- m_writer->emit(int8_t(litInst->value.intVal));
- m_writer->emit(")");
- return;
- }
+ {
+ m_writer->emit("int8_t(");
+ m_writer->emit(int8_t(litInst->value.intVal));
+ m_writer->emit(")");
+ return;
+ }
case BaseType::UInt8:
- {
- m_writer->emit("uint8_t(");
- m_writer->emit(UInt(uint8_t(litInst->value.intVal)));
- m_writer->emit("U");
- m_writer->emit(")");
- break;
- }
+ {
+ m_writer->emit("uint8_t(");
+ m_writer->emit(UInt(uint8_t(litInst->value.intVal)));
+ m_writer->emit("U");
+ m_writer->emit(")");
+ break;
+ }
case BaseType::Int16:
- {
- m_writer->emit("int16_t(");
- m_writer->emit(int16_t(litInst->value.intVal));
- m_writer->emit(")");
- return;
- }
+ {
+ m_writer->emit("int16_t(");
+ m_writer->emit(int16_t(litInst->value.intVal));
+ m_writer->emit(")");
+ return;
+ }
case BaseType::UInt16:
- {
- m_writer->emit("uint16_t(");
- m_writer->emit(UInt(uint16_t(litInst->value.intVal)));
- m_writer->emit("U");
- m_writer->emit(")");
- break;
- }
+ {
+ m_writer->emit("uint16_t(");
+ m_writer->emit(UInt(uint16_t(litInst->value.intVal)));
+ m_writer->emit("U");
+ m_writer->emit(")");
+ break;
+ }
case BaseType::Int:
- {
- m_writer->emit("int(");
- m_writer->emit(int32_t(litInst->value.intVal));
- m_writer->emit(")");
- return;
- }
+ {
+ m_writer->emit("int(");
+ m_writer->emit(int32_t(litInst->value.intVal));
+ m_writer->emit(")");
+ return;
+ }
case BaseType::UInt:
- {
- m_writer->emit(UInt(uint32_t(litInst->value.intVal)));
- m_writer->emit("U");
- break;
- }
+ {
+ m_writer->emit(UInt(uint32_t(litInst->value.intVal)));
+ m_writer->emit("U");
+ break;
+ }
case BaseType::Int64:
- {
- m_writer->emitInt64(int64_t(litInst->value.intVal));
- m_writer->emit("LL");
- break;
- }
+ {
+ m_writer->emitInt64(int64_t(litInst->value.intVal));
+ m_writer->emit("LL");
+ break;
+ }
case BaseType::UInt64:
- {
- SLANG_COMPILE_TIME_ASSERT(sizeof(litInst->value.intVal) >= sizeof(uint64_t));
- m_writer->emitUInt64(uint64_t(litInst->value.intVal));
- m_writer->emit("ULL");
- break;
- }
+ {
+ SLANG_COMPILE_TIME_ASSERT(
+ sizeof(litInst->value.intVal) >= sizeof(uint64_t));
+ m_writer->emitUInt64(uint64_t(litInst->value.intVal));
+ m_writer->emit("ULL");
+ break;
+ }
case BaseType::IntPtr:
- {
+ {
#if SLANG_PTR_IS_64
- m_writer->emit("int64_t(");
- m_writer->emitInt64(int64_t(litInst->value.intVal));
- m_writer->emit(")");
+ m_writer->emit("int64_t(");
+ m_writer->emitInt64(int64_t(litInst->value.intVal));
+ m_writer->emit(")");
#else
- m_writer->emit("int(");
- m_writer->emit(int(litInst->value.intVal));
- m_writer->emit(")");
+ m_writer->emit("int(");
+ m_writer->emit(int(litInst->value.intVal));
+ m_writer->emit(")");
#endif
- break;
- }
+ break;
+ }
case BaseType::UIntPtr:
- {
+ {
#if SLANG_PTR_IS_64
- m_writer->emit("uint64_t(");
- m_writer->emitUInt64(uint64_t(litInst->value.intVal));
- m_writer->emit(")");
+ m_writer->emit("uint64_t(");
+ m_writer->emitUInt64(uint64_t(litInst->value.intVal));
+ m_writer->emit(")");
#else
- m_writer->emit(UInt(uint32_t(litInst->value.intVal)));
- m_writer->emit("U");
+ m_writer->emit(UInt(uint32_t(litInst->value.intVal)));
+ m_writer->emit("U");
#endif
- break;
+ break;
+ }
}
-
}
+ else
+ {
+ // If no type... just output what we have
+ m_writer->emit(litInst->value.intVal);
+ }
+ break;
}
- else
- {
- // If no type... just output what we have
- m_writer->emit(litInst->value.intVal);
- }
- break;
- }
- case kIROp_FloatLit:
- m_writer->emit(((IRConstant*) inst)->value.floatVal);
- break;
+ case kIROp_FloatLit: m_writer->emit(((IRConstant*)inst)->value.floatVal); break;
case kIROp_BoolLit:
{
@@ -1282,20 +1285,16 @@ void CLikeSourceEmitter::emitSimpleValueImpl(IRInst* inst)
}
break;
- default:
- SLANG_UNIMPLEMENTED_X("val case for emit");
- break;
+ default: SLANG_UNIMPLEMENTED_X("val case for emit"); break;
}
-
}
bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
{
// Certain opcodes should never/always be folded in
- switch( inst->getOp() )
+ switch (inst->getOp())
{
- default:
- break;
+ default: break;
// Never fold these in, because they represent declarations
//
@@ -1306,15 +1305,13 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
case kIROp_Param:
case kIROp_Func:
case kIROp_Alloca:
- case kIROp_Store:
- return false;
+ case kIROp_Store: return false;
// Never fold these, because their result cannot be computed
// as a sub-expression (they must be emitted as a declaration
// or statement).
case kIROp_UpdateElement:
- case kIROp_DefaultConstruct:
- return false;
+ case kIROp_DefaultConstruct: return false;
// Always fold these in, because they are trivial
//
@@ -1322,8 +1319,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
case kIROp_FloatLit:
case kIROp_BoolLit:
case kIROp_CapabilityConjunction:
- case kIROp_CapabilityDisjunction:
- return true;
+ case kIROp_CapabilityDisjunction: return true;
// Always fold these in, because their results
// cannot be represented in the type system of
@@ -1337,29 +1333,25 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
case kIROp_GetElementPtr:
case kIROp_Specialize:
case kIROp_LookupWitness:
- case kIROp_GetValueFromBoundInterface:
- return true;
+ case kIROp_GetValueFromBoundInterface: return true;
- case kIROp_GetVulkanRayTracingPayloadLocation:
- return true;
+ case kIROp_GetVulkanRayTracingPayloadLocation: return true;
- case kIROp_NonUniformResourceIndex:
- return true;
+ case kIROp_NonUniformResourceIndex: return true;
}
// Layouts and attributes are only present to annotate other
// instructions, and should not be emitted as anything in
// source code.
//
- if(as<IRLayout>(inst))
+ if (as<IRLayout>(inst))
return true;
- if(as<IRAttr>(inst))
+ if (as<IRAttr>(inst))
return true;
- switch( inst->getOp() )
+ switch (inst->getOp())
{
- default:
- break;
+ default: break;
// HACK: don't fold these in because we currently lower
// them to initializer lists, which aren't allowed in
@@ -1368,9 +1360,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
case kIROp_MakeStruct:
case kIROp_MakeArray:
case kIROp_swizzleSet:
- case kIROp_MakeArrayFromElement:
- return false;
-
+ case kIROp_MakeArrayFromElement: return false;
}
// Instructions with specific result *types* will usually
@@ -1387,7 +1377,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
// then any types it constructs will be inlined into the body of the caller
// by default.
//
- if(as<IRType>(inst) || as<IRTypeKind>(type))
+ if (as<IRType>(inst) || as<IRTypeKind>(type))
return true;
// Unwrap any layers of array-ness from the type, so that
@@ -1400,7 +1390,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
// Don't allow temporaries of pointer types to be created,
// if target langauge doesn't support pointers.
- if(as<IRPtrTypeBase>(type))
+ if (as<IRPtrTypeBase>(type))
{
if (!doesTargetSupportPtrTypes())
return true;
@@ -1415,7 +1405,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
// cleans up cases where we use a parameter group
// or parameter block type as a function parameter...
//
- if(as<IRUniformParameterGroupType>(type))
+ if (as<IRUniformParameterGroupType>(type))
{
// TODO: we need to be careful here, because
// HLSL shader model 6 allows these as explicit
@@ -1442,23 +1432,23 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
// to fold them into their use sites in all cases
if (getSourceLanguage() == SourceLanguage::GLSL)
{
- if(as<IRResourceTypeBase>(type))
+ if (as<IRResourceTypeBase>(type))
{
return true;
}
- else if(as<IRHLSLStructuredBufferTypeBase>(type))
+ else if (as<IRHLSLStructuredBufferTypeBase>(type))
{
return true;
}
- else if(as<IRUntypedBufferResourceType>(type))
+ else if (as<IRUntypedBufferResourceType>(type))
{
return true;
}
- else if(as<IRSamplerStateTypeBase>(type))
+ else if (as<IRSamplerStateTypeBase>(type))
{
return true;
}
- else if(as<IRMeshOutputType>(type))
+ else if (as<IRMeshOutputType>(type))
{
return true;
}
@@ -1471,9 +1461,9 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
// If the instruction is at global scope, then it might represent
// a constant (e.g., the value of an enum case).
//
- if(as<IRModuleInst>(inst->getParent()))
+ if (as<IRModuleInst>(inst->getParent()))
{
- if(!inst->mightHaveSideEffects())
+ if (!inst->mightHaveSideEffects())
return true;
}
@@ -1481,7 +1471,8 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
if (auto call = as<IRCall>(inst))
{
auto callee = call->getCallee();
- if (getResolvedInstForDecorations(callee)->findDecoration<IRAlwaysFoldIntoUseSiteDecoration>())
+ if (getResolvedInstForDecorations(callee)
+ ->findDecoration<IRAlwaysFoldIntoUseSiteDecoration>())
{
return true;
}
@@ -1491,16 +1482,16 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
// above, we can now deal with the more general cases where we
// *should not* fold things.
// Don't fold something with no users:
- if(!inst->hasUses())
+ if (!inst->hasUses())
return false;
// Don't fold something that has multiple users:
- if(inst->hasMoreThanOneUse())
+ if (inst->hasMoreThanOneUse())
return false;
// Don't fold something that might have side effects:
- if(inst->mightHaveSideEffects())
+ if (inst->mightHaveSideEffects())
return false;
// Don't fold instructions that are marked `[precise]`.
@@ -1508,7 +1499,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
// decorations that affect the semantics of an instruction
// in ways that require a temporary to be introduced.
//
- if(inst->findDecoration<IRPreciseDecoration>())
+ if (inst->findDecoration<IRPreciseDecoration>())
return false;
// In general, undefined value should be emitted as an uninitialized
@@ -1535,22 +1526,24 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
const auto funcValue = callInst->getCallee();
// Let's see if this instruction is a intrinsic call
- // This is significant, because we can within a target intrinsics definition multiple accesses to the same
- // parameter. This is not indicated into the call, and can lead to output code computes something multiple
- // times as it is folding into the expression of the the target intrinsic, which we don't want.
+ // This is significant, because we can within a target intrinsics definition multiple
+ // accesses to the same parameter. This is not indicated into the call, and can lead to
+ // output code computes something multiple times as it is folding into the expression of the
+ // the target intrinsic, which we don't want.
UnownedStringSlice intrinsicDef;
IRInst* intrinsicInst;
if (findTargetIntrinsicDefinition(funcValue, intrinsicDef, intrinsicInst))
- {
+ {
// Find the index of the original instruction, to see if it's multiply used.
IRUse* args = callInst->getArgs();
const Index paramIndex = Index(use - args);
SLANG_ASSERT(paramIndex >= 0 && paramIndex < Index(callInst->getArgCount()));
- // Look through the slice to seeing how many times this parameters is used (signified via the $0...$9)
+ // Look through the slice to seeing how many times this parameters is used (signified
+ // via the $0...$9)
{
UnownedStringSlice slice = intrinsicDef;
-
+
const char* cur = slice.begin();
const char* end = slice.end();
@@ -1579,7 +1572,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
}
}
}
-
+
// If this is a call to a ResourceType's member function, don't fold for readability.
if (auto call = as<IRCall>(inst))
{
@@ -1614,22 +1607,22 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
if (as<IRSwizzledStore>(user))
{
if (isCPUTarget(getTargetReq()) || isCUDATarget(getTargetReq()))
- return false;
+ return false;
}
// We'd like to figure out if it is safe to fold our instruction into `user`
// First, let's make sure they are in the same block/parent:
- if(inst->getParent() != user->getParent())
+ if (inst->getParent() != user->getParent())
return false;
// Now let's look at all the instructions between this instruction
// and the user. If any of them might have side effects, then lets
// bail out now.
- for(auto ii = inst->getNextInst(); ii != user; ii = ii->getNextInst())
+ for (auto ii = inst->getNextInst(); ii != user; ii = ii->getNextInst())
{
- if(!ii)
+ if (!ii)
{
// We somehow reached the end of the block without finding
// the user, which doesn't make sense if uses dominate
@@ -1637,7 +1630,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
return false;
}
- if(ii->mightHaveSideEffects())
+ if (ii->mightHaveSideEffects())
return false;
}
@@ -1649,7 +1642,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
// into an unconditonal branch completely, and leave a more refined
// version of this check for later.
//
- if(as<IRUnconditionalBranch>(user))
+ if (as<IRUnconditionalBranch>(user))
return false;
// Okay, if we reach this point then the user comes later in
@@ -1674,77 +1667,67 @@ void CLikeSourceEmitter::emitDereferenceOperand(IRInst* inst, EmitOpInfo const&
m_writer->emit(getName(inst));
return;
case kIROp_FieldAddress:
- {
- auto innerPrec = getInfo(EmitOp::Postfix);
- bool innerNeedClose = maybeEmitParens(newOuterPrec, innerPrec);
- auto ii = as<IRFieldAddress>(inst);
- auto base = ii->getBase();
- if (isPtrToClassType(base->getDataType()))
- emitDereferenceOperand(base, leftSide(newOuterPrec, innerPrec));
- else
- emitOperand(base, leftSide(newOuterPrec, innerPrec));
- m_writer->emit("->");
- m_writer->emit(getName(ii->getField()));
- maybeCloseParens(innerNeedClose);
- return;
- }
- case kIROp_GetElementPtr:
- {
- const auto info = getInfo(EmitOp::Prefix);
- IRVectorType* vectorType = nullptr;
- if (auto ptrType = as<IRPtrTypeBase>(inst->getOperand(0)->getDataType()))
{
- vectorType = as<IRVectorType>(ptrType->getValueType());
+ auto innerPrec = getInfo(EmitOp::Postfix);
+ bool innerNeedClose = maybeEmitParens(newOuterPrec, innerPrec);
+ auto ii = as<IRFieldAddress>(inst);
+ auto base = ii->getBase();
+ if (isPtrToClassType(base->getDataType()))
+ emitDereferenceOperand(base, leftSide(newOuterPrec, innerPrec));
+ else
+ emitOperand(base, leftSide(newOuterPrec, innerPrec));
+ m_writer->emit("->");
+ m_writer->emit(getName(ii->getField()));
+ maybeCloseParens(innerNeedClose);
+ return;
}
- if (vectorType)
+ case kIROp_GetElementPtr:
{
- // Can't use simplified emit logic for get vector element operations on CUDA targets.
- if (isCUDATarget(m_codeGenContext->getTargetReq()))
- break;
- }
+ const auto info = getInfo(EmitOp::Prefix);
+ IRVectorType* vectorType = nullptr;
+ if (auto ptrType = as<IRPtrTypeBase>(inst->getOperand(0)->getDataType()))
+ {
+ vectorType = as<IRVectorType>(ptrType->getValueType());
+ }
+ if (vectorType)
+ {
+ // Can't use simplified emit logic for get vector element operations on CUDA
+ // targets.
+ if (isCUDATarget(m_codeGenContext->getTargetReq()))
+ break;
+ }
- auto rightSidePrec = rightSide(outerPrec, info);
- auto postfixInfo = getInfo(EmitOp::Postfix);
- bool rightSideNeedClose = maybeEmitParens(rightSidePrec, postfixInfo);
- emitDereferenceOperand(inst->getOperand(0), leftSide(rightSidePrec, postfixInfo));
- bool emitBracketPostfix = true;
- if (vectorType)
- {
- // Simplify the emitted code if we are referencing a known vector element.
- if (auto intLit = as<IRIntLit>(inst->getOperand(1)))
+ auto rightSidePrec = rightSide(outerPrec, info);
+ auto postfixInfo = getInfo(EmitOp::Postfix);
+ bool rightSideNeedClose = maybeEmitParens(rightSidePrec, postfixInfo);
+ emitDereferenceOperand(inst->getOperand(0), leftSide(rightSidePrec, postfixInfo));
+ bool emitBracketPostfix = true;
+ if (vectorType)
{
- emitBracketPostfix = false;
- switch (intLit->getValue())
+ // Simplify the emitted code if we are referencing a known vector element.
+ if (auto intLit = as<IRIntLit>(inst->getOperand(1)))
{
- case 0:
- m_writer->emit(".x");
- break;
- case 1:
- m_writer->emit(".y");
- break;
- case 2:
- m_writer->emit(".z");
- break;
- case 3:
- m_writer->emit(".w");
- break;
- default:
- emitBracketPostfix = true;
- break;
+ emitBracketPostfix = false;
+ switch (intLit->getValue())
+ {
+ case 0: m_writer->emit(".x"); break;
+ case 1: m_writer->emit(".y"); break;
+ case 2: m_writer->emit(".z"); break;
+ case 3: m_writer->emit(".w"); break;
+ default: emitBracketPostfix = true; break;
+ }
}
}
+ if (emitBracketPostfix)
+ {
+ m_writer->emit("[");
+ emitOperand(inst->getOperand(1), getInfo(EmitOp::General));
+ m_writer->emit("]");
+ }
+ maybeCloseParens(rightSideNeedClose);
+ return;
}
- if (emitBracketPostfix)
- {
- m_writer->emit("[");
- emitOperand(inst->getOperand(1), getInfo(EmitOp::General));
- m_writer->emit("]");
- }
- maybeCloseParens(rightSideNeedClose);
- return;
- }
- default:
- break;
+ default: break;
}
auto dereferencePrec = EmitOpInfo::get(EmitOp::Prefix);
@@ -1776,23 +1759,19 @@ void CLikeSourceEmitter::emitVarExpr(IRInst* inst, EmitOpInfo const& outerPrec)
}
}
-void CLikeSourceEmitter::emitOperandImpl(IRInst* inst, EmitOpInfo const& outerPrec)
+void CLikeSourceEmitter::emitOperandImpl(IRInst* inst, EmitOpInfo const& outerPrec)
{
- if( shouldFoldInstIntoUseSites(inst) )
+ if (shouldFoldInstIntoUseSites(inst))
{
emitInstExpr(inst, outerPrec);
return;
}
- switch(inst->getOp())
+ switch (inst->getOp())
{
case kIROp_Var:
- case kIROp_GlobalVar:
- emitVarExpr(inst, outerPrec);
- break;
- default:
- m_writer->emit(getName(inst));
- break;
+ case kIROp_GlobalVar: emitVarExpr(inst, outerPrec); break;
+ default: m_writer->emit(getName(inst)); break;
}
}
@@ -1802,9 +1781,10 @@ void CLikeSourceEmitter::emitArgs(IRInst* inst)
IRUse* args = inst->getOperands();
m_writer->emit("(");
- for(UInt aa = 0; aa < argCount; ++aa)
+ for (UInt aa = 0; aa < argCount; ++aa)
{
- if(aa != 0) m_writer->emit(", ");
+ if (aa != 0)
+ m_writer->emit(", ");
emitOperand(args[aa].get(), getInfo(EmitOp::General));
}
m_writer->emit(")");
@@ -1833,7 +1813,7 @@ void CLikeSourceEmitter::emitRateQualifiersAndAddressSpace(IRInst* value)
void CLikeSourceEmitter::emitInstResultDecl(IRInst* inst)
{
auto type = inst->getDataType();
- if(!type)
+ if (!type)
return;
if (as<IRVoidType>(type))
@@ -1852,20 +1832,13 @@ void CLikeSourceEmitter::emitInstResultDecl(IRInst* inst)
case SourceLanguage::CUDA:
case SourceLanguage::HLSL:
case SourceLanguage::C:
- case SourceLanguage::CPP:
- m_writer->emit("static const ");
- break;
- case SourceLanguage::Metal:
- m_writer->emit("constant ");
- break;
+ case SourceLanguage::CPP: m_writer->emit("static const "); break;
+ case SourceLanguage::Metal: m_writer->emit("constant "); break;
case SourceLanguage::WGSL:
// This is handled by emitVarKeyword, below
break;
- default:
- m_writer->emit("const ");
- break;
+ default: m_writer->emit("const "); break;
}
-
}
emitVarKeyword(type, inst);
@@ -1882,24 +1855,25 @@ IRTargetSpecificDecoration* CLikeSourceEmitter::findBestTargetDecoration(IRInst*
IRTargetIntrinsicDecoration* CLikeSourceEmitter::_findBestTargetIntrinsicDecoration(IRInst* inInst)
{
- return as<IRTargetIntrinsicDecoration>(findBestTargetDecoration<IRTargetSpecificDefinitionDecoration>(inInst));
+ return as<IRTargetIntrinsicDecoration>(
+ findBestTargetDecoration<IRTargetSpecificDefinitionDecoration>(inInst));
}
-/* static */bool CLikeSourceEmitter::isOrdinaryName(UnownedStringSlice const& name)
+/* static */ bool CLikeSourceEmitter::isOrdinaryName(UnownedStringSlice const& name)
{
char const* cursor = name.begin();
- char const*const end = name.end();
+ char const* const end = name.end();
// Consume an optional `.` at the start, which indicates
// the ordinary name is for a member function.
- if(cursor < end && *cursor == '.')
+ if (cursor < end && *cursor == '.')
cursor++;
// Must have at least one char, and first char can't be a digit
if (cursor >= end || CharUtil::isDigit(cursor[0]))
return false;
- for(; cursor < end; ++cursor)
+ for (; cursor < end; ++cursor)
{
const auto c = *cursor;
if (CharUtil::isAlphaOrDigit(c) || c == '_')
@@ -1920,16 +1894,20 @@ IRTargetIntrinsicDecoration* CLikeSourceEmitter::_findBestTargetIntrinsicDecorat
}
-void CLikeSourceEmitter::emitIntrinsicCallExpr(IRCall* inst, UnownedStringSlice intrinsicDefinition, IRInst* intrinsicInst, EmitOpInfo const& inOuterPrec)
+void CLikeSourceEmitter::emitIntrinsicCallExpr(
+ IRCall* inst,
+ UnownedStringSlice intrinsicDefinition,
+ IRInst* intrinsicInst,
+ EmitOpInfo const& inOuterPrec)
{
emitIntrinsicCallExprImpl(inst, intrinsicDefinition, intrinsicInst, inOuterPrec);
}
void CLikeSourceEmitter::emitIntrinsicCallExprImpl(
- IRCall* inst,
- UnownedStringSlice intrinsicDefinition,
- IRInst* intrinsicInst,
- EmitOpInfo const& inOuterPrec)
+ IRCall* inst,
+ UnownedStringSlice intrinsicDefinition,
+ IRInst* intrinsicInst,
+ EmitOpInfo const& inOuterPrec)
{
auto outerPrec = inOuterPrec;
@@ -1942,7 +1920,7 @@ void CLikeSourceEmitter::emitIntrinsicCallExprImpl(
auto name = intrinsicDefinition;
- if(isOrdinaryName(name))
+ if (isOrdinaryName(name))
{
// Simple case: it is just an ordinary name, so we call it like a builtin.
auto prec = getInfo(EmitOp::Postfix);
@@ -1952,7 +1930,7 @@ void CLikeSourceEmitter::emitIntrinsicCallExprImpl(
// to indicate that the operation should be called as a member
// function on its first operand.
//
- if(name[0] == '.')
+ if (name[0] == '.')
{
emitOperand(args[0].get(), leftSide(outerPrec, prec));
m_writer->emit(".");
@@ -1966,7 +1944,8 @@ void CLikeSourceEmitter::emitIntrinsicCallExprImpl(
m_writer->emit("(");
for (Index aa = 0; aa < argCount; ++aa)
{
- if (aa != 0) m_writer->emit(", ");
+ if (aa != 0)
+ m_writer->emit(", ");
emitOperand(args[aa].get(), getInfo(EmitOp::General));
}
m_writer->emit(")");
@@ -1974,7 +1953,7 @@ void CLikeSourceEmitter::emitIntrinsicCallExprImpl(
maybeCloseParens(needClose);
return;
}
- else if(name == ".operator[]")
+ else if (name == ".operator[]")
{
// The user is invoking a built-in subscript operator
//
@@ -1994,7 +1973,7 @@ void CLikeSourceEmitter::emitIntrinsicCallExprImpl(
emitOperand(args[argIndex++].get(), getInfo(EmitOp::General));
m_writer->emit("]");
- if(argIndex < argCount)
+ if (argIndex < argCount)
{
m_writer->emit(" = ");
emitOperand(args[argIndex++].get(), getInfo(EmitOp::General));
@@ -2057,7 +2036,10 @@ void CLikeSourceEmitter::emitComInterfaceCallExpr(IRCall* inst, EmitOpInfo const
maybeCloseParens(needClose);
}
-bool CLikeSourceEmitter::findTargetIntrinsicDefinition(IRInst* callee, UnownedStringSlice& outDefinition, IRInst*& outInst)
+bool CLikeSourceEmitter::findTargetIntrinsicDefinition(
+ IRInst* callee,
+ UnownedStringSlice& outDefinition,
+ IRInst*& outInst)
{
return Slang::findTargetIntrinsicDefinition(callee, getTargetCaps(), outDefinition, outInst);
}
@@ -2087,9 +2069,7 @@ void CLikeSourceEmitter::emitCallExpr(IRCall* inst, EmitOpInfo outerPrec)
break;
case kIROp_ComPtrType:
case kIROp_PtrType:
- case kIROp_NativePtrType:
- emitComInterfaceCallExpr(inst, outerPrec);
- return;
+ case kIROp_NativePtrType: emitComInterfaceCallExpr(inst, outerPrec); return;
}
}
@@ -2189,7 +2169,8 @@ bool CLikeSourceEmitter::shouldForceUnpackConstantBufferElements(IRInst* cbuffer
{
if (getTargetReq()->getTarget() != CodeGenTarget::HLSL)
return false;
- if (!getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::NoHLSLPackConstantBufferElements))
+ if (!getTargetProgram()->getOptionSet().getBoolOption(
+ CompilerOptionName::NoHLSLPackConstantBufferElements))
return false;
auto type = as<IRUniformParameterGroupType>(cbufferType);
if (!type)
@@ -2204,25 +2185,20 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
{
EmitOpInfo outerPrec = inOuterPrec;
bool needClose = false;
- switch(inst->getOp())
+ switch (inst->getOp())
{
case kIROp_GlobalHashedStringLiterals:
- /* Don't need to to output anything for this instruction - it's used for reflecting string literals that
- are hashed with 'getStringHash' */
- break;
- case kIROp_RTTIPointerType:
+ /* Don't need to to output anything for this instruction - it's used for reflecting
+ string literals that are hashed with 'getStringHash' */
break;
+ case kIROp_RTTIPointerType: break;
case kIROp_undefined:
- case kIROp_DefaultConstruct:
- m_writer->emit(getName(inst));
- break;
+ case kIROp_DefaultConstruct: m_writer->emit(getName(inst)); break;
case kIROp_IntLit:
case kIROp_FloatLit:
- case kIROp_BoolLit:
- emitSimpleValue(inst);
- break;
+ case kIROp_BoolLit: emitSimpleValue(inst); break;
case kIROp_MakeVector:
case kIROp_MakeMatrix:
@@ -2273,75 +2249,76 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
case kIROp_CastPtrToInt:
case kIROp_CastIntToPtr:
case kIROp_PtrCast:
- {
- // Simple constructor call
- auto prec = getInfo(EmitOp::Prefix);
- needClose = maybeEmitParens(outerPrec, prec);
+ {
+ // Simple constructor call
+ auto prec = getInfo(EmitOp::Prefix);
+ needClose = maybeEmitParens(outerPrec, prec);
- m_writer->emit("(");
- emitType(inst->getDataType());
- m_writer->emit(")");
+ m_writer->emit("(");
+ emitType(inst->getDataType());
+ m_writer->emit(")");
- emitOperand(inst->getOperand(0), rightSide(outerPrec,prec));
- break;
- }
+ emitOperand(inst->getOperand(0), rightSide(outerPrec, prec));
+ break;
+ }
case kIROp_FieldExtract:
- {
- // Extract field from aggregate
- IRFieldExtract* fieldExtract = (IRFieldExtract*) inst;
-
- auto prec = getInfo(EmitOp::Postfix);
- needClose = maybeEmitParens(outerPrec, prec);
-
- auto base = fieldExtract->getBase();
- emitOperand(base, leftSide(outerPrec, prec));
- if (base->getDataType()->getOp() == kIROp_ClassType)
- m_writer->emit("->");
- else
- m_writer->emit(".");
- m_writer->emit(getName(fieldExtract->getField()));
- break;
- }
- case kIROp_FieldAddress:
- {
- // Extract field "address" from aggregate
-
- IRFieldAddress* ii = (IRFieldAddress*) inst;
-
- if (doesTargetSupportPtrTypes())
{
- auto prec = getInfo(EmitOp::Prefix);
+ // Extract field from aggregate
+ IRFieldExtract* fieldExtract = (IRFieldExtract*)inst;
+
+ auto prec = getInfo(EmitOp::Postfix);
needClose = maybeEmitParens(outerPrec, prec);
- m_writer->emit("&");
- outerPrec = rightSide(outerPrec, prec);
- auto innerPrec = getInfo(EmitOp::Postfix);
- bool innerNeedClose = maybeEmitParens(outerPrec, innerPrec);
- auto base = ii->getBase();
- if (isPtrToClassType(base->getDataType()))
- emitDereferenceOperand(base, leftSide(outerPrec, innerPrec));
+
+ auto base = fieldExtract->getBase();
+ emitOperand(base, leftSide(outerPrec, prec));
+ if (base->getDataType()->getOp() == kIROp_ClassType)
+ m_writer->emit("->");
else
- emitOperand(base, leftSide(outerPrec, innerPrec));
- m_writer->emit("->");
- m_writer->emit(getName(ii->getField()));
- maybeCloseParens(innerNeedClose);
+ m_writer->emit(".");
+ m_writer->emit(getName(fieldExtract->getField()));
+ break;
}
- else
+ case kIROp_FieldAddress:
{
- auto prec = getInfo(EmitOp::Postfix);
- needClose = maybeEmitParens(outerPrec, prec);
- bool skipBase = (isD3DTarget(getTargetReq()) &&
- hasExplicitConstantBufferOffset(ii->getBase()->getDataType())) ||
- shouldForceUnpackConstantBufferElements(ii->getBase()->getDataType());
- if (!skipBase)
+ // Extract field "address" from aggregate
+
+ IRFieldAddress* ii = (IRFieldAddress*)inst;
+
+ if (doesTargetSupportPtrTypes())
{
+ auto prec = getInfo(EmitOp::Prefix);
+ needClose = maybeEmitParens(outerPrec, prec);
+ m_writer->emit("&");
+ outerPrec = rightSide(outerPrec, prec);
+ auto innerPrec = getInfo(EmitOp::Postfix);
+ bool innerNeedClose = maybeEmitParens(outerPrec, innerPrec);
auto base = ii->getBase();
- emitOperand(base, leftSide(outerPrec, prec));
- m_writer->emit(".");
+ if (isPtrToClassType(base->getDataType()))
+ emitDereferenceOperand(base, leftSide(outerPrec, innerPrec));
+ else
+ emitOperand(base, leftSide(outerPrec, innerPrec));
+ m_writer->emit("->");
+ m_writer->emit(getName(ii->getField()));
+ maybeCloseParens(innerNeedClose);
}
- m_writer->emit(getName(ii->getField()));
+ else
+ {
+ auto prec = getInfo(EmitOp::Postfix);
+ needClose = maybeEmitParens(outerPrec, prec);
+ bool skipBase =
+ (isD3DTarget(getTargetReq()) &&
+ hasExplicitConstantBufferOffset(ii->getBase()->getDataType())) ||
+ shouldForceUnpackConstantBufferElements(ii->getBase()->getDataType());
+ if (!skipBase)
+ {
+ auto base = ii->getBase();
+ emitOperand(base, leftSide(outerPrec, prec));
+ m_writer->emit(".");
+ }
+ m_writer->emit(getName(ii->getField()));
+ }
+ break;
}
- break;
- }
// Comparisons
case kIROp_Eql:
@@ -2350,19 +2327,19 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
case kIROp_Less:
case kIROp_Geq:
case kIROp_Leq:
- {
- const auto emitOp = getEmitOpForOp(inst->getOp());
+ {
+ const auto emitOp = getEmitOpForOp(inst->getOp());
- auto prec = getInfo(emitOp);
- needClose = maybeEmitParens(outerPrec, prec);
+ auto prec = getInfo(emitOp);
+ needClose = maybeEmitParens(outerPrec, prec);
- emitOperand(inst->getOperand(0), leftSide(outerPrec, prec));
- m_writer->emit(" ");
- m_writer->emit(prec.op);
- m_writer->emit(" ");
- emitOperand(inst->getOperand(1), rightSide(outerPrec, prec));
- break;
- }
+ emitOperand(inst->getOperand(0), leftSide(outerPrec, prec));
+ m_writer->emit(" ");
+ m_writer->emit(prec.op);
+ m_writer->emit(" ");
+ emitOperand(inst->getOperand(1), rightSide(outerPrec, prec));
+ break;
+ }
// Binary ops
case kIROp_Add:
@@ -2378,60 +2355,62 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
case kIROp_And:
case kIROp_Or:
case kIROp_Mul:
- {
- const auto emitOp = getEmitOpForOp(inst->getOp());
- const auto info = getInfo(emitOp);
+ {
+ const auto emitOp = getEmitOpForOp(inst->getOp());
+ const auto info = getInfo(emitOp);
- needClose = maybeEmitParens(outerPrec, info);
- emitOperand(inst->getOperand(0), leftSide(outerPrec, info));
- m_writer->emit(" ");
- m_writer->emit(info.op);
- m_writer->emit(" ");
- emitOperand(inst->getOperand(1), rightSide(outerPrec, info));
- break;
- }
+ needClose = maybeEmitParens(outerPrec, info);
+ emitOperand(inst->getOperand(0), leftSide(outerPrec, info));
+ m_writer->emit(" ");
+ m_writer->emit(info.op);
+ m_writer->emit(" ");
+ emitOperand(inst->getOperand(1), rightSide(outerPrec, info));
+ break;
+ }
// Unary
case kIROp_Not:
case kIROp_Neg:
case kIROp_BitNot:
- {
- IRInst* operand = inst->getOperand(0);
+ {
+ IRInst* operand = inst->getOperand(0);
- const auto emitOp = getEmitOpForOp(inst->getOp());
- const auto prec = getInfo(emitOp);
+ const auto emitOp = getEmitOpForOp(inst->getOp());
+ const auto prec = getInfo(emitOp);
- needClose = maybeEmitParens(outerPrec, prec);
+ needClose = maybeEmitParens(outerPrec, prec);
- switch (inst->getOp())
- {
- case kIROp_BitNot:
+ switch (inst->getOp())
{
- // If it's a BitNot, but the data type is bool special case to !
- m_writer->emit(as<IRBoolType>(inst->getDataType()) ? "!" : prec.op);
- break;
- }
+ case kIROp_BitNot:
+ {
+ // If it's a BitNot, but the data type is bool special case to !
+ m_writer->emit(as<IRBoolType>(inst->getDataType()) ? "!" : prec.op);
+ break;
+ }
case kIROp_Not:
- {
- m_writer->emit(prec.op);
- break;
- }
+ {
+ m_writer->emit(prec.op);
+ break;
+ }
case kIROp_Neg:
- {
- // Emit a space after the unary -, so if we are followed by a negative literal we don't end up with --
- // which some downstream compilers determine to be decrement.
- m_writer->emit("- ");
- break;
+ {
+ // Emit a space after the unary -, so if we are followed by a negative literal
+ // we don't end up with -- which some downstream compilers determine to be
+ // decrement.
+ m_writer->emit("- ");
+ break;
+ }
}
- }
- emitOperand(operand, rightSide(outerPrec, prec));
- break;
- }
+ emitOperand(operand, rightSide(outerPrec, prec));
+ break;
+ }
case kIROp_Load:
{
auto base = inst->getOperand(0);
emitDereferenceOperand(base, outerPrec);
- if (isKhronosTarget(getTargetReq()) && isSingleElementConstantBuffer(base->getDataType()))
+ if (isKhronosTarget(getTargetReq()) &&
+ isSingleElementConstantBuffer(base->getDataType()))
{
m_writer->emit("._data");
}
@@ -2522,7 +2501,9 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
break;
case kIROp_NonUniformResourceIndex:
- emitOperand(inst->getOperand(0), getInfo(EmitOp::General)); // Directly emit NonUniformResourceIndex Operand0;
+ emitOperand(
+ inst->getOperand(0),
+ getInfo(EmitOp::General)); // Directly emit NonUniformResourceIndex Operand0;
break;
case kIROp_getNativeStr:
@@ -2545,59 +2526,63 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
break;
}
case kIROp_GetNativePtr:
- {
- auto prec = getInfo(EmitOp::Postfix);
- needClose = maybeEmitParens(outerPrec, prec);
- emitOperand(inst->getOperand(0), leftSide(outerPrec, prec));
- m_writer->emit(".get()");
- break;
- }
+ {
+ auto prec = getInfo(EmitOp::Postfix);
+ needClose = maybeEmitParens(outerPrec, prec);
+ emitOperand(inst->getOperand(0), leftSide(outerPrec, prec));
+ m_writer->emit(".get()");
+ break;
+ }
case kIROp_GetManagedPtrWriteRef:
- {
- auto prec = getInfo(EmitOp::Postfix);
- needClose = maybeEmitParens(outerPrec, prec);
- emitDereferenceOperand(inst->getOperand(0), leftSide(outerPrec, prec));
- m_writer->emit(".writeRef()");
- break;
- }
+ {
+ auto prec = getInfo(EmitOp::Postfix);
+ needClose = maybeEmitParens(outerPrec, prec);
+ emitDereferenceOperand(inst->getOperand(0), leftSide(outerPrec, prec));
+ m_writer->emit(".writeRef()");
+ break;
+ }
case kIROp_ManagedPtrAttach:
- {
- auto prec = getInfo(EmitOp::Postfix);
- needClose = maybeEmitParens(outerPrec, prec);
- emitDereferenceOperand(inst->getOperand(0), leftSide(outerPrec, prec));
- m_writer->emit(".attach(");
- emitOperand(inst->getOperand(1), EmitOpInfo());
- m_writer->emit(")");
- break;
- }
+ {
+ auto prec = getInfo(EmitOp::Postfix);
+ needClose = maybeEmitParens(outerPrec, prec);
+ emitDereferenceOperand(inst->getOperand(0), leftSide(outerPrec, prec));
+ m_writer->emit(".attach(");
+ emitOperand(inst->getOperand(1), EmitOpInfo());
+ m_writer->emit(")");
+ break;
+ }
case kIROp_ManagedPtrDetach:
- {
- auto prec = getInfo(EmitOp::Postfix);
- needClose = maybeEmitParens(outerPrec, prec);
- emitOperand(inst->getOperand(0), leftSide(outerPrec, prec));
- m_writer->emit(".detach()");
- break;
- }
+ {
+ auto prec = getInfo(EmitOp::Postfix);
+ needClose = maybeEmitParens(outerPrec, prec);
+ emitOperand(inst->getOperand(0), leftSide(outerPrec, prec));
+ m_writer->emit(".detach()");
+ break;
+ }
case kIROp_GetOffsetPtr:
- {
- auto prec = getInfo(EmitOp::Add);
- needClose = maybeEmitParens(outerPrec, prec);
- emitOperand(inst->getOperand(0), leftSide(outerPrec, prec));
- m_writer->emit(" + ");
- emitOperand(inst->getOperand(1), rightSide(outerPrec, prec));
- break;
- }
+ {
+ auto prec = getInfo(EmitOp::Add);
+ needClose = maybeEmitParens(outerPrec, prec);
+ emitOperand(inst->getOperand(0), leftSide(outerPrec, prec));
+ m_writer->emit(" + ");
+ emitOperand(inst->getOperand(1), rightSide(outerPrec, prec));
+ break;
+ }
case kIROp_ImageSubscript:
// We should have legalized ImageSubscript before emit for metal targets
if (isMetalTarget(this->getTargetReq()))
- getSink()->diagnose(inst, Diagnostics::unimplemented, "kIROp_ImageSubscript is unimplemented for Metal, expected legalization beforehand");
+ getSink()->diagnose(
+ inst,
+ Diagnostics::unimplemented,
+ "kIROp_ImageSubscript is unimplemented for Metal, expected legalization "
+ "beforehand");
[[fallthrough]];
case kIROp_GetElement:
case kIROp_MeshOutputRef:
case kIROp_GetElementPtr:
// HACK: deal with translation of GLSL geometry shader input arrays.
- if(auto decoration = inst->getOperand(0)->findDecoration<IRGLSLOuterArrayDecoration>())
+ if (auto decoration = inst->getOperand(0)->findDecoration<IRGLSLOuterArrayDecoration>())
{
auto prec = getInfo(EmitOp::Postfix);
needClose = maybeEmitParens(outerPrec, prec);
@@ -2657,7 +2642,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
UInt elementIndex = (UInt)irConst->value.intVal;
SLANG_RELEASE_ASSERT(elementIndex < 4);
- char const* kComponents[] = { "x", "y", "z", "w" };
+ char const* kComponents[] = {"x", "y", "z", "w"};
m_writer->emit(kComponents[elementIndex]);
}
}
@@ -2693,9 +2678,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
}
break;
- case kIROp_Param:
- m_writer->emit(getName(inst));
- break;
+ case kIROp_Param: m_writer->emit(getName(inst)); break;
case kIROp_MakeArray:
case kIROp_MakeStruct:
@@ -2708,7 +2691,8 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
UInt argCount = inst->getOperandCount();
for (UInt aa = 0; aa < argCount; ++aa)
{
- if (aa != 0) m_writer->emit(", ");
+ if (aa != 0)
+ m_writer->emit(", ");
emitOperand(inst->getOperand(aa), getInfo(EmitOp::General));
}
m_writer->emit(" }");
@@ -2726,7 +2710,8 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
->getValue();
for (UInt aa = 0; aa < argCount; ++aa)
{
- if (aa != 0) m_writer->emit(", ");
+ if (aa != 0)
+ m_writer->emit(", ");
emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
}
m_writer->emit(" }");
@@ -2741,7 +2726,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
// provided in a prelude for C/C++, so that the target
// can easily emit code for whatever the best possible
// bitcast is on the platform.
-
+
auto prec = getInfo(EmitOp::Prefix);
needClose = maybeEmitParens(outerPrec, prec);
@@ -2754,130 +2739,128 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
}
break;
case kIROp_GlobalConstant:
- case kIROp_GetValueFromBoundInterface:
- emitOperand(inst->getOperand(0), outerPrec);
- break;
+ case kIROp_GetValueFromBoundInterface: emitOperand(inst->getOperand(0), outerPrec); break;
case kIROp_ByteAddressBufferLoad:
- {
- m_writer->emit("(");
- emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
- m_writer->emit(").Load<");
- emitType(inst->getDataType());
- m_writer->emit(" >(");
- emitOperand(inst->getOperand(1), getInfo(EmitOp::General));
- m_writer->emit(")");
- break;
- }
+ {
+ m_writer->emit("(");
+ emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
+ m_writer->emit(").Load<");
+ emitType(inst->getDataType());
+ m_writer->emit(" >(");
+ emitOperand(inst->getOperand(1), getInfo(EmitOp::General));
+ m_writer->emit(")");
+ break;
+ }
case kIROp_ByteAddressBufferStore:
- {
- auto prec = getInfo(EmitOp::Postfix);
- needClose = maybeEmitParens(outerPrec, prec);
+ {
+ auto prec = getInfo(EmitOp::Postfix);
+ needClose = maybeEmitParens(outerPrec, prec);
- emitOperand(inst->getOperand(0), leftSide(outerPrec, prec));
- m_writer->emit(".Store(");
- emitOperand(inst->getOperand(1), getInfo(EmitOp::General));
- m_writer->emit(",");
- emitOperand(inst->getOperand(inst->getOperandCount() - 1), getInfo(EmitOp::General));
- m_writer->emit(")");
- break;
- }
+ emitOperand(inst->getOperand(0), leftSide(outerPrec, prec));
+ m_writer->emit(".Store(");
+ emitOperand(inst->getOperand(1), getInfo(EmitOp::General));
+ m_writer->emit(",");
+ emitOperand(inst->getOperand(inst->getOperandCount() - 1), getInfo(EmitOp::General));
+ m_writer->emit(")");
+ break;
+ }
case kIROp_PackAnyValue:
- {
- m_writer->emit("packAnyValue<");
- m_writer->emit(getIntVal(cast<IRAnyValueType>(inst->getDataType())->getSize()));
- m_writer->emit(",");
- emitType(inst->getOperand(0)->getDataType());
- m_writer->emit(">(");
- emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
- m_writer->emit(")");
- break;
- }
- case kIROp_UnpackAnyValue:
- {
- m_writer->emit("unpackAnyValue<");
- m_writer->emit(getIntVal(cast<IRAnyValueType>(inst->getOperand(0)->getDataType())->getSize()));
- m_writer->emit(",");
- emitType(inst->getDataType());
- m_writer->emit(">(");
- emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
- m_writer->emit(")");
- break;
- }
- case kIROp_GpuForeach:
- {
- auto operand = inst->getOperand(2);
- if (as<IRFunc>(operand))
{
- //emitOperand(operand->findDecoration<IREntryPointDecoration>(), getInfo(EmitOp::General));
- emitOperand(operand, getInfo(EmitOp::General));
+ m_writer->emit("packAnyValue<");
+ m_writer->emit(getIntVal(cast<IRAnyValueType>(inst->getDataType())->getSize()));
+ m_writer->emit(",");
+ emitType(inst->getOperand(0)->getDataType());
+ m_writer->emit(">(");
+ emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
+ m_writer->emit(")");
+ break;
}
- else
+ case kIROp_UnpackAnyValue:
{
- SLANG_UNEXPECTED("Expected 3rd operand to be a function");
+ m_writer->emit("unpackAnyValue<");
+ m_writer->emit(
+ getIntVal(cast<IRAnyValueType>(inst->getOperand(0)->getDataType())->getSize()));
+ m_writer->emit(",");
+ emitType(inst->getDataType());
+ m_writer->emit(">(");
+ emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
+ m_writer->emit(")");
+ break;
}
- m_writer->emit("_wrapper(");
- emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
- m_writer->emit(", ");
- emitOperand(inst->getOperand(1), getInfo(EmitOp::General));
- UInt argCount = inst->getOperandCount();
- for (UInt aa = 3; aa < argCount; ++aa)
+ case kIROp_GpuForeach:
{
+ auto operand = inst->getOperand(2);
+ if (as<IRFunc>(operand))
+ {
+ // emitOperand(operand->findDecoration<IREntryPointDecoration>(),
+ // getInfo(EmitOp::General));
+ emitOperand(operand, getInfo(EmitOp::General));
+ }
+ else
+ {
+ SLANG_UNEXPECTED("Expected 3rd operand to be a function");
+ }
+ m_writer->emit("_wrapper(");
+ emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
m_writer->emit(", ");
- emitOperand(inst->getOperand(aa), getInfo(EmitOp::General));
+ emitOperand(inst->getOperand(1), getInfo(EmitOp::General));
+ UInt argCount = inst->getOperandCount();
+ for (UInt aa = 3; aa < argCount; ++aa)
+ {
+ m_writer->emit(", ");
+ emitOperand(inst->getOperand(aa), getInfo(EmitOp::General));
+ }
+ m_writer->emit(")");
+ break;
}
- m_writer->emit(")");
- break;
- }
case kIROp_GetStringHash:
- {
- auto getStringHashInst = as<IRGetStringHash>(inst);
- auto stringLit = getStringHashInst->getStringLit();
-
- if (stringLit)
{
- auto slice = stringLit->getStringSlice();
- m_writer->emit(getStableHashCode32(slice.begin(), slice.getLength()).hash);
- }
- else
- {
- // Couldn't handle
- diagnoseUnhandledInst(inst);
+ auto getStringHashInst = as<IRGetStringHash>(inst);
+ auto stringLit = getStringHashInst->getStringLit();
+
+ if (stringLit)
+ {
+ auto slice = stringLit->getStringSlice();
+ m_writer->emit(getStableHashCode32(slice.begin(), slice.getLength()).hash);
+ }
+ else
+ {
+ // Couldn't handle
+ diagnoseUnhandledInst(inst);
+ }
+ break;
}
- break;
- }
case kIROp_Printf:
- {
- m_writer->emit("printf(");
- emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
- if (inst->getOperandCount() == 2)
{
- auto operand = inst->getOperand(1);
- if (auto makeStruct = as<IRMakeStruct>(operand))
+ m_writer->emit("printf(");
+ emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
+ if (inst->getOperandCount() == 2)
{
- // Flatten the tuple resulting from the variadic pack.
- for (UInt bb = 0; bb < makeStruct->getOperandCount(); ++bb)
+ auto operand = inst->getOperand(1);
+ if (auto makeStruct = as<IRMakeStruct>(operand))
{
- m_writer->emit(", ");
- emitOperand(makeStruct->getOperand(bb), getInfo(EmitOp::General));
+ // Flatten the tuple resulting from the variadic pack.
+ for (UInt bb = 0; bb < makeStruct->getOperandCount(); ++bb)
+ {
+ m_writer->emit(", ");
+ emitOperand(makeStruct->getOperand(bb), getInfo(EmitOp::General));
+ }
}
}
+ m_writer->emit(")");
+ break;
}
- m_writer->emit(")");
- break;
- }
case kIROp_RequireGLSLExtension:
- {
- break; //should already have set requirement; case covered for empty intrinsic block
- }
+ {
+ break; // should already have set requirement; case covered for empty intrinsic block
+ }
case kIROp_RequireComputeDerivative:
- {
- break; //should already have been parsed and used.
- }
- default:
- diagnoseUnhandledInst(inst);
- break;
+ {
+ break; // should already have been parsed and used.
+ }
+ default: diagnoseUnhandledInst(inst); break;
}
maybeCloseParens(needClose);
}
@@ -2890,8 +2873,11 @@ void CLikeSourceEmitter::emitInst(IRInst* inst)
}
// Don't emit any context message for an explicit `AbortCompilationException`
// because it should only happen when an error is already emitted.
- catch(const AbortCompilationException&) { throw; }
- catch(...)
+ catch (const AbortCompilationException&)
+ {
+ throw;
+ }
+ catch (...)
{
noteInternalErrorLoc(inst->sourceLoc);
throw;
@@ -2913,10 +2899,10 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst)
}
else
{
- m_writer->advanceToSourceLocation(inst->sourceLoc);
+ m_writer->advanceToSourceLocation(inst->sourceLoc);
}
- switch(inst->getOp())
+ switch (inst->getOp())
{
default:
emitInstResultDecl(inst);
@@ -2927,8 +2913,7 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst)
case kIROp_DebugSource:
case kIROp_DebugLine:
case kIROp_DebugVar:
- case kIROp_DebugValue:
- break;
+ case kIROp_DebugValue: break;
case kIROp_Unmodified:
break;
@@ -2949,14 +2934,10 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst)
case kIROp_AtomicExchange:
case kIROp_AtomicCompareExchange:
case kIROp_StructuredBufferGetDimensions:
- case kIROp_MetalAtomicCast:
- emitInstStmt(inst);
- break;
+ case kIROp_MetalAtomicCast: emitInstStmt(inst); break;
case kIROp_LiveRangeStart:
- case kIROp_LiveRangeEnd:
- emitLiveness(inst);
- break;
+ case kIROp_LiveRangeEnd: emitLiveness(inst); break;
case kIROp_undefined:
case kIROp_DefaultConstruct:
{
@@ -2965,8 +2946,7 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst)
}
break;
- case kIROp_AllocateOpaqueHandle:
- break;
+ case kIROp_AllocateOpaqueHandle: break;
case kIROp_Var:
{
auto var = cast<IRVar>(inst);
@@ -2995,14 +2975,12 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst)
if (((IRReturn*)inst)->getVal()->getOp() != kIROp_VoidLit)
{
m_writer->emit(" ");
- emitOperand(((IRReturn*) inst)->getVal(), getInfo(EmitOp::General));
+ emitOperand(((IRReturn*)inst)->getVal(), getInfo(EmitOp::General));
}
m_writer->emit(";\n");
break;
- case kIROp_discard:
- emitInstStmt(inst);
- break;
+ case kIROp_discard: emitInstStmt(inst); break;
case kIROp_swizzleSet:
{
@@ -3027,7 +3005,7 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst)
UInt elementIndex = (UInt)irConst->value.intVal;
SLANG_RELEASE_ASSERT(elementIndex < 4);
- char const* kComponents[] = { "x", "y", "z", "w" };
+ char const* kComponents[] = {"x", "y", "z", "w"};
m_writer->emit(kComponents[elementIndex]);
}
maybeCloseParens(needCloseSubscript);
@@ -3066,7 +3044,7 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst)
UInt elementIndex = (UInt)irConst->value.intVal;
SLANG_RELEASE_ASSERT(elementIndex < 4);
- char const* kComponents[] = { "x", "y", "z", "w" };
+ char const* kComponents[] = {"x", "y", "z", "w"};
m_writer->emit(kComponents[elementIndex]);
}
maybeCloseParens(needCloseSubscript);
@@ -3179,16 +3157,14 @@ void CLikeSourceEmitter::_emitInstAsDefaultInitializedVar(IRInst* inst, IRType*
case CodeGenTarget::CPPSource:
case CodeGenTarget::HostCPPSource:
case CodeGenTarget::PyTorchCppBinding:
- case CodeGenTarget::CUDASource:
- m_writer->emit(" = {}");
- break;
+ case CodeGenTarget::CUDASource: m_writer->emit(" = {}"); break;
}
m_writer->emit(";\n");
}
void CLikeSourceEmitter::emitSemanticsUsingVarLayout(IRVarLayout* varLayout)
{
- if(auto semanticAttr = varLayout->findAttr<IRSemanticAttr>())
+ if (auto semanticAttr = varLayout->findAttr<IRSemanticAttr>())
{
// Note: We force the semantic name stored in the IR to
// upper-case here because that is what existing Slang
@@ -3210,7 +3186,7 @@ void CLikeSourceEmitter::emitSemanticsUsingVarLayout(IRVarLayout* varLayout)
m_writer->emit(" : ");
m_writer->emit(name);
- if(auto index = semanticAttr->getIndex())
+ if (auto index = semanticAttr->getIndex())
{
m_writer->emit(index);
}
@@ -3222,7 +3198,9 @@ void CLikeSourceEmitter::emitSemantics(IRInst* inst, bool allowOffsetLayout)
emitSemanticsImpl(inst, allowOffsetLayout);
}
-void CLikeSourceEmitter::emitDecorationLayoutSemantics(IRInst* inst, char const* uniformSemanticSpelling)
+void CLikeSourceEmitter::emitDecorationLayoutSemantics(
+ IRInst* inst,
+ char const* uniformSemanticSpelling)
{
emitLayoutSemanticsImpl(inst, uniformSemanticSpelling, EmitLayoutSemanticOption::kPreType);
}
@@ -3232,15 +3210,17 @@ void CLikeSourceEmitter::emitLayoutSemantics(IRInst* inst, char const* uniformSe
emitLayoutSemanticsImpl(inst, uniformSemanticSpelling, EmitLayoutSemanticOption::kPostType);
}
-void CLikeSourceEmitter::emitSwitchCaseSelectorsImpl(const SwitchRegion::Case* currentCase, bool isDefault)
+void CLikeSourceEmitter::emitSwitchCaseSelectorsImpl(
+ const SwitchRegion::Case* currentCase,
+ bool isDefault)
{
- for(auto caseVal : currentCase->values)
+ for (auto caseVal : currentCase->values)
{
m_writer->emit("case ");
emitOperand(caseVal, getInfo(EmitOp::General));
m_writer->emit(":\n");
}
- if(isDefault)
+ if (isDefault)
{
m_writer->emit("default:\n");
}
@@ -3252,24 +3232,25 @@ void CLikeSourceEmitter::emitRegion(Region* inRegion)
// regions iteratively rather than recursively.
// This is effectively an emulation of tail recursion.
Region* region = inRegion;
- while(region)
+ while (region)
{
// What flavor of region are we trying to emit?
- switch(region->getFlavor())
+ switch (region->getFlavor())
{
case Region::Flavor::Simple:
{
// A simple region consists of a basic block followed
// by another region.
//
- auto simpleRegion = (SimpleRegion*) region;
+ auto simpleRegion = (SimpleRegion*)region;
// We start by outputting all of the non-terminator
// instructions in the block.
//
auto block = simpleRegion->block;
auto terminator = block->getTerminator();
- for (auto inst = block->getFirstInst(); inst != terminator; inst = inst->getNextInst())
+ for (auto inst = block->getFirstInst(); inst != terminator;
+ inst = inst->getNextInst())
{
emitInst(inst);
}
@@ -3281,7 +3262,7 @@ void CLikeSourceEmitter::emitRegion(Region* inRegion)
// them into the current block.
//
m_writer->advanceToSourceLocation(terminator->sourceLoc);
- switch(terminator->getOp())
+ switch (terminator->getOp())
{
default:
// Don't do anything with the terminator, and assume
@@ -3312,16 +3293,12 @@ void CLikeSourceEmitter::emitRegion(Region* inRegion)
// Break and continue regions are trivial to handle, as long as we
// don't need to consider multi-level break/continue (which we
// don't for now).
- case Region::Flavor::Break:
- m_writer->emit("break;\n");
- break;
- case Region::Flavor::Continue:
- m_writer->emit("continue;\n");
- break;
+ case Region::Flavor::Break: m_writer->emit("break;\n"); break;
+ case Region::Flavor::Continue: m_writer->emit("continue;\n"); break;
case Region::Flavor::If:
{
- auto ifRegion = (IfRegion*) region;
+ auto ifRegion = (IfRegion*)region;
emitIfDecorationsImpl(ifRegion->ifElseInst);
@@ -3340,7 +3317,7 @@ void CLikeSourceEmitter::emitRegion(Region* inRegion)
// Don't emit the `else` region if it would be empty
//
- if(auto elseRegion = ifRegion->elseRegion)
+ if (auto elseRegion = ifRegion->elseRegion)
{
m_writer->emit("else\n{\n");
m_writer->indent();
@@ -3363,7 +3340,7 @@ void CLikeSourceEmitter::emitRegion(Region* inRegion)
case Region::Flavor::Loop:
{
- auto loopRegion = (LoopRegion*) region;
+ auto loopRegion = (LoopRegion*)region;
auto loopInst = loopRegion->loopInst;
// If the user applied an explicit decoration to the loop,
@@ -3371,10 +3348,11 @@ void CLikeSourceEmitter::emitRegion(Region* inRegion)
// along in the output code (if the target language
// supports the semantics of the decoration).
//
- if (auto loopControlDecoration = loopInst->findDecoration<IRLoopControlDecoration>())
+ if (auto loopControlDecoration =
+ loopInst->findDecoration<IRLoopControlDecoration>())
{
emitLoopControlDecorationImpl(loopControlDecoration);
- }
+ }
m_writer->emit("for(;;)\n{\n");
m_writer->indent();
@@ -3389,17 +3367,17 @@ void CLikeSourceEmitter::emitRegion(Region* inRegion)
case Region::Flavor::Switch:
{
- auto switchRegion = (SwitchRegion*) region;
+ auto switchRegion = (SwitchRegion*)region;
emitSwitchDecorationsImpl(switchRegion->switchInst);
-
+
// Emit the start of our statement.
m_writer->emit("switch(");
emitOperand(switchRegion->getCondition(), getInfo(EmitOp::General));
m_writer->emit(")\n{\n");
auto defaultCase = switchRegion->defaultCase;
- for(auto currentCase : switchRegion->cases)
+ for (auto currentCase : switchRegion->cases)
{
bool isDefault = (currentCase.Ptr() == defaultCase);
emitSwitchCaseSelectors(currentCase.Ptr(), isDefault);
@@ -3436,7 +3414,9 @@ bool CLikeSourceEmitter::isDefinition(IRFunc* func)
return func->getFirstBlock() != nullptr;
}
-void CLikeSourceEmitter::emitEntryPointAttributes(IRFunc* irFunc, IREntryPointDecoration* entryPointDecor)
+void CLikeSourceEmitter::emitEntryPointAttributes(
+ IRFunc* irFunc,
+ IREntryPointDecoration* entryPointDecor)
{
emitEntryPointAttributesImpl(irFunc, entryPointDecor);
}
@@ -3462,7 +3442,7 @@ void CLikeSourceEmitter::emitFunctionBody(IRGlobalValueWithCode* code)
// storage for derived structures like the region tree (and logic
// for invalidating them when a transformation would break them).
//
- fixValueScoping(regionTree, [this](IRInst* inst) {return shouldFoldInstIntoUseSites(inst); });
+ fixValueScoping(regionTree, [this](IRInst* inst) { return shouldFoldInstIntoUseSites(inst); });
// Now emit high-level code from that structured region tree.
//
@@ -3474,13 +3454,13 @@ void CLikeSourceEmitter::emitSimpleFuncParamImpl(IRParam* param)
auto paramName = getName(param);
auto paramType = param->getDataType();
- if(auto layoutDecoration = param->findDecoration<IRLayoutDecoration>() )
+ if (auto layoutDecoration = param->findDecoration<IRLayoutDecoration>())
{
auto layout = as<IRVarLayout>(layoutDecoration->getLayout());
SLANG_ASSERT(layout);
- if(layout->usesResourceKind(LayoutResourceKind::VaryingInput)
- || layout->usesResourceKind(LayoutResourceKind::VaryingOutput))
+ if (layout->usesResourceKind(LayoutResourceKind::VaryingInput) ||
+ layout->usesResourceKind(LayoutResourceKind::VaryingOutput))
{
emitInterpolationModifiers(param, paramType, layout);
emitMeshShaderModifiers(param);
@@ -3538,7 +3518,7 @@ void CLikeSourceEmitter::emitSimpleFuncImpl(IRFunc* func)
emitSemantics(func);
// TODO: encode declaration vs. definition
- if(isDefinition(func))
+ if (isDefinition(func))
{
m_writer->emit("\n{\n");
m_writer->indent();
@@ -3561,17 +3541,17 @@ void CLikeSourceEmitter::emitParamTypeImpl(IRType* type, String const& name)
// encoded as a parameter of pointer type, so
// we need to decode that here.
//
- if( auto outType = as<IROutType>(type))
+ if (auto outType = as<IROutType>(type))
{
m_writer->emit("out ");
type = outType->getValueType();
}
- else if( auto inOutType = as<IRInOutType>(type))
+ else if (auto inOutType = as<IRInOutType>(type))
{
m_writer->emit("inout ");
type = inOutType->getValueType();
}
- else if( auto refType = as<IRRefType>(type))
+ else if (auto refType = as<IRRefType>(type))
{
// Note: There is no HLSL/GLSL equivalent for by-reference parameters,
// so we don't actually expect to encounter these in user code.
@@ -3605,7 +3585,7 @@ void CLikeSourceEmitter::emitFuncDecl(IRFunc* func, const String& name)
// to it, and the HLSL compiler will get upset if the
// forward declaration doesn't *also* have those
// attributes.
- if(asEntryPoint(func))
+ if (asEntryPoint(func))
return;
@@ -3621,9 +3601,9 @@ void CLikeSourceEmitter::emitFuncDecl(IRFunc* func, const String& name)
m_writer->emit("(");
auto paramCount = funcType->getParamCount();
- for(UInt pp = 0; pp < paramCount; ++pp)
+ for (UInt pp = 0; pp < paramCount; ++pp)
{
- if(pp != 0)
+ if (pp != 0)
m_writer->emit(", ");
String paramName;
@@ -3638,7 +3618,7 @@ void CLikeSourceEmitter::emitFuncDecl(IRFunc* func, const String& name)
IREntryPointLayout* CLikeSourceEmitter::getEntryPointLayout(IRFunc* func)
{
- if( auto layoutDecoration = func->findDecoration<IRLayoutDecoration>() )
+ if (auto layoutDecoration = func->findDecoration<IRLayoutDecoration>())
{
return as<IREntryPointLayout>(layoutDecoration->getLayout());
}
@@ -3675,8 +3655,7 @@ bool shouldWrapInExternCBlock(IRFunc* func)
{
switch (decor->getOp())
{
- case kIROp_ExternCDecoration:
- return true;
+ case kIROp_ExternCDecoration: return true;
}
}
return false;
@@ -3700,7 +3679,7 @@ void CLikeSourceEmitter::emitFunc(IRFunc* func)
m_writer->emit("extern \"C\" {\n");
}
- if(!isDefinition(func))
+ if (!isDefinition(func))
{
// This is just a function declaration,
// and so we want to emit it as such.
@@ -3723,7 +3702,7 @@ void CLikeSourceEmitter::emitFunc(IRFunc* func)
void CLikeSourceEmitter::emitFuncDecorationsImpl(IRFunc* func)
{
- for(auto decoration : func->getDecorations())
+ for (auto decoration : func->getDecorations())
{
emitFuncDecorationImpl(decoration);
}
@@ -3735,7 +3714,7 @@ void CLikeSourceEmitter::emitStruct(IRStructType* structType)
// If the selected `struct` type is actually an intrinsic
// on our target, then we don't want to emit anything at all.
- if(isTargetIntrinsic(structType))
+ if (isTargetIntrinsic(structType))
{
return;
}
@@ -3755,23 +3734,25 @@ void CLikeSourceEmitter::emitStructDeclarationSeparatorImpl()
m_writer->emit(";");
}
-void CLikeSourceEmitter::emitStructDeclarationsBlock(IRStructType* structType, bool allowOffsetLayout)
+void CLikeSourceEmitter::emitStructDeclarationsBlock(
+ IRStructType* structType,
+ bool allowOffsetLayout)
{
m_writer->emit("\n{\n");
m_writer->indent();
- for(auto ff : structType->getFields())
+ for (auto ff : structType->getFields())
{
auto fieldKey = ff->getKey();
auto fieldType = ff->getFieldType();
// Filter out fields with `void` type that might
// have been introduced by legalization.
- if(as<IRVoidType>(fieldType))
+ if (as<IRVoidType>(fieldType))
continue;
// Note: GLSL doesn't support interpolation modifiers on `struct` fields
- if( getSourceLanguage() != SourceLanguage::GLSL )
+ if (getSourceLanguage() != SourceLanguage::GLSL)
{
emitInterpolationModifiers(fieldKey, fieldType, nullptr);
}
@@ -3841,7 +3822,8 @@ void CLikeSourceEmitter::emitClass(IRClassType* classType)
m_writer->emit("SLANG_COM_OBJECT_IUNKNOWN_ALL\n");
m_writer->emit("void* getInterface(const Guid & uuid)\n{\n");
m_writer->indent();
- m_writer->emit("if (uuid == ISlangUnknown::getTypeGuid()) return static_cast<ISlangUnknown*>(this);\n");
+ m_writer->emit("if (uuid == ISlangUnknown::getTypeGuid()) return "
+ "static_cast<ISlangUnknown*>(this);\n");
for (auto wt : comWitnessTables)
{
auto interfaceName = getName(wt->getConformanceType());
@@ -3883,9 +3865,11 @@ void CLikeSourceEmitter::emitClass(IRClassType* classType)
for (auto wtEntry : wt->getChildren())
{
auto req = as<IRWitnessTableEntry>(wtEntry);
- if (!req) continue;
+ if (!req)
+ continue;
auto func = as<IRFunc>(req->getSatisfyingVal());
- if (!func) continue;
+ if (!func)
+ continue;
m_writer->emit("virtual SLANG_NO_THROW ");
emitType(func->getResultType(), "SLANG_MCALL " + getName(req->getRequirementKey()));
m_writer->emit("(");
@@ -3903,7 +3887,10 @@ void CLikeSourceEmitter::emitClass(IRClassType* classType)
m_writer->emit("};\n\n");
}
-void CLikeSourceEmitter::emitInterpolationModifiers(IRInst* varInst, IRType* valueType, IRVarLayout* layout)
+void CLikeSourceEmitter::emitInterpolationModifiers(
+ IRInst* varInst,
+ IRType* valueType,
+ IRVarLayout* layout)
{
emitInterpolationModifiersImpl(varInst, valueType, layout);
}
@@ -3913,10 +3900,10 @@ void CLikeSourceEmitter::emitMeshShaderModifiers(IRInst* varInst)
emitMeshShaderModifiersImpl(varInst);
}
- /// Emit modifiers that should apply even for a declaration of an SSA temporary.
+/// Emit modifiers that should apply even for a declaration of an SSA temporary.
void CLikeSourceEmitter::emitTempModifiers(IRInst* temp)
{
- if(temp->findDecoration<IRPreciseDecoration>())
+ if (temp->findDecoration<IRPreciseDecoration>())
{
m_writer->emit("precise ");
}
@@ -3924,7 +3911,8 @@ void CLikeSourceEmitter::emitTempModifiers(IRInst* temp)
void CLikeSourceEmitter::emitVarModifiers(IRVarLayout* layout, IRInst* varDecl, IRType* varType)
{
- // TODO(JS): We could push all of this onto the target impls, and then not need so many virtual hooks.
+ // TODO(JS): We could push all of this onto the target impls, and then not need so many virtual
+ // hooks.
emitVarDecorationsImpl(varDecl);
emitTempModifiers(varDecl);
@@ -3936,8 +3924,8 @@ void CLikeSourceEmitter::emitVarModifiers(IRVarLayout* layout, IRInst* varDecl,
// Target specific modifier output
emitImageFormatModifierImpl(varDecl, varType);
- if(layout->usesResourceKind(LayoutResourceKind::VaryingInput)
- || layout->usesResourceKind(LayoutResourceKind::VaryingOutput))
+ if (layout->usesResourceKind(LayoutResourceKind::VaryingInput) ||
+ layout->usesResourceKind(LayoutResourceKind::VaryingOutput))
{
emitInterpolationModifiers(varDecl, varType, layout);
emitMeshShaderModifiers(varDecl);
@@ -3966,9 +3954,9 @@ void CLikeSourceEmitter::emitArrayBrackets(IRType* inType)
// reach a non-array type in the middle.
//
IRType* type = inType;
- for(;;)
+ for (;;)
{
- if(auto arrayType = as<IRArrayType>(type))
+ if (auto arrayType = as<IRArrayType>(type))
{
m_writer->emit("[");
emitVal(arrayType->getElementCount(), getInfo(EmitOp::General));
@@ -3978,7 +3966,7 @@ void CLikeSourceEmitter::emitArrayBrackets(IRType* inType)
//
type = arrayType->getElementType();
}
- else if(auto unsizedArrayType = as<IRUnsizedArrayType>(type))
+ else if (auto unsizedArrayType = as<IRUnsizedArrayType>(type))
{
m_writer->emit("[]");
@@ -3995,18 +3983,20 @@ void CLikeSourceEmitter::emitArrayBrackets(IRType* inType)
}
}
-void CLikeSourceEmitter::emitParameterGroup(IRGlobalParam* varDecl, IRUniformParameterGroupType* type)
+void CLikeSourceEmitter::emitParameterGroup(
+ IRGlobalParam* varDecl,
+ IRUniformParameterGroupType* type)
{
emitParameterGroupImpl(varDecl, type);
}
-void CLikeSourceEmitter::emitVarKeywordImpl(IRType * /* type */, IRInst* /* varDecl */) {}
+void CLikeSourceEmitter::emitVarKeywordImpl(IRType* /* type */, IRInst* /* varDecl */) {}
void CLikeSourceEmitter::emitVar(IRVar* varDecl)
{
auto allocatedType = varDecl->getDataType();
auto varType = allocatedType->getValueType();
-// auto addressSpace = allocatedType->getAddressSpace();
+ // auto addressSpace = allocatedType->getAddressSpace();
#if 0
switch( varType->op )
@@ -4087,14 +4077,13 @@ bool _isFoldableValue(IRInst* val)
case kIROp_CastFloatToInt:
case kIROp_IntCast:
case kIROp_FloatCast:
- {
- for (UInt i = 0; i < val->getOperandCount(); i++)
- if (!_isFoldableValue(val->getOperand(i)))
- return false;
- return true;
- }
- default:
- return false;
+ {
+ for (UInt i = 0; i < val->getOperandCount(); i++)
+ if (!_isFoldableValue(val->getOperand(i)))
+ return false;
+ return true;
+ }
+ default: return false;
}
}
@@ -4126,7 +4115,7 @@ void CLikeSourceEmitter::emitGlobalVar(IRGlobalVar* varDecl)
// If we can't emit the initializer as an expression,
// we will emit it as a separate function.
- //
+ //
// TODO: the C language does not allow defining
// functions that return arrays, so if we have an
// array type here, we are going to generate invalid
@@ -4165,8 +4154,7 @@ void CLikeSourceEmitter::emitGlobalVar(IRGlobalVar* varDecl)
m_writer->emit("static ");
break;
- default:
- break;
+ default: break;
}
emitVarModifiers(layout, varDecl, varType);
@@ -4202,7 +4190,7 @@ void CLikeSourceEmitter::emitGlobalParam(IRGlobalParam* varDecl)
auto rawType = varDecl->getDataType();
auto varType = rawType;
- if( auto outType = as<IROutTypeBase>(varType) )
+ if (auto outType = as<IROutTypeBase>(varType))
{
varType = outType->getValueType();
}
@@ -4242,7 +4230,7 @@ void CLikeSourceEmitter::emitGlobalParam(IRGlobalParam* varDecl)
SLANG_ASSERT(layout);
emitVarModifiers(layout, varDecl, varType);
-
+
emitDecorationLayoutSemantics(varDecl, "register");
emitRateQualifiersAndAddressSpace(varDecl);
@@ -4273,7 +4261,8 @@ static bool _shouldSkipFuncEmit(IRInst* func)
// only by the witness table. We will emit this func differently than normal funcs
// and this is handled by `emitComWitnessTable`.
- if (func->hasMoreThanOneUse()) return false;
+ if (func->hasMoreThanOneUse())
+ return false;
if (func->firstUse)
{
if (auto entry = as<IRWitnessTableEntry>(func->firstUse->getUser()))
@@ -4297,11 +4286,11 @@ void CLikeSourceEmitter::emitGlobalInstImpl(IRInst* inst)
{
m_writer->advanceToSourceLocation(inst->sourceLoc);
- switch(inst->getOp())
+ switch (inst->getOp())
{
case kIROp_GlobalHashedStringLiterals:
- /* Don't need to to output anything for this instruction - it's used for reflecting string literals that
- are hashed with 'getStringHash' */
+ /* Don't need to to output anything for this instruction - it's used for reflecting
+ string literals that are hashed with 'getStringHash' */
break;
case kIROp_InterfaceRequirementEntry:
@@ -4312,38 +4301,22 @@ void CLikeSourceEmitter::emitGlobalInstImpl(IRInst* inst)
case kIROp_Func:
if (!_shouldSkipFuncEmit(inst))
{
- emitFunc((IRFunc*) inst);
+ emitFunc((IRFunc*)inst);
}
break;
- case kIROp_GlobalVar:
- emitGlobalVar((IRGlobalVar*) inst);
- break;
+ case kIROp_GlobalVar: emitGlobalVar((IRGlobalVar*)inst); break;
- case kIROp_GlobalParam:
- emitGlobalParam((IRGlobalParam*) inst);
- break;
+ case kIROp_GlobalParam: emitGlobalParam((IRGlobalParam*)inst); break;
- case kIROp_Var:
- emitVar((IRVar*) inst);
- break;
+ case kIROp_Var: emitVar((IRVar*)inst); break;
- case kIROp_StructType:
- emitStruct(cast<IRStructType>(inst));
- break;
- case kIROp_ClassType:
- emitClass(cast<IRClassType>(inst));
- break;
- case kIROp_InterfaceType:
- emitInterface(cast<IRInterfaceType>(inst));
- break;
- case kIROp_WitnessTable:
- emitWitnessTable(cast<IRWitnessTable>(inst));
- break;
+ case kIROp_StructType: emitStruct(cast<IRStructType>(inst)); break;
+ case kIROp_ClassType: emitClass(cast<IRClassType>(inst)); break;
+ case kIROp_InterfaceType: emitInterface(cast<IRInterfaceType>(inst)); break;
+ case kIROp_WitnessTable: emitWitnessTable(cast<IRWitnessTable>(inst)); break;
- case kIROp_RTTIObject:
- emitRTTIObject(cast<IRRTTIObject>(inst));
- break;
+ case kIROp_RTTIObject: emitRTTIObject(cast<IRRTTIObject>(inst)); break;
default:
// We have an "ordinary" instruction at the global
@@ -4358,11 +4331,15 @@ void CLikeSourceEmitter::emitGlobalInstImpl(IRInst* inst)
}
}
-void CLikeSourceEmitter::ensureInstOperand(ComputeEmitActionsContext* ctx, IRInst* inst, EmitAction::Level requiredLevel)
+void CLikeSourceEmitter::ensureInstOperand(
+ ComputeEmitActionsContext* ctx,
+ IRInst* inst,
+ EmitAction::Level requiredLevel)
{
- if(!inst) return;
+ if (!inst)
+ return;
- if(inst->getParent() == ctx->moduleInst)
+ if (inst->getParent() == ctx->moduleInst)
{
ensureGlobalInst(ctx, inst, requiredLevel);
}
@@ -4377,36 +4354,33 @@ void CLikeSourceEmitter::ensureInstOperandsRec(ComputeEmitActionsContext* ctx, I
switch (inst->getOp())
{
case kIROp_PtrType:
- {
- auto ptrType = static_cast<IRPtrType*>(inst);
- auto valueType = ptrType->getValueType();
-
- if (ctx->openInsts.contains(valueType))
{
- requiredLevel = EmitAction::ForwardDeclaration;
- }
- else
- {
- requiredLevel = EmitAction::Definition;
+ auto ptrType = static_cast<IRPtrType*>(inst);
+ auto valueType = ptrType->getValueType();
+
+ if (ctx->openInsts.contains(valueType))
+ {
+ requiredLevel = EmitAction::ForwardDeclaration;
+ }
+ else
+ {
+ requiredLevel = EmitAction::Definition;
+ }
+ break;
}
- break;
- }
- case kIROp_NativePtrType:
- requiredLevel = EmitAction::ForwardDeclaration;
- break;
+ case kIROp_NativePtrType: requiredLevel = EmitAction::ForwardDeclaration; break;
case kIROp_LookupWitness:
case kIROp_FieldExtract:
case kIROp_FieldAddress:
- {
- auto opType = inst->getOperand(0)->getDataType();
- if (auto nativePtrType = as<IRNativePtrType>(opType))
{
- ensureInstOperand(ctx, nativePtrType->getValueType(), requiredLevel);
+ auto opType = inst->getOperand(0)->getDataType();
+ if (auto nativePtrType = as<IRNativePtrType>(opType))
+ {
+ ensureInstOperand(ctx, nativePtrType->getValueType(), requiredLevel);
+ }
+ break;
}
- break;
- }
- default:
- break;
+ default: break;
}
if (auto comWitnessDecoration = as<IRCOMWitnessDecoration>(inst))
@@ -4421,7 +4395,7 @@ void CLikeSourceEmitter::ensureInstOperandsRec(ComputeEmitActionsContext* ctx, I
requiredLevel = EmitAction::ForwardDeclaration;
}
- for(UInt ii = 0; ii < operandCount; ++ii)
+ for (UInt ii = 0; ii < operandCount; ++ii)
{
// TODO: there are some special cases we can add here,
// to avoid outputting full definitions in cases that
@@ -4435,23 +4409,23 @@ void CLikeSourceEmitter::ensureInstOperandsRec(ComputeEmitActionsContext* ctx, I
ensureInstOperand(ctx, inst->getOperand(ii), requiredLevel);
}
- for(auto child : inst->getDecorationsAndChildren())
+ for (auto child : inst->getDecorationsAndChildren())
{
ensureInstOperandsRec(ctx, child);
}
}
-void CLikeSourceEmitter::ensureGlobalInst(ComputeEmitActionsContext* ctx, IRInst* inst, EmitAction::Level requiredLevel)
+void CLikeSourceEmitter::ensureGlobalInst(
+ ComputeEmitActionsContext* ctx,
+ IRInst* inst,
+ EmitAction::Level requiredLevel)
{
// Skip certain instructions that don't affect output.
- switch(inst->getOp())
+ switch (inst->getOp())
{
- case kIROp_Generic:
- return;
- case kIROp_ThisType:
- return;
- default:
- break;
+ case kIROp_Generic: return;
+ case kIROp_ThisType: return;
+ default: break;
}
if (as<IRBasicType>(inst))
return;
@@ -4465,17 +4439,16 @@ void CLikeSourceEmitter::ensureGlobalInst(ComputeEmitActionsContext* ctx, IRInst
// but the pointer type itself should be considered emitted as definition.
requiredLevel = EmitAction::Level::Definition;
break;
- default:
- break;
+ default: break;
}
// Have we already processed this instruction?
EmitAction::Level existingLevel;
- if(ctx->mapInstToLevel.tryGetValue(inst, existingLevel))
+ if (ctx->mapInstToLevel.tryGetValue(inst, existingLevel))
{
// If we've already emitted it suitably,
// then don't worry about it.
- if(existingLevel >= requiredLevel)
+ if (existingLevel >= requiredLevel)
return;
}
@@ -4483,9 +4456,9 @@ void CLikeSourceEmitter::ensureGlobalInst(ComputeEmitActionsContext* ctx, IRInst
action.level = requiredLevel;
action.inst = inst;
- if(requiredLevel == EmitAction::Level::Definition)
+ if (requiredLevel == EmitAction::Level::Definition)
{
- if(ctx->openInsts.contains(inst))
+ if (ctx->openInsts.contains(inst))
{
SLANG_UNEXPECTED("circularity during codegen");
return;
@@ -4504,12 +4477,11 @@ void CLikeSourceEmitter::ensureGlobalInst(ComputeEmitActionsContext* ctx, IRInst
switch (inst->getOp())
{
case kIROp_InterfaceRequirementEntry:
- {
- return;
- }
+ {
+ return;
+ }
- default:
- break;
+ default: break;
}
ctx->actions->add(action);
}
@@ -4521,13 +4493,13 @@ void CLikeSourceEmitter::computeEmitActions(IRModule* module, List<EmitAction>&
ctx.actions = &ioActions;
ctx.openInsts = InstHashSet(module);
- for(auto inst : module->getGlobalInsts())
+ for (auto inst : module->getGlobalInsts())
{
// Emit all resource-typed objects first. This is to avoid an odd scenario in HLSL
// where not using a resource type in a resource definition before the same type
// is used for a function parameter causes HLSL to complain about an 'incomplete type'
- //
- if ( isResourceType(inst->getDataType()) )
+ //
+ if (isResourceType(inst->getDataType()))
{
ensureGlobalInst(&ctx, inst, EmitAction::Level::Definition);
}
@@ -4554,9 +4526,9 @@ void CLikeSourceEmitter::computeEmitActions(IRModule* module, List<EmitAction>&
};
}
}
- for(auto inst : module->getGlobalInsts())
+ for (auto inst : module->getGlobalInsts())
{
- if( as<IRType>(inst) )
+ if (as<IRType>(inst))
{
// Don't emit a type unless it is actually used or is marked exported.
if (!inst->findDecoration<IRHLSLExportDecoration>())
@@ -4564,7 +4536,7 @@ void CLikeSourceEmitter::computeEmitActions(IRModule* module, List<EmitAction>&
}
// Skip resource types in this pass.
- if ( isResourceType(inst->getDataType()) )
+ if (isResourceType(inst->getDataType()))
continue;
ensureGlobalInst(&ctx, inst, EmitAction::Level::Definition);
@@ -4575,42 +4547,35 @@ void CLikeSourceEmitter::emitForwardDeclaration(IRInst* inst)
{
switch (inst->getOp())
{
- case kIROp_Func:
- emitFuncDecl(cast<IRFunc>(inst));
- break;
+ case kIROp_Func: emitFuncDecl(cast<IRFunc>(inst)); break;
case kIROp_StructType:
m_writer->emit("struct ");
m_writer->emit(getName(inst));
m_writer->emit(";\n");
break;
case kIROp_InterfaceType:
- {
- if (inst->findDecoration<IRComInterfaceDecoration>())
{
- m_writer->emit("struct ");
- m_writer->emit(getName(inst));
- m_writer->emit(";\n");
+ if (inst->findDecoration<IRComInterfaceDecoration>())
+ {
+ m_writer->emit("struct ");
+ m_writer->emit(getName(inst));
+ m_writer->emit(";\n");
+ }
+ break;
}
- break;
- }
- default:
- SLANG_UNREACHABLE("emit forward declaration");
+ default: SLANG_UNREACHABLE("emit forward declaration");
}
}
void CLikeSourceEmitter::executeEmitActions(List<EmitAction> const& actions)
{
- for(auto action : actions)
+ for (auto action : actions)
{
- switch(action.level)
+ switch (action.level)
{
- case EmitAction::Level::ForwardDeclaration:
- emitForwardDeclaration(action.inst);
- break;
+ case EmitAction::Level::ForwardDeclaration: emitForwardDeclaration(action.inst); break;
- case EmitAction::Level::Definition:
- emitGlobalInst(action.inst);
- break;
+ case EmitAction::Level::Definition: emitGlobalInst(action.inst); break;
}
}
}