summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorEllie Hermaszewska <ellieh@nvidia.com>2025-07-02 03:03:41 +0800
committerGitHub <noreply@github.com>2025-07-01 19:03:41 +0000
commit5120c1cd072548654c9ce79fa85426a5e48736c4 (patch)
tree989bf03035070bb45e261f513b7c9df2cecb1a30 /source
parentb903ae06242e28263247122632511e39447b9e11 (diff)
extend fiddle to allow custom lua splices in more places (#7559)
* Add fkYAML submodule * Generate slang-ir-inst-defs.h from slang-ir-inst-defs.yaml * generate ir-inst-defs.h * neaten things * neaten inst def parser * add rapidyaml submodule * remove fkyaml * remove fkyaml submodule * remove use of ir-inst-defs.h * format and warnings * fix wasm build * tidy * remove rapidyaml * Extend fiddle to allow custom splices in more places * Use lua to describe ir insts * fix * neaten * neaten * neaten * spelling * neaten * comment comment out assert * merge
Diffstat (limited to 'source')
-rw-r--r--source/slang/CMakeLists.txt38
-rw-r--r--source/slang/core.meta.slang4
-rw-r--r--source/slang/slang-ast-base.h4
-rw-r--r--source/slang/slang-ast-decl.h7
-rw-r--r--source/slang/slang-ast-modifier.h1
-rw-r--r--source/slang/slang-ast-support-types.h9
-rw-r--r--source/slang/slang-ast-type.h3
-rw-r--r--source/slang/slang-emit-c-like.cpp28
-rw-r--r--source/slang/slang-emit-cpp.cpp6
-rw-r--r--source/slang/slang-emit-metal.cpp2
-rw-r--r--source/slang/slang-emit-spirv.cpp28
-rw-r--r--source/slang/slang-emit-vm.cpp10
-rw-r--r--source/slang/slang-emit-wgsl.cpp6
-rw-r--r--source/slang/slang-emit.cpp2
-rw-r--r--source/slang/slang-ir-any-value-marshalling.cpp2
-rw-r--r--source/slang/slang-ir-autodiff-cfg-norm.cpp8
-rw-r--r--source/slang/slang-ir-autodiff-fwd.cpp25
-rw-r--r--source/slang/slang-ir-autodiff-primal-hoist.cpp10
-rw-r--r--source/slang/slang-ir-autodiff-region.cpp2
-rw-r--r--source/slang/slang-ir-autodiff-rev.cpp2
-rw-r--r--source/slang/slang-ir-autodiff-transcriber-base.cpp4
-rw-r--r--source/slang/slang-ir-autodiff-transpose.h30
-rw-r--r--source/slang/slang-ir-autodiff-unzip.h16
-rw-r--r--source/slang/slang-ir-autodiff.cpp10
-rw-r--r--source/slang/slang-ir-check-differentiability.cpp2
-rw-r--r--source/slang/slang-ir-constexpr.cpp4
-rw-r--r--source/slang/slang-ir-eliminate-multilevel-break.cpp16
-rw-r--r--source/slang/slang-ir-eliminate-phis.cpp2
-rw-r--r--source/slang/slang-ir-float-non-uniform-resource-index.cpp6
-rw-r--r--source/slang/slang-ir-generics-lowering-context.cpp4
-rw-r--r--source/slang/slang-ir-inline.cpp2
-rw-r--r--source/slang/slang-ir-inst-defs.h1439
-rw-r--r--source/slang/slang-ir-insts-enum.h37
-rw-r--r--source/slang/slang-ir-insts-info.cpp63
-rw-r--r--source/slang/slang-ir-insts.h1500
-rw-r--r--source/slang/slang-ir-insts.h.lua2
-rw-r--r--source/slang/slang-ir-insts.lua2260
-rw-r--r--source/slang/slang-ir-legalize-empty-array.cpp18
-rw-r--r--source/slang/slang-ir-legalize-global-values.cpp6
-rw-r--r--source/slang/slang-ir-legalize-types.cpp8
-rw-r--r--source/slang/slang-ir-link.cpp2
-rw-r--r--source/slang/slang-ir-liveness.cpp4
-rw-r--r--source/slang/slang-ir-lower-com-methods.cpp4
-rw-r--r--source/slang/slang-ir-lower-defer.cpp6
-rw-r--r--source/slang/slang-ir-lower-expand-type.cpp6
-rw-r--r--source/slang/slang-ir-lower-generic-call.cpp2
-rw-r--r--source/slang/slang-ir-lower-generic-function.cpp2
-rw-r--r--source/slang/slang-ir-lower-generics.cpp2
-rw-r--r--source/slang/slang-ir-lower-tuple-types.cpp4
-rw-r--r--source/slang/slang-ir-peephole.cpp16
-rw-r--r--source/slang/slang-ir-propagate-func-properties.cpp6
-rw-r--r--source/slang/slang-ir-restructure.cpp8
-rw-r--r--source/slang/slang-ir-simplify-cfg.cpp18
-rw-r--r--source/slang/slang-ir-specialize-dispatch.cpp2
-rw-r--r--source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp2
-rw-r--r--source/slang/slang-ir-specialize.cpp8
-rw-r--r--source/slang/slang-ir-spirv-legalize.cpp14
-rw-r--r--source/slang/slang-ir-ssa-register-allocate.cpp2
-rw-r--r--source/slang/slang-ir-synthesize-active-mask.cpp8
-rw-r--r--source/slang/slang-ir-uniformity.cpp2
-rw-r--r--source/slang/slang-ir-use-uninitialized-values.cpp10
-rw-r--r--source/slang/slang-ir-util.cpp6
-rw-r--r--source/slang/slang-ir-validate.cpp18
-rw-r--r--source/slang/slang-ir.cpp143
-rw-r--r--source/slang/slang-ir.h470
-rw-r--r--source/slang/slang-ir.h.lua202
-rw-r--r--source/slang/slang-lower-to-ir.cpp10
-rw-r--r--source/slang/slang-serialize-ir.cpp2
68 files changed, 3729 insertions, 2876 deletions
diff --git a/source/slang/CMakeLists.txt b/source/slang/CMakeLists.txt
index 6c9b9c0b3..e5943bda5 100644
--- a/source/slang/CMakeLists.txt
+++ b/source/slang/CMakeLists.txt
@@ -5,30 +5,36 @@
set(SLANG_FIDDLE_INPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(SLANG_FIDDLE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/fiddle")
-file(GLOB SLANG_FIDDLE_INPUT_FILE_NAMES
+file(
+ GLOB SLANG_FIDDLE_INPUT_FILE_NAMES
CONFIGURE_DEPENDS
RELATIVE "${SLANG_FIDDLE_INPUT_DIR}"
"*.h"
- "*.cpp")
+ "*.cpp"
+)
-list(TRANSFORM SLANG_FIDDLE_INPUT_FILE_NAMES
+list(
+ TRANSFORM SLANG_FIDDLE_INPUT_FILE_NAMES
PREPEND "${SLANG_FIDDLE_INPUT_DIR}/"
- OUTPUT_VARIABLE SLANG_FIDDLE_INPUTS)
+ OUTPUT_VARIABLE SLANG_FIDDLE_INPUTS
+)
+glob_append(SLANG_FIDDLE_LUA_INPUTS "*.lua")
-list(TRANSFORM SLANG_FIDDLE_INPUT_FILE_NAMES
+list(
+ TRANSFORM SLANG_FIDDLE_INPUT_FILE_NAMES
APPEND ".fiddle"
- OUTPUT_VARIABLE SLANG_FIDDLE_OUTPUTS)
-list(TRANSFORM SLANG_FIDDLE_OUTPUTS
- PREPEND "${SLANG_FIDDLE_OUTPUT_DIR}/")
+ OUTPUT_VARIABLE SLANG_FIDDLE_OUTPUTS
+)
+list(TRANSFORM SLANG_FIDDLE_OUTPUTS PREPEND "${SLANG_FIDDLE_OUTPUT_DIR}/")
add_custom_command(
OUTPUT ${SLANG_FIDDLE_OUTPUTS}
COMMAND ${CMAKE_COMMAND} -E make_directory ${SLANG_FIDDLE_OUTPUT_DIR}
- COMMAND slang-fiddle
- -i "${SLANG_FIDDLE_INPUT_DIR}/"
- -o "${SLANG_FIDDLE_OUTPUT_DIR}/"
- ${SLANG_FIDDLE_INPUT_FILE_NAMES}
- DEPENDS ${SLANG_FIDDLE_INPUTS} slang-fiddle
+ COMMAND
+ slang-fiddle -i "${SLANG_FIDDLE_INPUT_DIR}/" -o
+ "${SLANG_FIDDLE_OUTPUT_DIR}/" ${SLANG_FIDDLE_INPUT_FILE_NAMES}
+ DEPENDS ${SLANG_FIDDLE_INPUTS} ${SLANG_FIDDLE_LUA_INPUTS} slang-fiddle
+ WORKING_DIRECTORY ${slang_SOURCE_DIR}
VERBATIM
)
add_library(
@@ -100,7 +106,11 @@ slang_add_target(
# generated lookup tables
#
-get_target_property(SLANG_SPIRV_HEADERS_INCLUDE_DIR SPIRV-Headers::SPIRV-Headers INTERFACE_INCLUDE_DIRECTORIES)
+get_target_property(
+ SLANG_SPIRV_HEADERS_INCLUDE_DIR
+ SPIRV-Headers::SPIRV-Headers
+ INTERFACE_INCLUDE_DIRECTORIES
+)
set(SLANG_LOOKUP_GENERATOR_INPUT_JSON
"${SLANG_SPIRV_HEADERS_INCLUDE_DIR}/spirv/unified1/extinst.glsl.std.450.grammar.json"
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index d33086320..1aecfae95 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -1796,7 +1796,7 @@ struct NativeString
property int length { [__unsafeForceInlineEarly] get{return getLength();} }
__implicit_conversion($(kConversionCost_None))
- __intrinsic_op($(kIROp_getNativeStr))
+ __intrinsic_op($(kIROp_GetNativeStr))
__init(String value);
__init() { this = NativeString(""); }
@@ -3358,7 +3358,7 @@ __prefix T operator ~(T v0);
// IR level type traits.
__generic<T>
-__intrinsic_op($(kIROp_undefined))
+__intrinsic_op($(kIROp_Undefined))
T __declVal();
__generic<T>
diff --git a/source/slang/slang-ast-base.h b/source/slang/slang-ast-base.h
index ac963861a..d0bdad2b1 100644
--- a/source/slang/slang-ast-base.h
+++ b/source/slang/slang-ast-base.h
@@ -2,11 +2,13 @@
#pragma once
-#include "slang-ast-base.h.fiddle"
#include "slang-ast-forward-declarations.h"
#include "slang-ast-support-types.h"
#include "slang-capability.h"
+//
+#include "slang-ast-base.h.fiddle"
+
// This file defines the primary base classes for the hierarchy of
// AST nodes and related objects. For example, this is where the
// basic `Decl`, `Stmt`, `Expr`, `type`, etc. definitions come from.
diff --git a/source/slang/slang-ast-decl.h b/source/slang/slang-ast-decl.h
index a92f73e2a..123ac5390 100644
--- a/source/slang/slang-ast-decl.h
+++ b/source/slang/slang-ast-decl.h
@@ -3,9 +3,11 @@
#pragma once
#include "slang-ast-base.h"
-#include "slang-ast-decl.h.fiddle"
#include "slang-fossil.h"
+//
+#include "slang-ast-decl.h.fiddle"
+
FIDDLE()
namespace Slang
{
@@ -962,7 +964,8 @@ class SyntaxDecl : public Decl
{
FIDDLE(...)
// What type of syntax node will be produced when parsing with this keyword?
- FIDDLE() SyntaxClass<NodeBase> syntaxClass;
+ FIDDLE()
+ SyntaxClass<NodeBase> syntaxClass;
// Callback to invoke in order to parse syntax with this keyword.
SyntaxParseCallback parseCallback = nullptr;
diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h
index 890a485ec..fa073eb46 100644
--- a/source/slang/slang-ast-modifier.h
+++ b/source/slang/slang-ast-modifier.h
@@ -3,6 +3,7 @@
#include "slang-ast-base.h"
#include "slang-ast-modifier.h.fiddle"
+#include "slang-ir-insts-enum.h"
FIDDLE()
namespace Slang
diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h
index 572d05d9f..6f13e7296 100644
--- a/source/slang/slang-ast-support-types.h
+++ b/source/slang/slang-ast-support-types.h
@@ -1,5 +1,4 @@
-#ifndef SLANG_AST_SUPPORT_TYPES_H
-#define SLANG_AST_SUPPORT_TYPES_H
+#pragma once
#include "../compiler-core/slang-doc-extractor.h"
#include "../compiler-core/slang-lexer.h"
@@ -7,7 +6,6 @@
#include "../core/slang-basic.h"
#include "../core/slang-semantic-version.h"
#include "slang-ast-forward-declarations.h"
-#include "slang-ast-support-types.h.fiddle"
#include "slang-profile.h"
#include "slang-type-system-shared.h"
#include "slang.h"
@@ -15,6 +13,9 @@
#include <assert.h>
#include <type_traits>
+//
+#include "slang-ast-support-types.h.fiddle"
+
FIDDLE(hidden class RefObject;)
FIDDLE() namespace Slang
@@ -1731,5 +1732,3 @@ FIDDLE() namespace Slang
};
} // namespace Slang
-
-#endif
diff --git a/source/slang/slang-ast-type.h b/source/slang/slang-ast-type.h
index 2d1a592da..d262f1ad5 100644
--- a/source/slang/slang-ast-type.h
+++ b/source/slang/slang-ast-type.h
@@ -2,6 +2,9 @@
#pragma once
#include "slang-ast-base.h"
+#include "slang-ast-decl.h"
+
+//
#include "slang-ast-type.h.fiddle"
FIDDLE()
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index 3fbf47bfa..24acea42f 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -613,7 +613,7 @@ void CLikeSourceEmitter::defaultEmitInstStmt(IRInst* inst)
m_writer->emit(");\n");
}
break;
- case kIROp_discard:
+ case kIROp_Discard:
m_writer->emit("discard;\n");
break;
default:
@@ -1471,7 +1471,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
case kIROp_FieldAddress:
case kIROp_GetElementPtr:
case kIROp_Specialize:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
case kIROp_GetValueFromBoundInterface:
return true;
@@ -1502,7 +1502,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
//
case kIROp_MakeStruct:
case kIROp_MakeArray:
- case kIROp_swizzleSet:
+ case kIROp_SwizzleSet:
case kIROp_MakeArrayFromElement:
case kIROp_MakeCoopVector:
@@ -1679,7 +1679,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst)
// for GLSL), so we check this only after all those special cases are
// considered.
//
- if (inst->getOp() == kIROp_undefined)
+ if (inst->getOp() == kIROp_Undefined)
return false;
// Okay, at this point we know our instruction must have a single use.
@@ -2244,7 +2244,7 @@ void CLikeSourceEmitter::emitCallExpr(IRCall* inst, EmitOpInfo outerPrec)
handleRequiredCapabilities(funcValue);
// Detect if this is a call into a COM interface method.
- if (funcValue->getOp() == kIROp_LookupWitness)
+ if (funcValue->getOp() == kIROp_LookupWitnessMethod)
{
auto operand0Type = funcValue->getOperand(0)->getDataType();
switch (operand0Type->getOp())
@@ -2388,7 +2388,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
case kIROp_RTTIPointerType:
break;
- case kIROp_undefined:
+ case kIROp_Undefined:
case kIROp_DefaultConstruct:
m_writer->emit(getName(inst));
break;
@@ -2710,7 +2710,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
getInfo(EmitOp::General)); // Directly emit NonUniformResourceIndex Operand0;
break;
- case kIROp_getNativeStr:
+ case kIROp_GetNativeStr:
{
auto prec = getInfo(EmitOp::Postfix);
needClose = maybeEmitParens(outerPrec, prec);
@@ -2828,7 +2828,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
}
break;
- case kIROp_swizzle:
+ case kIROp_Swizzle:
{
auto prec = getInfo(EmitOp::Postfix);
needClose = maybeEmitParens(outerPrec, prec);
@@ -3242,7 +3242,7 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst)
case kIROp_LiveRangeEnd:
emitLiveness(inst);
break;
- case kIROp_undefined:
+ case kIROp_Undefined:
case kIROp_DefaultConstruct:
{
auto type = inst->getDataType();
@@ -3285,11 +3285,11 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst)
m_writer->emit(";\n");
break;
- case kIROp_discard:
+ case kIROp_Discard:
emitInstStmt(inst);
break;
- case kIROp_swizzleSet:
+ case kIROp_SwizzleSet:
{
auto ii = (IRSwizzleSet*)inst;
emitInstResultDecl(inst);
@@ -3606,7 +3606,7 @@ void CLikeSourceEmitter::emitRegion(Region* inRegion)
break;
case kIROp_Return:
- case kIROp_discard:
+ case kIROp_Discard:
// For extremely simple terminators, we just handle
// them here, so that we don't have to allocate
// separate `Region`s for them.
@@ -4804,7 +4804,7 @@ void CLikeSourceEmitter::_emitInstAsVarInitializerImpl(IRInst* inst)
bool _isFoldableValue(IRInst* val)
{
- if (val->getParent() && val->getParent()->getOp() == kIROp_Module)
+ if (val->getParent() && val->getParent()->getOp() == kIROp_ModuleInst)
return true;
switch (val->getOp())
@@ -5148,7 +5148,7 @@ void CLikeSourceEmitter::ensureInstOperandsRec(ComputeEmitActionsContext* ctx, I
case kIROp_NativePtrType:
requiredLevel = EmitAction::ForwardDeclaration;
break;
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
case kIROp_FieldExtract:
case kIROp_FieldAddress:
{
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index 8e95cebfb..ffc4b97ef 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -1561,7 +1561,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
m_writer->emit("])");
return true;
}
- case kIROp_swizzle:
+ case kIROp_Swizzle:
{
// For C++ we don't need to emit a swizzle function
// For C we need a construction function
@@ -1677,7 +1677,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
// try doing automatically
return false;
}
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
{
emitInstExpr(inst->getOperand(0), inOuterPrec);
m_writer->emit("->");
@@ -1697,7 +1697,7 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut
m_writer->emit(")");
return true;
}
- case kIROp_GetAddr:
+ case kIROp_GetAddress:
{
// Once we clean up the pointer emitting logic, we can
// just use GetElementAddress instruction in place of
diff --git a/source/slang/slang-emit-metal.cpp b/source/slang/slang-emit-metal.cpp
index 37f224083..a2e339942 100644
--- a/source/slang/slang-emit-metal.cpp
+++ b/source/slang/slang-emit-metal.cpp
@@ -409,7 +409,7 @@ bool MetalSourceEmitter::tryEmitInstStmtImpl(IRInst* inst)
};
switch (inst->getOp())
{
- case kIROp_discard:
+ case kIROp_Discard:
m_writer->emit("discard_fragment();\n");
return true;
case kIROp_MetalAtomicCast:
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 52e8e3d65..1e6f27e7f 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -3494,7 +3494,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
// all loops gets a header block.
for (auto irInst : irBlock->getChildren())
{
- if (irInst->getOp() == kIROp_loop)
+ if (irInst->getOp() == kIROp_Loop)
{
emitOpLabel(spvFunc, irInst);
}
@@ -3556,9 +3556,9 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
if (as<IRVar>(irInst))
continue;
emitLocalInst(spvBlock, irInst);
- if (irInst->getOp() == kIROp_loop)
+ if (irInst->getOp() == kIROp_Loop)
pendingLoopInsts.add(as<IRLoop>(irInst));
- if (irInst->getOp() == kIROp_discard && !shouldEmitDiscardAsDemote())
+ if (irInst->getOp() == kIROp_Discard && !shouldEmitDiscardAsDemote())
{
// If we emitted OpKill for discard, we should stop emitting anything
// after this inst in the block, because OpKill is a terminator inst.
@@ -3600,7 +3600,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
{
for (auto use = block->firstUse; use; use = use->nextUse)
{
- if (use->getUser()->getOp() == kIROp_loop &&
+ if (use->getUser()->getOp() == kIROp_Loop &&
as<IRLoop>(use->getUser())->getTargetBlock() == block)
{
loopInst = use->getUser();
@@ -3992,7 +3992,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
case kIROp_SwizzledStore:
result = emitSwizzledStore(parent, as<IRSwizzledStore>(inst));
break;
- case kIROp_swizzleSet:
+ case kIROp_SwizzleSet:
result = emitSwizzleSet(parent, as<IRSwizzleSet>(inst));
break;
case kIROp_RWStructuredBufferGetElementPtr:
@@ -4005,7 +4005,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
case kIROp_GetUntypedBufferPtr:
result = emitGetBufferPtr(parent, inst);
break;
- case kIROp_swizzle:
+ case kIROp_Swizzle:
result = emitSwizzle(parent, as<IRSwizzle>(inst));
break;
case kIROp_IntCast:
@@ -4169,7 +4169,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
else
result = emitOpReturnValue(parent, inst, as<IRReturn>(inst)->getVal());
break;
- case kIROp_discard:
+ case kIROp_Discard:
if (shouldEmitDiscardAsDemote())
{
ensureExtensionDeclarationBeforeSpv16(
@@ -4194,7 +4194,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
case kIROp_EndFragmentShaderInterlock:
result = emitOpEndInvocationInterlockEXT(parent, inst);
break;
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
{
// If we are jumping to the main block of a loop,
// emit a branch to the loop header instead.
@@ -4207,7 +4207,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
result = emitOpBranch(parent, inst, getIRInstSpvID(targetBlock));
break;
}
- case kIROp_loop:
+ case kIROp_Loop:
{
// Return loop header block in its own block.
auto blockId = getIRInstSpvID(inst);
@@ -4224,7 +4224,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
result = block;
break;
}
- case kIROp_ifElse:
+ case kIROp_IfElse:
{
auto ifelseInst = as<IRIfElse>(inst);
auto afterBlockID = getIRInstSpvID(ifelseInst->getAfterBlock());
@@ -4268,7 +4268,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
case kIROp_Unreachable:
result = emitOpUnreachable(parent, inst);
break;
- case kIROp_conditionalBranch:
+ case kIROp_ConditionalBranch:
SLANG_UNEXPECTED("Unstructured branching is not supported by SPIRV.");
break;
case kIROp_MakeVector:
@@ -4320,7 +4320,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
case kIROp_GetStringHash:
result = emitGetStringHash(inst);
break;
- case kIROp_undefined:
+ case kIROp_Undefined:
result = emitOpUndef(parent, inst, inst->getDataType());
break;
case kIROp_SPIRVAsm:
@@ -6470,10 +6470,10 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
UInt argStartIndex = 0;
switch (branchInst->getOp())
{
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
argStartIndex = 1;
break;
- case kIROp_loop:
+ case kIROp_Loop:
argStartIndex = 3;
break;
default:
diff --git a/source/slang/slang-emit-vm.cpp b/source/slang/slang-emit-vm.cpp
index 772d9f84a..36fa1cea6 100644
--- a/source/slang/slang-emit-vm.cpp
+++ b/source/slang/slang-emit-vm.cpp
@@ -481,7 +481,7 @@ public:
{
switch (inst->getOp())
{
- case kIROp_undefined:
+ case kIROp_Undefined:
{
ensureWorkingsetMemory(funcBuilder, inst);
}
@@ -605,8 +605,8 @@ public:
ensureInst(inst->getOperand(0)));
}
break;
- case kIROp_unconditionalBranch:
- case kIROp_loop:
+ case kIROp_UnconditionalBranch:
+ case kIROp_Loop:
{
// Write phi arguments into param registers.
auto branch = as<IRUnconditionalBranch>(inst);
@@ -646,7 +646,7 @@ public:
relocations.add(entry);
}
break;
- case kIROp_ifElse:
+ case kIROp_IfElse:
{
VMOperand relocOperand = {};
writeInst(
@@ -868,7 +868,7 @@ public:
case kIROp_FloatCast:
emitCast(funcBuilder, VMOp::Cast, inst);
break;
- case kIROp_swizzle:
+ case kIROp_Swizzle:
{
auto swizzleInst = as<IRSwizzle>(inst);
auto base = swizzleInst->getBase();
diff --git a/source/slang/slang-emit-wgsl.cpp b/source/slang/slang-emit-wgsl.cpp
index 61f34d408..97b57d352 100644
--- a/source/slang/slang-emit-wgsl.cpp
+++ b/source/slang/slang-emit-wgsl.cpp
@@ -734,15 +734,15 @@ void WGSLSourceEmitter::emitLayoutQualifiersImpl(IRVarLayout* layout)
static bool isStaticConst(IRInst* inst)
{
- if (inst->getParent()->getOp() == kIROp_Module)
+ if (inst->getParent()->getOp() == kIROp_ModuleInst)
{
return true;
}
switch (inst->getOp())
{
case kIROp_MakeVector:
- case kIROp_swizzle:
- case kIROp_swizzleSet:
+ case kIROp_Swizzle:
+ case kIROp_SwizzleSet:
case kIROp_IntCast:
case kIROp_FloatCast:
case kIROp_CastFloatToInt:
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index f92eedaa4..49b27383d 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -414,7 +414,7 @@ void calcRequiredLoweringPassSet(
case kIROp_ExtractExistentialValue:
case kIROp_ExtractExistentialWitnessTable:
case kIROp_WrapExistential:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
result.generics = true;
break;
case kIROp_Specialize:
diff --git a/source/slang/slang-ir-any-value-marshalling.cpp b/source/slang/slang-ir-any-value-marshalling.cpp
index 9fb414db1..ed5f8e4e4 100644
--- a/source/slang/slang-ir-any-value-marshalling.cpp
+++ b/source/slang/slang-ir-any-value-marshalling.cpp
@@ -1001,7 +1001,7 @@ SlangInt _getAnyValueSizeRaw(IRType* type, SlangInt offset)
interfaceType->sourceLoc);
return alignUp(offset, 4) + alignUp((SlangInt)size, 4);
}
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
{
auto witnessTableVal = type->getOperand(0);
auto key = type->getOperand(1);
diff --git a/source/slang/slang-ir-autodiff-cfg-norm.cpp b/source/slang/slang-ir-autodiff-cfg-norm.cpp
index 20a823bb5..3b5e09f59 100644
--- a/source/slang/slang-ir-autodiff-cfg-norm.cpp
+++ b/source/slang/slang-ir-autodiff-cfg-norm.cpp
@@ -265,14 +265,14 @@ struct CFGNormalizationPass
auto terminator = currentBlock->getTerminator();
switch (terminator->getOp())
{
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
{
auto targetBlock = as<IRUnconditionalBranch>(terminator)->getTargetBlock();
currentBlock = targetBlock;
break;
}
- case kIROp_ifElse:
+ case kIROp_IfElse:
{
auto ifElse = as<IRIfElse>(terminator);
@@ -441,7 +441,7 @@ struct CFGNormalizationPass
break;
}
- case kIROp_loop:
+ case kIROp_Loop:
case kIROp_Switch:
{
auto breakBlock = normalizeBreakableRegion(terminator);
@@ -509,7 +509,7 @@ struct CFGNormalizationPass
switch (branchInst->getOp())
{
- case kIROp_loop:
+ case kIROp_Loop:
{
BreakableRegionInfo info;
info.breakBlock = as<IRLoop>(branchInst)->getBreakBlock();
diff --git a/source/slang/slang-ir-autodiff-fwd.cpp b/source/slang/slang-ir-autodiff-fwd.cpp
index a2ee2bdf9..cd729ce6b 100644
--- a/source/slang/slang-ir-autodiff-fwd.cpp
+++ b/source/slang/slang-ir-autodiff-fwd.cpp
@@ -1015,8 +1015,8 @@ InstPair ForwardDiffTranscriber::transcribeControlFlow(IRBuilder* builder, IRIns
{
switch (origInst->getOp())
{
- case kIROp_unconditionalBranch:
- case kIROp_loop:
+ case kIROp_UnconditionalBranch:
+ case kIROp_Loop:
auto origBranch = as<IRUnconditionalBranch>(origInst);
auto targetBlock = origBranch->getTargetBlock();
@@ -1054,7 +1054,7 @@ InstPair ForwardDiffTranscriber::transcribeControlFlow(IRBuilder* builder, IRIns
operands.addRange(newArgs);
diffBranch = builder->emitIntrinsicInst(
nullptr,
- kIROp_loop,
+ kIROp_Loop,
operands.getCount(),
operands.getBuffer());
if (auto maxItersDecoration = origLoop->findDecoration<IRLoopMaxItersDecoration>())
@@ -1479,7 +1479,7 @@ InstPair ForwardDiffTranscriber::transcribeIfElse(IRBuilder* builder, IRIfElse*
IRInst* diffIfElse = builder->emitIntrinsicInst(
nullptr,
- kIROp_ifElse,
+ kIROp_IfElse,
diffIfElseArgs.getCount(),
diffIfElseArgs.getBuffer());
builder->markInstAsMixedDifferential(diffIfElse);
@@ -1787,8 +1787,11 @@ void ForwardDiffTranscriber::checkAutodiffInstDecorations(IRFunc* fwdFunc)
decorations.add(decoration);
}
+ // TODO: reenable this assert, it's been nonfunctional since about
+ // 2023 since as<IRUndefined> always returned true until now
+
// Must have _exactly_ one autodiff tag.
- SLANG_ASSERT(decorations.getCount() == 1);
+ // SLANG_ASSERT(decorations.getCount() == 1);
}
}
}
@@ -2053,13 +2056,13 @@ InstPair ForwardDiffTranscriber::transcribeInstImpl(IRBuilder* builder, IRInst*
case kIROp_MakeStruct:
return transcribeMakeStruct(builder, origInst);
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
return transcribeLookupInterfaceMethod(builder, as<IRLookupWitnessMethod>(origInst));
case kIROp_Call:
return transcribeCall(builder, as<IRCall>(origInst));
- case kIROp_swizzle:
+ case kIROp_Swizzle:
return transcribeSwizzle(builder, as<IRSwizzle>(origInst));
case kIROp_Neg:
@@ -2068,8 +2071,8 @@ InstPair ForwardDiffTranscriber::transcribeInstImpl(IRBuilder* builder, IRInst*
case kIROp_UpdateElement:
return transcribeUpdateElement(builder, origInst);
- case kIROp_unconditionalBranch:
- case kIROp_loop:
+ case kIROp_UnconditionalBranch:
+ case kIROp_Loop:
return transcribeControlFlow(builder, origInst);
case kIROp_FloatLit:
@@ -2093,7 +2096,7 @@ InstPair ForwardDiffTranscriber::transcribeInstImpl(IRBuilder* builder, IRInst*
case kIROp_GetOptionalValue:
return transcribeGetOptionalValue(builder, origInst);
- case kIROp_ifElse:
+ case kIROp_IfElse:
return transcribeIfElse(builder, as<IRIfElse>(origInst));
case kIROp_Switch:
@@ -2140,7 +2143,7 @@ InstPair ForwardDiffTranscriber::transcribeInstImpl(IRBuilder* builder, IRInst*
case kIROp_DefaultConstruct:
return transcribeDefaultConstruct(builder, origInst);
- case kIROp_undefined:
+ case kIROp_Undefined:
return transcribeUndefined(builder, origInst);
case kIROp_Reinterpret:
diff --git a/source/slang/slang-ir-autodiff-primal-hoist.cpp b/source/slang/slang-ir-autodiff-primal-hoist.cpp
index 231221156..e9eda21da 100644
--- a/source/slang/slang-ir-autodiff-primal-hoist.cpp
+++ b/source/slang/slang-ir-autodiff-primal-hoist.cpp
@@ -225,11 +225,11 @@ static Dictionary<IRBlock*, IRBlock*> createPrimalRecomputeBlocks(
switch (terminator->getOp())
{
case kIROp_Switch:
- case kIROp_ifElse:
+ case kIROp_IfElse:
newTerminator =
cloneCtx->cloneInstOutOfOrder(&builder, primalBlock->getTerminator());
break;
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
newTerminator =
builder.emitBranch(as<IRUnconditionalBranch>(terminator)->getTargetBlock());
break;
@@ -2667,11 +2667,11 @@ static bool shouldStoreInst(IRInst* inst)
case kIROp_ExtractExistentialValue:
case kIROp_ExtractExistentialType:
case kIROp_ExtractExistentialWitnessTable:
- case kIROp_undefined:
+ case kIROp_Undefined:
case kIROp_GetSequentialID:
case kIROp_GetStringHash:
case kIROp_Specialize:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
case kIROp_Param:
case kIROp_DetachDerivative:
return false;
@@ -2704,7 +2704,7 @@ static bool shouldStoreInst(IRInst* inst)
case kIROp_GetElement:
case kIROp_FieldExtract:
- case kIROp_swizzle:
+ case kIROp_Swizzle:
case kIROp_UpdateElement:
case kIROp_OptionalHasValue:
case kIROp_GetOptionalValue:
diff --git a/source/slang/slang-ir-autodiff-region.cpp b/source/slang/slang-ir-autodiff-region.cpp
index 787488341..58bbdc76e 100644
--- a/source/slang/slang-ir-autodiff-region.cpp
+++ b/source/slang/slang-ir-autodiff-region.cpp
@@ -22,7 +22,7 @@ RefPtr<IndexedRegionMap> buildIndexedRegionMap(IRGlobalValueWithCode* func)
switch (terminator->getOp())
{
- case kIROp_loop:
+ case kIROp_Loop:
{
auto loopRegion = regionMap->newRegion(as<IRLoop>(terminator), currentRegion);
auto condBlock = as<IRLoop>(terminator)->getTargetBlock();
diff --git a/source/slang/slang-ir-autodiff-rev.cpp b/source/slang/slang-ir-autodiff-rev.cpp
index 773a7741f..ca768cd66 100644
--- a/source/slang/slang-ir-autodiff-rev.cpp
+++ b/source/slang/slang-ir-autodiff-rev.cpp
@@ -259,7 +259,7 @@ InstPair BackwardDiffTranscriberBase::transcribeInstImpl(IRBuilder* builder, IRI
case kIROp_Return:
return transcribeReturn(builder, as<IRReturn>(origInst));
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
return transcribeLookupInterfaceMethod(builder, as<IRLookupWitnessMethod>(origInst));
case kIROp_Specialize:
diff --git a/source/slang/slang-ir-autodiff-transcriber-base.cpp b/source/slang/slang-ir-autodiff-transcriber-base.cpp
index d3d5d72a9..a4934dc28 100644
--- a/source/slang/slang-ir-autodiff-transcriber-base.cpp
+++ b/source/slang/slang-ir-autodiff-transcriber-base.cpp
@@ -70,7 +70,7 @@ bool AutoDiffTranscriberBase::shouldUseOriginalAsPrimal(IRInst* currentParent, I
{
if (as<IRGlobalValueWithCode>(origInst))
return true;
- if (origInst->parent && origInst->parent->getOp() == kIROp_Module)
+ if (origInst->parent && origInst->parent->getOp() == kIROp_ModuleInst)
return true;
if (isChildInstOf(currentParent, origInst->getParent()))
return true;
@@ -413,7 +413,7 @@ bool AutoDiffTranscriberBase::isExistentialType(IRType* type)
case kIROp_ExtractExistentialType:
case kIROp_InterfaceType:
case kIROp_AssociatedType:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
return true;
default:
return false;
diff --git a/source/slang/slang-ir-autodiff-transpose.h b/source/slang/slang-ir-autodiff-transpose.h
index 09f70725a..69cb2c8ce 100644
--- a/source/slang/slang-ir-autodiff-transpose.h
+++ b/source/slang/slang-ir-autodiff-transpose.h
@@ -187,7 +187,7 @@ struct DiffTransposePass
case kIROp_Return:
return RegionEntryPoint(revBlockMap[currentBlock], nullptr);
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
{
auto branchInst = as<IRUnconditionalBranch>(terminator);
auto nextBlock = as<IRBlock>(branchInst->getTargetBlock());
@@ -207,7 +207,7 @@ struct DiffTransposePass
break;
}
- case kIROp_ifElse:
+ case kIROp_IfElse:
{
auto ifElse = as<IRIfElse>(terminator);
@@ -273,7 +273,7 @@ struct DiffTransposePass
break;
}
- case kIROp_loop:
+ case kIROp_Loop:
{
auto loop = as<IRLoop>(terminator);
@@ -850,7 +850,7 @@ struct DiffTransposePass
TODO: need a better way to move specialize, lookupwitness,
extractExistentialType/Value/Witness insts to a proper location that dominates
all their use sites. Create copies of these insts when necessary. case
- kIROp_Specialize: case kIROp_LookupWitness: case kIROp_ExtractExistentialType:
+ kIROp_Specialize: case kIROp_LookupWitnessMethod: case kIROp_ExtractExistentialType:
case kIROp_ExtractExistentialValue:
case kIROp_ExtractExistentialWitnessTable:
*/
@@ -1248,7 +1248,7 @@ struct DiffTransposePass
baseFnType);
IRInst* revCallee = nullptr;
- if (getResolvedInstForDecorations(baseFn)->getOp() == kIROp_LookupWitness)
+ if (getResolvedInstForDecorations(baseFn)->getOp() == kIROp_LookupWitnessMethod)
{
// This is an interface method call, we can simply transcribe it here.
auto specialize = as<IRSpecialize>(baseFn);
@@ -1363,15 +1363,15 @@ struct DiffTransposePass
auto terminatorInst = block->getTerminator();
switch (terminatorInst->getOp())
{
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
case kIROp_Return:
return nullptr;
- case kIROp_ifElse:
+ case kIROp_IfElse:
return as<IRIfElse>(terminatorInst)->getAfterBlock();
case kIROp_Switch:
return as<IRSwitch>(terminatorInst)->getBreakLabel();
- case kIROp_loop:
+ case kIROp_Loop:
return as<IRLoop>(terminatorInst)->getBreakBlock();
default:
@@ -1467,7 +1467,7 @@ struct DiffTransposePass
case kIROp_Call:
return transposeCall(builder, as<IRCall>(fwdInst), revValue);
- case kIROp_swizzle:
+ case kIROp_Swizzle:
return transposeSwizzle(builder, as<IRSwizzle>(fwdInst), revValue);
case kIROp_FieldExtract:
@@ -1558,12 +1558,12 @@ struct DiffTransposePass
case kIROp_ReverseGradientDiffPairRef:
case kIROp_DefaultConstruct:
case kIROp_Specialize:
- case kIROp_unconditionalBranch:
- case kIROp_conditionalBranch:
- case kIROp_ifElse:
- case kIROp_loop:
+ case kIROp_UnconditionalBranch:
+ case kIROp_ConditionalBranch:
+ case kIROp_IfElse:
+ case kIROp_Loop:
case kIROp_Switch:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
case kIROp_ExtractExistentialType:
case kIROp_ExtractExistentialWitnessTable:
{
@@ -2163,7 +2163,7 @@ struct DiffTransposePass
switch (type->getOp())
{
case kIROp_ExtractExistentialType:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
return true;
default:
return false;
diff --git a/source/slang/slang-ir-autodiff-unzip.h b/source/slang/slang-ir-autodiff-unzip.h
index 80b2038aa..5685906b6 100644
--- a/source/slang/slang-ir-autodiff-unzip.h
+++ b/source/slang/slang-ir-autodiff-unzip.h
@@ -588,7 +588,7 @@ struct DiffUnzipPass
{
switch (branchInst->getOp())
{
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
{
auto uncondBranchInst = as<IRUnconditionalBranch>(branchInst);
auto targetBlock = uncondBranchInst->getTargetBlock();
@@ -615,7 +615,7 @@ struct DiffUnzipPass
diffArgs.getBuffer()));
}
- case kIROp_conditionalBranch:
+ case kIROp_ConditionalBranch:
{
auto trueBlock = as<IRConditionalBranch>(branchInst)->getTrueBlock();
auto falseBlock = as<IRConditionalBranch>(branchInst)->getFalseBlock();
@@ -632,7 +632,7 @@ struct DiffUnzipPass
as<IRBlock>(diffMap[falseBlock])));
}
- case kIROp_ifElse:
+ case kIROp_IfElse:
{
auto trueBlock = as<IRIfElse>(branchInst)->getTrueBlock();
auto falseBlock = as<IRIfElse>(branchInst)->getFalseBlock();
@@ -686,7 +686,7 @@ struct DiffUnzipPass
diffCaseArgs.getBuffer()));
}
- case kIROp_loop:
+ case kIROp_Loop:
return splitLoop(primalBuilder, diffBuilder, as<IRLoop>(branchInst));
default:
@@ -716,11 +716,11 @@ struct DiffUnzipPass
case kIROp_Return:
return splitReturn(primalBuilder, diffBuilder, as<IRReturn>(inst));
- case kIROp_unconditionalBranch:
- case kIROp_conditionalBranch:
- case kIROp_ifElse:
+ case kIROp_UnconditionalBranch:
+ case kIROp_ConditionalBranch:
+ case kIROp_IfElse:
case kIROp_Switch:
- case kIROp_loop:
+ case kIROp_Loop:
return splitControlFlow(primalBuilder, diffBuilder, inst);
case kIROp_Unreachable:
diff --git a/source/slang/slang-ir-autodiff.cpp b/source/slang/slang-ir-autodiff.cpp
index 133c257a8..5a8dc9074 100644
--- a/source/slang/slang-ir-autodiff.cpp
+++ b/source/slang/slang-ir-autodiff.cpp
@@ -824,7 +824,7 @@ IRInst* DifferentialPairTypeBuilder::_createDiffPairType(IRType* origBaseType, I
{
switch (origBaseType->getOp())
{
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
case kIROp_Specialize:
case kIROp_Param:
return nullptr;
@@ -2961,7 +2961,7 @@ struct AutoDiffPass : public InstPassBase
// For generics/struct types, we will generate a new generic/struct type
// representing the differntial.
- SLANG_RELEASE_ASSERT(t->getParent() && t->getParent()->getOp() == kIROp_Module);
+ SLANG_RELEASE_ASSERT(t->getParent() && t->getParent()->getOp() == kIROp_ModuleInst);
builder.setInsertBefore(t);
auto diffInfo = fillDifferentialTypeImplementation(&ctx, diffTypes, t);
diffTypes[t] = diffInfo;
@@ -3373,7 +3373,7 @@ struct AutoDiffPass : public InstPassBase
{
case kIROp_Func:
case kIROp_Specialize:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
case kIROp_Generic:
if (auto innerFunc =
as<IRFunc>(getResolvedInstForDecorations(inst->getOperand(0))))
@@ -3829,14 +3829,14 @@ UIndex addPhiOutputArg(
builder->setInsertInto(block);
switch (branchInst->getOp())
{
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
inoutTerminatorInst = builder->emitBranch(
branchInst->getTargetBlock(),
phiArgs.getCount(),
phiArgs.getBuffer());
break;
- case kIROp_loop:
+ case kIROp_Loop:
{
auto newLoop = builder->emitLoop(
as<IRLoop>(branchInst)->getTargetBlock(),
diff --git a/source/slang/slang-ir-check-differentiability.cpp b/source/slang/slang-ir-check-differentiability.cpp
index 7f3c7bf01..e9cb7e1f1 100644
--- a/source/slang/slang-ir-check-differentiability.cpp
+++ b/source/slang/slang-ir-check-differentiability.cpp
@@ -251,7 +251,7 @@ public:
bool isSynthesizeConstructor = false;
- if (auto constructor = funcInst->findDecoration<IRConstructorDecorartion>())
+ if (auto constructor = funcInst->findDecoration<IRConstructorDecoration>())
isSynthesizeConstructor = constructor->getSynthesizedStatus();
// This is a kernel function, we don't allow using TorchTensor type here.
diff --git a/source/slang/slang-ir-constexpr.cpp b/source/slang/slang-ir-constexpr.cpp
index 620c65d4e..0bdbe260a 100644
--- a/source/slang/slang-ir-constexpr.cpp
+++ b/source/slang/slang-ir-constexpr.cpp
@@ -129,7 +129,7 @@ bool opCanBeConstExpr(IROp op)
case kIROp_MakeUInt64:
case kIROp_MakeArray:
case kIROp_MakeArrayFromElement:
- case kIROp_swizzle:
+ case kIROp_Swizzle:
case kIROp_GetElement:
case kIROp_FieldExtract:
case kIROp_UpdateElement:
@@ -142,7 +142,7 @@ bool opCanBeConstExpr(IROp op)
case kIROp_GetOptionalValue:
case kIROp_DifferentialPairGetDifferential:
case kIROp_DifferentialPairGetPrimal:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
case kIROp_Specialize:
// TODO: more cases
return true;
diff --git a/source/slang/slang-ir-eliminate-multilevel-break.cpp b/source/slang/slang-ir-eliminate-multilevel-break.cpp
index 741b7fbd0..cbbd1c5c8 100644
--- a/source/slang/slang-ir-eliminate-multilevel-break.cpp
+++ b/source/slang/slang-ir-eliminate-multilevel-break.cpp
@@ -32,7 +32,7 @@ struct EliminateMultiLevelBreakContext
{
switch (headerInst->getOp())
{
- case kIROp_loop:
+ case kIROp_Loop:
return as<IRLoop>(headerInst)->getBreakBlock();
case kIROp_Switch:
return as<IRSwitch>(headerInst)->getBreakLabel();
@@ -45,7 +45,7 @@ struct EliminateMultiLevelBreakContext
{
switch (headerInst->getOp())
{
- case kIROp_loop:
+ case kIROp_Loop:
builder->replaceOperand(&(as<IRLoop>(headerInst)->breakBlock), block);
break;
case kIROp_Switch:
@@ -103,7 +103,7 @@ struct EliminateMultiLevelBreakContext
continue;
switch (block->getTerminator()->getOp())
{
- case kIROp_loop:
+ case kIROp_Loop:
case kIROp_Switch:
{
// Both region and switch insts mark the start a breakable region.
@@ -146,7 +146,7 @@ struct EliminateMultiLevelBreakContext
auto terminator = block->getTerminator();
switch (terminator->getOp())
{
- case kIROp_loop:
+ case kIROp_Loop:
case kIROp_Switch:
{
RefPtr<BreakableRegionInfo> regionInfo = new BreakableRegionInfo();
@@ -434,8 +434,8 @@ struct EliminateMultiLevelBreakContext
auto user = use->getUser();
switch (user->getOp())
{
- case kIROp_conditionalBranch:
- case kIROp_ifElse:
+ case kIROp_ConditionalBranch:
+ case kIROp_IfElse:
case kIROp_Switch:
// For complex branches, insert an intermediate block so we can specify the
// target index argument.
@@ -457,10 +457,10 @@ struct EliminateMultiLevelBreakContext
use->set(tmpBlock);
}
break;
- case kIROp_loop:
+ case kIROp_Loop:
// Ignore.
continue;
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
{
auto originalBranch = as<IRUnconditionalBranch>(user);
if (originalBranch->getOperandCount() == 1)
diff --git a/source/slang/slang-ir-eliminate-phis.cpp b/source/slang/slang-ir-eliminate-phis.cpp
index a16446319..d5f1b9e43 100644
--- a/source/slang/slang-ir-eliminate-phis.cpp
+++ b/source/slang/slang-ir-eliminate-phis.cpp
@@ -1038,7 +1038,7 @@ struct PhiEliminationContext
// so that any logic that might have moved another parameter
// into a temporary will influence our result.
//
- if ((*srcArg.currentValPtr)->getOp() != kIROp_undefined)
+ if ((*srcArg.currentValPtr)->getOp() != kIROp_Undefined)
{
// If we are trying to emit a store directly after a load from the same var,
// skip the store.
diff --git a/source/slang/slang-ir-float-non-uniform-resource-index.cpp b/source/slang/slang-ir-float-non-uniform-resource-index.cpp
index e37b0445b..dbcb093c2 100644
--- a/source/slang/slang-ir-float-non-uniform-resource-index.cpp
+++ b/source/slang/slang-ir-float-non-uniform-resource-index.cpp
@@ -91,7 +91,7 @@ void processNonUniformResourceIndex(
user->getOperand(1));
}
break;
- case kIROp_swizzle:
+ case kIROp_Swizzle:
// Ignore when `NonUniformResourceIndex` is not on base
if (user->getOperand(0) == inst)
{
@@ -103,7 +103,7 @@ void processNonUniformResourceIndex(
operands[0] = inst->getOperand(0);
newUser = builder.emitIntrinsicInst(
user->getFullType(),
- kIROp_swizzle,
+ kIROp_Swizzle,
operands.getCount(),
operands.getArrayView().getBuffer());
}
@@ -141,7 +141,7 @@ void processNonUniformResourceIndex(
case kIROp_NonUniformResourceIndex:
case kIROp_CastDescriptorHandleToUInt2:
case kIROp_GetElement:
- case kIROp_swizzle:
+ case kIROp_Swizzle:
resWorkList.add(nonuniformUser);
break;
};
diff --git a/source/slang/slang-ir-generics-lowering-context.cpp b/source/slang/slang-ir-generics-lowering-context.cpp
index 199eae2fc..0dee5631a 100644
--- a/source/slang/slang-ir-generics-lowering-context.cpp
+++ b/source/slang/slang-ir-generics-lowering-context.cpp
@@ -16,7 +16,7 @@ bool isPolymorphicType(IRInst* typeInst)
case kIROp_ThisType:
case kIROp_AssociatedType:
case kIROp_InterfaceType:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
return true;
case kIROp_Specialize:
{
@@ -299,7 +299,7 @@ IRType* SharedGenericsLoweringContext::lowerType(
return tupleType;
}
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
{
auto lookupInterface = static_cast<IRLookupWitnessMethod*>(paramType);
auto witnessTableType =
diff --git a/source/slang/slang-ir-inline.cpp b/source/slang/slang-ir-inline.cpp
index 8575330f8..9e522081f 100644
--- a/source/slang/slang-ir-inline.cpp
+++ b/source/slang/slang-ir-inline.cpp
@@ -1269,7 +1269,7 @@ struct IntrinsicFunctionInliningPass : InliningPassBase
hasSpvAsm = true;
continue;
case kIROp_Load:
- case kIROp_swizzle:
+ case kIROp_Swizzle:
case kIROp_Store:
continue;
default:
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
deleted file mode 100644
index d3db24d20..000000000
--- a/source/slang/slang-ir-inst-defs.h
+++ /dev/null
@@ -1,1439 +0,0 @@
-// slang-ir-inst-defs.h
-
-// clang-format off
-
-#ifndef INST
-#error Must #define `INST` before including `ir-inst-defs.h`
-#endif
-
-#ifndef INST_RANGE
-#define INST_RANGE(BASE, FIRST, LAST) /* empty */
-#endif
-
-#define PARENT kIROpFlag_Parent
-#define USE_OTHER kIROpFlag_UseOther
-#define HOISTABLE kIROpFlag_Hoistable
-#define GLOBAL kIROpFlag_Global
-
-INST(Nop, nop, 0, 0)
-
-/* Types */
-
- /* Basic Types */
-
- #define DEFINE_BASE_TYPE_INST(NAME) INST(NAME ## Type, NAME, 0, HOISTABLE)
- FOREACH_BASE_TYPE(DEFINE_BASE_TYPE_INST)
- #undef DEFINE_BASE_TYPE_INST
- INST(AfterBaseType, afterBaseType, 0, 0)
-
- INST_RANGE(BasicType, VoidType, AfterBaseType)
-
- /* StringTypeBase */
- INST(StringType, String, 0, HOISTABLE)
- INST(NativeStringType, NativeString, 0, HOISTABLE)
- INST_RANGE(StringTypeBase, StringType, NativeStringType)
-
- INST(CapabilitySetType, CapabilitySet, 0, HOISTABLE)
-
- INST(DynamicType, DynamicType, 0, HOISTABLE)
-
- INST(AnyValueType, AnyValueType, 1, HOISTABLE)
-
- INST(RawPointerType, RawPointerType, 0, HOISTABLE)
- INST(RTTIPointerType, RTTIPointerType, 1, HOISTABLE)
- INST(AfterRawPointerTypeBase, AfterRawPointerTypeBase, 0, 0)
- INST_RANGE(RawPointerTypeBase, RawPointerType, AfterRawPointerTypeBase)
-
-
- /* ArrayTypeBase */
- INST(ArrayType, Array, 2, HOISTABLE)
- INST(UnsizedArrayType, UnsizedArray, 1, HOISTABLE)
- INST_RANGE(ArrayTypeBase, ArrayType, UnsizedArrayType)
-
- INST(FuncType, Func, 0, HOISTABLE)
- INST(BasicBlockType, BasicBlock, 0, HOISTABLE)
-
- INST(VectorType, Vec, 2, HOISTABLE)
- INST(MatrixType, Mat, 4, HOISTABLE)
-
- INST(ConjunctionType, Conjunction, 0, HOISTABLE)
- INST(AttributedType, Attributed, 0, HOISTABLE)
- INST(ResultType, Result, 2, HOISTABLE)
- INST(OptionalType, Optional, 1, HOISTABLE)
- INST(EnumType, Enum, 1, PARENT)
-
- INST(DifferentialPairType, DiffPair, 1, HOISTABLE)
- INST(DifferentialPairUserCodeType, DiffPairUserCode, 1, HOISTABLE)
- INST(DifferentialPtrPairType, DiffRefPair, 1, HOISTABLE)
- INST_RANGE(DifferentialPairTypeBase, DifferentialPairType, DifferentialPtrPairType)
-
- INST(BackwardDiffIntermediateContextType, BwdDiffIntermediateCtxType, 1, HOISTABLE)
-
- INST(TensorViewType, TensorView, 1, HOISTABLE)
- INST(TorchTensorType, TorchTensor, 0, HOISTABLE)
- INST(ArrayListType, ArrayListVector, 1, HOISTABLE)
-
- INST(AtomicType, Atomic, 1, HOISTABLE)
-
- /* BindExistentialsTypeBase */
-
- // A `BindExistentials<B, T0,w0, T1,w1, ...>` represents
- // taking type `B` and binding each of its existential type
- // parameters, recursively, with the specified arguments,
- // where each `Ti, wi` pair represents the concrete type
- // and witness table to plug in for parameter `i`.
- //
- INST(BindExistentialsType, BindExistentials, 1, HOISTABLE)
-
- // An `BindInterface<B, T0, w0>` represents the special case
- // of a `BindExistentials` where the type `B` is known to be
- // an interface type.
- //
- INST(BoundInterfaceType, BoundInterface, 3, HOISTABLE)
-
- INST_RANGE(BindExistentialsTypeBase, BindExistentialsType, BoundInterfaceType)
-
- /* Rate */
- INST(ConstExprRate, ConstExpr, 0, HOISTABLE)
- INST(SpecConstRate, SpecConst, 0, HOISTABLE)
- INST(GroupSharedRate, GroupShared, 0, HOISTABLE)
- INST(ActualGlobalRate, ActualGlobalRate, 0, HOISTABLE)
- INST_RANGE(Rate, ConstExprRate, GroupSharedRate)
-
- INST(RateQualifiedType, RateQualified, 2, HOISTABLE)
-
- // Kinds represent the "types of types."
- // They should not really be nested under `IRType`
- // in the overall hierarchy, but we can fix that later.
- //
- /* Kind */
- INST(TypeKind, Type, 0, HOISTABLE)
- INST(TypeParameterPackKind, TypeParameterPack, 0, HOISTABLE)
- INST(RateKind, Rate, 0, HOISTABLE)
- INST(GenericKind, Generic, 0, HOISTABLE)
- INST_RANGE(Kind, TypeKind, GenericKind)
-
- /* PtrTypeBase */
- INST(PtrType, Ptr, 1, HOISTABLE)
- INST(RefType, Ref, 1, HOISTABLE)
- INST(ConstRefType, ConstRef, 1, HOISTABLE)
- // A `PsuedoPtr<T>` logically represents a pointer to a value of type
- // `T` on a platform that cannot support pointers. The expectation
- // is that the "pointer" will be legalized away by storing a value
- // of type `T` somewhere out-of-line.
-
- INST(PseudoPtrType, PseudoPtr, 1, HOISTABLE)
-
- /* OutTypeBase */
- INST(OutType, Out, 1, HOISTABLE)
- INST(InOutType, InOut, 1, HOISTABLE)
- INST_RANGE(OutTypeBase, OutType, InOutType)
- INST_RANGE(PtrTypeBase, PtrType, InOutType)
-
-
- // A ComPtr<T> type is treated as a opaque type that represents a reference-counted handle to a COM object.
- INST(ComPtrType, ComPtr, 1, HOISTABLE)
- // A NativePtr<T> type represents a native pointer to a managed resource.
- INST(NativePtrType, NativePtr, 1, HOISTABLE)
-
- // A DescriptorHandle<T> type represents a bindless handle to an opaue resource type.
- INST(DescriptorHandleType, DescriptorHandle, 1, HOISTABLE)
-
- // An AtomicUint is a placeholder type for a storage buffer, and will be mangled during compiling.
- INST(GLSLAtomicUintType, GLSLAtomicUint, 0, HOISTABLE)
-
- /* SamplerStateTypeBase */
- INST(SamplerStateType, SamplerState, 0, HOISTABLE)
- INST(SamplerComparisonStateType, SamplerComparisonState, 0, HOISTABLE)
- INST_RANGE(SamplerStateTypeBase, SamplerStateType, SamplerComparisonStateType)
-
- INST(DefaultBufferLayoutType, DefaultLayout, 0, HOISTABLE)
- INST(Std140BufferLayoutType, Std140Layout, 0, HOISTABLE)
- INST(Std430BufferLayoutType, Std430Layout, 0, HOISTABLE)
- INST(ScalarBufferLayoutType, ScalarLayout, 0, HOISTABLE)
-
- INST(SubpassInputType, SubpassInputType, 2, HOISTABLE)
-
- INST(TextureFootprintType, TextureFootprintType, 1, HOISTABLE)
-
- INST(TextureShape1DType, TextureShape1DType, 0, HOISTABLE)
- INST(TextureShape2DType, TextureShape1DType, 0, HOISTABLE)
- INST(TextureShape3DType, TextureShape1DType, 0, HOISTABLE)
- INST(TextureShapeCubeType, TextureShape1DType, 0, HOISTABLE)
- INST(TextureShapeBufferType, TextureShapeBufferType, 0, HOISTABLE)
-
- // TODO: Why do we have all this hierarchy here, when everything
- // that actually matters is currently nested under `TextureTypeBase`?
- /* ResourceTypeBase */
- /* ResourceType */
- /* TextureTypeBase */
- /* TextureType */
- INST(TextureType, TextureType, 8, HOISTABLE)
- /* GLSLImageType */
- INST(GLSLImageType, GLSLImageType, 0, USE_OTHER | HOISTABLE)
- INST_RANGE(TextureTypeBase, TextureType, GLSLImageType)
- INST_RANGE(ResourceType, TextureType, GLSLImageType)
- INST_RANGE(ResourceTypeBase, TextureType, GLSLImageType)
-
- /* UntypedBufferResourceType */
- /* ByteAddressBufferTypeBase */
- INST(HLSLByteAddressBufferType, ByteAddressBuffer, 0, HOISTABLE)
- INST(HLSLRWByteAddressBufferType, RWByteAddressBuffer, 0, HOISTABLE)
- INST(HLSLRasterizerOrderedByteAddressBufferType, RasterizerOrderedByteAddressBuffer, 0, HOISTABLE)
- INST_RANGE(ByteAddressBufferTypeBase, HLSLByteAddressBufferType, HLSLRasterizerOrderedByteAddressBufferType)
- INST(RaytracingAccelerationStructureType, RaytracingAccelerationStructure, 0, HOISTABLE)
- INST_RANGE(UntypedBufferResourceType, HLSLByteAddressBufferType, RaytracingAccelerationStructureType)
-
- /* HLSLPatchType */
- INST(HLSLInputPatchType, InputPatch, 2, HOISTABLE)
- INST(HLSLOutputPatchType, OutputPatch, 2, HOISTABLE)
- INST_RANGE(HLSLPatchType, HLSLInputPatchType, HLSLOutputPatchType)
-
- INST(GLSLInputAttachmentType, GLSLInputAttachment, 0, HOISTABLE)
-
- /* BuiltinGenericType */
- /* HLSLStreamOutputType */
- INST(HLSLPointStreamType, PointStream, 1, HOISTABLE)
- INST(HLSLLineStreamType, LineStream, 1, HOISTABLE)
- INST(HLSLTriangleStreamType, TriangleStream, 1, HOISTABLE)
- INST_RANGE(HLSLStreamOutputType, HLSLPointStreamType, HLSLTriangleStreamType)
-
- /* MeshOutputType */
- INST(VerticesType, Vertices, 2, HOISTABLE)
- INST(IndicesType, Indices, 2, HOISTABLE)
- INST(PrimitivesType, Primitives, 2, HOISTABLE)
- INST_RANGE(MeshOutputType, VerticesType, PrimitivesType)
-
- /* Metal Mesh Type */
- INST(MetalMeshType, metal::mesh, 5, HOISTABLE)
- /* Metal Mesh Grid Properties */
- INST(MetalMeshGridPropertiesType, mesh_grid_properties, 0, HOISTABLE)
-
- /* HLSLStructuredBufferTypeBase */
- INST(HLSLStructuredBufferType, StructuredBuffer, 0, HOISTABLE)
- INST(HLSLRWStructuredBufferType, RWStructuredBuffer, 0, HOISTABLE)
- INST(HLSLRasterizerOrderedStructuredBufferType, RasterizerOrderedStructuredBuffer, 0, HOISTABLE)
- INST(HLSLAppendStructuredBufferType, AppendStructuredBuffer, 0, HOISTABLE)
- INST(HLSLConsumeStructuredBufferType, ConsumeStructuredBuffer, 0, HOISTABLE)
- INST_RANGE(HLSLStructuredBufferTypeBase, HLSLStructuredBufferType, HLSLConsumeStructuredBufferType)
-
- /* PointerLikeType */
- /* ParameterGroupType */
- /* UniformParameterGroupType */
- INST(ConstantBufferType, ConstantBuffer, 1, HOISTABLE)
- INST(TextureBufferType, TextureBuffer, 1, HOISTABLE)
- INST(ParameterBlockType, ParameterBlock, 1, HOISTABLE)
- INST_RANGE(UniformParameterGroupType, ConstantBufferType, ParameterBlockType)
-
- /* VaryingParameterGroupType */
- INST(GLSLInputParameterGroupType, GLSLInputParameterGroup, 0, HOISTABLE)
- INST(GLSLOutputParameterGroupType, GLSLOutputParameterGroup, 0, HOISTABLE)
- INST_RANGE(VaryingParameterGroupType, GLSLInputParameterGroupType, GLSLOutputParameterGroupType)
- INST(GLSLShaderStorageBufferType, GLSLShaderStorageBuffer, 1, HOISTABLE)
- INST_RANGE(ParameterGroupType, ConstantBufferType, GLSLShaderStorageBufferType)
- INST_RANGE(PointerLikeType, ConstantBufferType, GLSLShaderStorageBufferType)
- INST_RANGE(BuiltinGenericType, HLSLPointStreamType, GLSLShaderStorageBufferType)
-
-INST(RayQueryType, RayQuery, 1, HOISTABLE)
-INST(HitObjectType, HitObject, 0, HOISTABLE)
-INST(CoopVectorType, CoopVectorType, 2, HOISTABLE)
-INST(CoopMatrixType, CoopMatrixType, 5, HOISTABLE)
-INST(TensorAddressingTensorLayoutType, TensorAddressingTensorLayoutType, 2, HOISTABLE)
-INST(TensorAddressingTensorViewType, TensorAddressingTensorViewType, 3, HOISTABLE)
-INST(MakeTensorAddressingTensorLayout, MakeTensorAddressingTensorLayout, 0, 0)
-INST(MakeTensorAddressingTensorView, MakeTensorAddressingTensorView, 0, 0)
-
-// Opaque type that can be dynamically cast to other resource types.
-INST(DynamicResourceType, DynamicResource, 0, HOISTABLE)
-
-// A user-defined structure declaration at the IR level.
-// Unlike in the AST where there is a distinction between
-// a `StructDecl` and a `DeclRefType` that refers to it,
-// at the IR level the struct declaration and the type
-// are the same IR instruction.
-//
-// This is a parent instruction that holds zero or more
-// `field` instructions.
-//
-INST(StructType, struct, 0, PARENT)
-INST(ClassType, class, 0, PARENT)
-INST(InterfaceType, interface, 0, GLOBAL)
-INST(AssociatedType, associated_type, 0, HOISTABLE)
-INST(ThisType, this_type, 0, HOISTABLE)
-INST(RTTIType, rtti_type, 0, HOISTABLE)
-INST(RTTIHandleType, rtti_handle_type, 0, HOISTABLE)
-/*TupleTypeBase*/
- INST(TupleType, tuple_type, 0, HOISTABLE)
- INST(TypePack, TypePack, 0, HOISTABLE)
-INST_RANGE(TupleTypeBase, TupleType, TypePack)
-INST(TargetTupleType, TargetTuple, 0, HOISTABLE)
-INST(ExpandTypeOrVal, ExpandTypeOrVal, 1, HOISTABLE)
-
-// A type that identifies it's contained type as being emittable as `spirv_literal.
-INST(SPIRVLiteralType, spirvLiteralType, 1, HOISTABLE)
-
-// A TypeType-typed IRValue represents a IRType.
-// It is used to represent a type parameter/argument in a generics.
-INST(TypeType, type_t, 0, HOISTABLE)
-
-/*IRWitnessTableTypeBase*/
- // An `IRWitnessTable` has type `WitnessTableType`.
- INST(WitnessTableType, witness_table_t, 1, HOISTABLE)
- // An integer type representing a witness table for targets where
- // witness tables are represented as integer IDs. This type is used
- // during the lower-generics pass while generating dynamic dispatch
- // code and will eventually lower into an uint type.
- INST(WitnessTableIDType, witness_table_id_t, 1, HOISTABLE)
-INST_RANGE(WitnessTableTypeBase, WitnessTableType, WitnessTableIDType)
-INST_RANGE(Type, VoidType, WitnessTableIDType)
-
-/*IRGlobalValueWithCode*/
- /* IRGlobalValueWithParams*/
- INST(Func, func, 0, PARENT)
- INST(Generic, generic, 0, PARENT)
- INST_RANGE(GlobalValueWithParams, Func, Generic)
-
- INST(GlobalVar, global_var, 0, GLOBAL)
-INST_RANGE(GlobalValueWithCode, Func, GlobalVar)
-
-INST(GlobalParam, global_param, 0, GLOBAL)
-INST(GlobalConstant, globalConstant, 0, GLOBAL)
-
-INST(StructKey, key, 0, GLOBAL)
-INST(GlobalGenericParam, global_generic_param, 0, GLOBAL)
-INST(WitnessTable, witness_table, 0, HOISTABLE)
-
-INST(IndexedFieldKey, indexedFieldKey, 2, HOISTABLE)
-
-// A placeholder witness that ThisType implements the enclosing interface.
-// Used only in interface definitions.
-INST(ThisTypeWitness, thisTypeWitness, 1, 0)
-
-// A placeholder witness for the fact that two types are equal.
-INST(TypeEqualityWitness, TypeEqualityWitness, 2, HOISTABLE)
-
-INST(GlobalHashedStringLiterals, global_hashed_string_literals, 0, 0)
-
-INST(Module, module, 0, PARENT)
-
-INST(Block, block, 0, PARENT)
-
-/* IRConstant */
- INST(BoolLit, boolConst, 0, 0)
- INST(IntLit, integer_constant, 0, 0)
- INST(FloatLit, float_constant, 0, 0)
- INST(PtrLit, ptr_constant, 0, 0)
- INST(StringLit, string_constant, 0, 0)
- INST(BlobLit, string_constant, 0, 0)
- INST(VoidLit, void_constant, 0, 0)
-INST_RANGE(Constant, BoolLit, VoidLit)
-
-INST(CapabilityConjunction, capabilityConjunction, 0, HOISTABLE)
-INST(CapabilityDisjunction, capabilityDisjunction, 0, HOISTABLE)
-INST_RANGE(CapabilitySet, CapabilityConjunction, CapabilityDisjunction)
-
-INST(undefined, undefined, 0, 0)
-
-// A `defaultConstruct` operation creates an initialized
-// value of the result type, and can only be used for types
-// where default construction is a meaningful thing to do.
-//
-INST(DefaultConstruct, defaultConstruct, 0, 0)
-
-INST(MakeDifferentialPair, MakeDiffPair, 2, 0)
-INST(MakeDifferentialPairUserCode, MakeDiffPairUserCode, 2, 0)
-INST(MakeDifferentialPtrPair, MakeDiffRefPair, 2, 0)
-INST_RANGE(MakeDifferentialPairBase, MakeDifferentialPair, MakeDifferentialPtrPair)
-
-INST(DifferentialPairGetDifferential, GetDifferential, 1, 0)
-INST(DifferentialPairGetDifferentialUserCode, GetDifferentialUserCode, 1, 0)
-INST(DifferentialPtrPairGetDifferential, GetDifferentialPtr, 1, 0)
-INST_RANGE(DifferentialPairGetDifferentialBase, DifferentialPairGetDifferential, DifferentialPtrPairGetDifferential)
-
-INST(DifferentialPairGetPrimal, GetPrimal, 1, 0)
-INST(DifferentialPairGetPrimalUserCode, GetPrimalUserCode, 1, 0)
-INST(DifferentialPtrPairGetPrimal, GetPrimalRef, 1, 0)
-INST_RANGE(DifferentialPairGetPrimalBase, DifferentialPairGetPrimal, DifferentialPtrPairGetPrimal)
-
-INST(Specialize, specialize, 2, HOISTABLE)
-INST(LookupWitness, lookupWitness, 2, HOISTABLE)
-INST(GetSequentialID, GetSequentialID, 1, HOISTABLE)
-INST(BindGlobalGenericParam, bind_global_generic_param, 2, 0)
-INST(AllocObj, allocObj, 0, 0)
-
-INST(GlobalValueRef, globalValueRef, 1, 0)
-
-INST(MakeUInt64, makeUInt64, 2, 0)
-INST(MakeVector, makeVector, 0, 0)
-INST(MakeMatrix, makeMatrix, 0, 0)
-INST(MakeMatrixFromScalar, makeMatrixFromScalar, 1, 0)
-INST(MatrixReshape, matrixReshape, 1, 0)
-INST(VectorReshape, vectorReshape, 1, 0)
-INST(MakeArray, makeArray, 0, 0)
-INST(MakeArrayFromElement, makeArrayFromElement, 1, 0)
-INST(MakeCoopVector, makeCoopVector, 0, 0)
-INST(MakeCoopVectorFromValuePack, makeCoopVectorFromValuePack, 1, 0)
-INST(MakeStruct, makeStruct, 0, 0)
-INST(MakeTuple, makeTuple, 0, 0)
-INST(MakeTargetTuple, makeTuple, 0, 0)
-INST(MakeValuePack, makeValuePack, 0, 0)
-INST(GetTargetTupleElement, getTargetTupleElement, 0, 0)
-INST(GetTupleElement, getTupleElement, 2, 0)
-INST(LoadResourceDescriptorFromHeap, LoadResourceDescriptorFromHeap, 1, 0)
-INST(LoadSamplerDescriptorFromHeap, LoadSamplerDescriptorFromHeap, 1, 0)
-INST(MakeCombinedTextureSamplerFromHandle, MakeCombinedTextureSamplerFromHandle, 1, 0)
-INST(MakeWitnessPack, MakeWitnessPack, 0, HOISTABLE)
-INST(Expand, Expand, 1, 0)
-INST(Each, Each, 1, HOISTABLE)
-INST(MakeResultValue, makeResultValue, 1, 0)
-INST(MakeResultError, makeResultError, 1, 0)
-INST(IsResultError, isResultError, 1, 0)
-INST(GetResultError, getResultError, 1, 0)
-INST(GetResultValue, getResultValue, 1, 0)
-INST(GetOptionalValue, getOptionalValue, 1, 0)
-INST(OptionalHasValue, optionalHasValue, 1, 0)
-INST(MakeOptionalValue, makeOptionalValue, 1, 0)
-INST(MakeOptionalNone, makeOptionalNone, 1, 0)
-INST(CombinedTextureSamplerGetTexture, CombinedTextureSamplerGetTexture, 1, 0)
-INST(CombinedTextureSamplerGetSampler, CombinedTextureSamplerGetSampler, 1, 0)
-INST(Call, call, 1, 0)
-
-INST(RTTIObject, rtti_object, 0, 0)
-INST(Alloca, alloca, 1, 0)
-
-INST(UpdateElement, updateElement, 2, 0)
-INST(DetachDerivative, detachDerivative, 1, 0)
-
-INST(BitfieldExtract, bitfieldExtract, 3, 0)
-INST(BitfieldInsert, bitfieldInsert, 4, 0)
-
-INST(PackAnyValue, packAnyValue, 1, 0)
-INST(UnpackAnyValue, unpackAnyValue, 1, 0)
-
-INST(WitnessTableEntry, witness_table_entry, 2, 0)
-INST(InterfaceRequirementEntry, interface_req_entry, 2, GLOBAL)
-
-// An inst to represent the workgroup size of the calling entry point.
-// We will materialize this inst during `translateGlobalVaryingVar`.
-INST(GetWorkGroupSize, GetWorkGroupSize, 0, HOISTABLE)
-
-// An inst that returns the current stage of the calling entry point.
-INST(GetCurrentStage, GetCurrentStage, 0, 0)
-
-INST(Param, param, 0, 0)
-INST(StructField, field, 2, 0)
-INST(Var, var, 0, 0)
-
-INST(Load, load, 1, 0)
-INST(Store, store, 2, 0)
-
-// Atomic Operations
- INST(AtomicLoad, atomicLoad, 1, 0)
- INST(AtomicStore, atomicStore, 2, 0)
- INST(AtomicExchange, atomicExchange, 2, 0)
- INST(AtomicCompareExchange, atomicCompareExchange, 3, 0)
- INST(AtomicAdd, atomicAdd, 2, 0)
- INST(AtomicSub, atomicSub, 2, 0)
- INST(AtomicAnd, atomicAnd, 2, 0)
- INST(AtomicOr, atomicOr, 2, 0)
- INST(AtomicXor, atomicXor, 2, 0)
- INST(AtomicMin, atomicMin, 2, 0)
- INST(AtomicMax, atomicMax, 2, 0)
- INST(AtomicInc, atomicInc, 1, 0)
- INST(AtomicDec, atomicDec, 1, 0)
-INST_RANGE(AtomicOperation, AtomicLoad, AtomicDec)
-
-// Produced and removed during backward auto-diff pass as a temporary placeholder representing the
-// currently accumulated derivative to pass to some dOut argument in a nested call.
-INST(LoadReverseGradient, LoadReverseGradient, 1, 0)
-
-// Produced and removed during backward auto-diff pass as a temporary placeholder containing the
-// primal and accumulated derivative values to pass to an inout argument in a nested call.
-INST(ReverseGradientDiffPairRef, ReverseGradientDiffPairRef, 2, 0)
-
-// Produced and removed during backward auto-diff pass. This inst is generated by the splitting step
-// to represent a reference to an inout parameter for use in the primal part of the computation.
-INST(PrimalParamRef, PrimalParamRef, 1, 0)
-
-// Produced and removed during backward auto-diff pass. This inst is generated by the splitting step
-// to represent a reference to an inout parameter for use in the back-prop part of the computation.
-INST(DiffParamRef, DiffParamRef, 1, 0)
-
-// Check that the value is a differential null value.
-INST(IsDifferentialNull, IsDifferentialNull, 1, 0)
-
-INST(FieldExtract, get_field, 2, 0)
-INST(FieldAddress, get_field_addr, 2, 0)
-
-INST(GetElement, getElement, 2, 0)
-INST(GetElementPtr, getElementPtr, 2, 0)
-// Pointer offset: computes pBase + offset_in_elements
-INST(GetOffsetPtr, getOffsetPtr, 2, 0)
-INST(GetAddr, getAddr, 1, 0)
-
-INST(CastDynamicResource, castDynamicResource, 1, 0)
-
-// Get an unowned NativeString from a String.
-INST(getNativeStr, getNativeStr, 1, 0)
-
-// Make String from a NativeString.
-INST(MakeString, makeString, 1, 0)
-
-// Get a native ptr from a ComPtr or RefPtr
-INST(GetNativePtr, getNativePtr, 1, 0)
-
-// Get a write reference to a managed ptr var (operand must be Ptr<ComPtr<T>> or Ptr<RefPtr<T>>).
-INST(GetManagedPtrWriteRef, getManagedPtrWriteRef, 1, 0)
-
-// Attach a managedPtr var to a NativePtr without changing its ref count.
-INST(ManagedPtrAttach, ManagedPtrAttach, 1, 0)
-
-// Attach a managedPtr var to a NativePtr without changing its ref count.
-INST(ManagedPtrDetach, ManagedPtrDetach, 1, 0)
-
-// "Subscript" an image at a pixel coordinate to get pointer
-INST(ImageSubscript, imageSubscript, 2, 0)
-
-// Load from an Image.
-INST(ImageLoad, imageLoad, 2, 0)
-// Store into an Image.
-INST(ImageStore, imageStore, 3, 0)
-
-// Load (almost) arbitrary-type data from a byte-address buffer
-//
-// %dst = byteAddressBufferLoad(%buffer, %offset, %alignment)
-//
-// where
-// - `buffer` is a value of some `ByteAddressBufferTypeBase` type
-// - `offset` is an `int`
-// - `alignment` is an `int`
-// - `dst` is a value of some type containing only ordinary data
-//
-INST(ByteAddressBufferLoad, byteAddressBufferLoad, 3, 0)
-
-// Store (almost) arbitrary-type data to a byte-address buffer
-//
-// byteAddressBufferLoad(%buffer, %offset, %alignment, %src)
-//
-// where
-// - `buffer` is a value of some `ByteAddressBufferTypeBase` type
-// - `offset` is an `int`
-// - `alignment` is an `int`
-// - `src` is a value of some type containing only ordinary data
-//
-INST(ByteAddressBufferStore, byteAddressBufferStore, 4, 0)
-
-// Load data from a structured buffer
-//
-// %dst = structuredBufferLoad(%buffer, %index)
-//
-// where
-// - `buffer` is a value of some `StructuredBufferTypeBase` type with element type T
-// - `offset` is an `int`
-// - `dst` is a value of type T
-//
-INST(StructuredBufferLoad, structuredBufferLoad, 2, 0)
-INST(StructuredBufferLoadStatus, structuredBufferLoadStatus, 3, 0)
-INST(RWStructuredBufferLoad, rwstructuredBufferLoad, 2, 0)
-INST(RWStructuredBufferLoadStatus, rwstructuredBufferLoadStatus, 3, 0)
-
-// Store data to a structured buffer
-//
-// structuredBufferLoad(%buffer, %offset, %src)
-//
-// where
-// - `buffer` is a value of some `StructuredBufferTypeBase` type with element type T
-// - `offset` is an `int`
-// - `src` is a value of type T
-//
-INST(RWStructuredBufferStore, rwstructuredBufferStore, 3, 0)
-
-INST(RWStructuredBufferGetElementPtr, rwstructuredBufferGetElementPtr, 2, 0)
-
-// Append/Consume-StructuredBuffer operations
-INST(StructuredBufferAppend, StructuredBufferAppend, 1, 0)
-INST(StructuredBufferConsume, StructuredBufferConsume, 1, 0)
-INST(StructuredBufferGetDimensions, StructuredBufferGetDimensions, 1, 0)
-
-// Resource qualifiers for dynamically varying index
-INST(NonUniformResourceIndex, nonUniformResourceIndex, 1, 0)
-
-INST(GetNaturalStride, getNaturalStride, 1, 0)
-
-INST(MeshOutputRef, meshOutputRef, 2, 0)
-INST(MeshOutputSet, meshOutputSet, 3, 0)
-
-// only two parameters as they are effectively static
-// TODO: make them reference the _slang_mesh object directly
-INST(MetalSetVertex, metalSetVertex, 2, 0)
-INST(MetalSetPrimitive, metalSetPrimitive, 2, 0)
-INST(MetalSetIndices, metalSetIndices, 2, 0)
-
-INST(MetalCastToDepthTexture, MetalCastToDepthTexture, 1, 0)
-
-// Construct a vector from a scalar
-//
-// %dst = MakeVectorFromScalar %T %N %val
-//
-// where
-// - `T` is a `Type`
-// - `N` is a (compile-time) `Int`
-// - `val` is a `T`
-// - dst is a `Vec<T,N>`
-//
-INST(MakeVectorFromScalar, MakeVectorFromScalar, 3, 0)
-
-// A swizzle of a vector:
-//
-// %dst = swizzle %src %idx0 %idx1 ...
-//
-// where:
-// - `src` is a vector<T,N>
-// - `dst` is a vector<T,M>
-// - `idx0` through `idx[M-1]` are literal integers
-//
-INST(swizzle, swizzle, 1, 0)
-
-// Setting a vector via swizzle
-//
-// %dst = swizzle %base %src %idx0 %idx1 ...
-//
-// where:
-// - `base` is a vector<T,N>
-// - `dst` is a vector<T,N>
-// - `src` is a vector<T,M>
-// - `idx0` through `idx[M-1]` are literal integers
-//
-// The semantics of the op is:
-//
-// dst = base;
-// for(ii : 0 ... M-1 )
-// dst[ii] = src[idx[ii]];
-//
-INST(swizzleSet, swizzleSet, 2, 0)
-
-// Store to memory with a swizzle
-//
-// TODO: eventually this should be reduced to just
-// a write mask by moving the actual swizzle to the RHS.
-//
-// swizzleStore %dst %src %idx0 %idx1 ...
-//
-// where:
-// - `dst` is a vector<T,N>
-// - `src` is a vector<T,M>
-// - `idx0` through `idx[M-1]` are literal integers
-//
-// The semantics of the op is:
-//
-// for(ii : 0 ... M-1 )
-// dst[ii] = src[idx[ii]];
-//
-INST(SwizzledStore, swizzledStore, 2, 0)
-
-
-/* IRTerminatorInst */
-
- INST(Return, return_val, 1, 0)
- INST(Yield, yield, 1, 0)
- /* IRUnconditionalBranch */
- // unconditionalBranch <target>
- INST(unconditionalBranch, unconditionalBranch, 1, 0)
-
- // loop <target> <breakLabel> <continueLabel>
- INST(loop, loop, 3, 0)
- INST_RANGE(UnconditionalBranch, unconditionalBranch, loop)
-
- /* IRConditionalbranch */
-
- // conditionalBranch <condition> <trueBlock> <falseBlock>
-INST(conditionalBranch, conditionalBranch, 3, 0)
-
-// ifElse <condition> <trueBlock> <falseBlock> <mergeBlock>
-INST(ifElse, ifElse, 4, 0)
-INST_RANGE(ConditionalBranch, conditionalBranch, ifElse)
-
-INST(Throw, throw, 1, 0)
-// tryCall <successBlock> <failBlock> <callee> <args>...
-INST(TryCall, tryCall, 3, 0)
-// switch <val> <break> <default> <caseVal1> <caseBlock1> ...
-INST(Switch, switch, 3, 0)
-// target_switch <break> <targetName1> <block1> ...
-INST(TargetSwitch, targetSwitch, 1, 0)
-
-// A generic asm inst has an return semantics that terminates the control flow.
-INST(GenericAsm, GenericAsm, 1, 0)
-
-/* IRUnreachable */
-INST(MissingReturn, missingReturn, 0, 0)
-INST(Unreachable, unreachable, 0, 0)
-INST_RANGE(Unreachable, MissingReturn, Unreachable)
-
-INST(Defer, defer, 3, 0)
-
-INST_RANGE(TerminatorInst, Return, Defer)
-
-INST(discard, discard, 0, 0)
-
-INST(RequirePrelude, RequirePrelude, 1, 0)
-INST(RequireTargetExtension, RequireTargetExtension, 1, 0)
-INST(RequireComputeDerivative, RequireComputeDerivative, 0, 0)
-INST(StaticAssert, StaticAssert, 2, 0)
-INST(Printf, Printf, 1, 0)
-
-// Quad control execution modes.
-INST(RequireMaximallyReconverges, RequireMaximallyReconverges, 0, 0)
-INST(RequireQuadDerivatives, RequireQuadDerivatives, 0, 0)
-
-// TODO: We should consider splitting the basic arithmetic/comparison
-// ops into cases for signed integers, unsigned integers, and floating-point
-// values, to better match downstream targets that want to treat them
-// all differently (e.g., SPIR-V).
-
-INST(Add, add, 2, 0)
-INST(Sub, sub, 2, 0)
-INST(Mul, mul, 2, 0)
-INST(Div, div, 2, 0)
-
-// Remainder of division.
-//
-// Note: this is distinct from modulus, and we should have a separate
-// opcode for `mod` if we ever need to support it.
-//
-INST(IRem, irem, 2, 0) // integer (signed or unsigned)
-INST(FRem, frem, 2, 0) // floating-point
-
-INST(Lsh, shl, 2, 0)
-INST(Rsh, shr, 2, 0)
-
-INST(Eql, cmpEQ, 2, 0)
-INST(Neq, cmpNE, 2, 0)
-INST(Greater, cmpGT, 2, 0)
-INST(Less, cmpLT, 2, 0)
-INST(Geq, cmpGE, 2, 0)
-INST(Leq, cmpLE, 2, 0)
-
-INST(BitAnd, and, 2, 0)
-INST(BitXor, xor, 2, 0)
-INST(BitOr, or , 2, 0)
-
-INST(And, logicalAnd, 2, 0)
-INST(Or, logicalOr, 2, 0)
-
-INST(Neg, neg, 1, 0)
-INST(Not, not, 1, 0)
-INST(BitNot, bitnot, 1, 0)
-
-INST(Select, select, 3, 0)
-
-INST(CheckpointObject, checkpointObj, 1, 0)
-INST(LoopExitValue, loopExitValue, 1, 0)
-
-INST(GetStringHash, getStringHash, 1, 0)
-
-INST(WaveGetActiveMask, waveGetActiveMask, 0, 0)
-
-/// trueMask = waveMaskBallot(mask, condition)
-INST(WaveMaskBallot, waveMaskBallot, 2, 0)
-
-/// matchMask = waveMaskBallot(mask, value)
-INST(WaveMaskMatch, waveMaskMatch, 2, 0)
-
-// Texture sampling operation of the form `t.Sample(s,u)`
-INST(Sample, sample, 3, 0)
-
-INST(SampleGrad, sampleGrad, 4, 0)
-
-INST(GroupMemoryBarrierWithGroupSync, GroupMemoryBarrierWithGroupSync, 0, 0)
-
-INST(ControlBarrier, ControlBarrier, 0, 0)
-
-// GPU_FOREACH loop of the form
-INST(GpuForeach, gpuForeach, 3, 0)
-
-// Wrapper for OptiX intrinsics used to load and store ray payload data using
-// a pointer represented by two payload registers.
-INST(GetOptiXRayPayloadPtr, getOptiXRayPayloadPtr, 0, HOISTABLE)
-
-// Wrapper for OptiX intrinsics used to load a single hit attribute
-// Takes two arguments: the type (either float or int), and the hit
-// attribute index
-INST(GetOptiXHitAttribute, getOptiXHitAttribute, 2, 0)
-
-// Wrapper for OptiX intrinsics used to load shader binding table record data
-// using a pointer.
-INST(GetOptiXSbtDataPtr, getOptiXSbtDataPointer, 0, 0)
-
-INST(GetVulkanRayTracingPayloadLocation, GetVulkanRayTracingPayloadLocation, 1, 0)
-
-INST(GetLegalizedSPIRVGlobalParamAddr, GetLegalizedSPIRVGlobalParamAddr, 1, 0)
-
-INST(GetPerVertexInputArray, GetPerVertexInputArray, 1, HOISTABLE)
-INST(ResolveVaryingInputRef, ResolveVaryingInputRef, 1, HOISTABLE)
-
-INST(ForceVarIntoStructTemporarily, ForceVarIntoStructTemporarily, 1, 0)
-INST(ForceVarIntoRayPayloadStructTemporarily, ForceVarIntoRayPayloadStructTemporarily, 1, 0)
-INST_RANGE(ForceVarIntoStructTemporarily, ForceVarIntoStructTemporarily, ForceVarIntoRayPayloadStructTemporarily)
-
-INST(MetalAtomicCast, MetalAtomicCast, 1, 0)
-
-INST(IsTextureAccess, IsTextureAccess, 1, 0)
-INST(IsTextureScalarAccess, IsTextureScalarAccess, 1, 0)
-INST(IsTextureArrayAccess, IsTextureArrayAccess, 1, 0)
-INST(ExtractTextureFromTextureAccess, ExtractTextureFromTextureAccess, 1, 0)
-INST(ExtractCoordFromTextureAccess, ExtractCoordFromTextureAccess, 1, 0)
-INST(ExtractArrayCoordFromTextureAccess, ExtractArrayCoordFromTextureAccess, 1, 0)
-
-INST(MakeArrayList, makeArrayList, 0, 0)
-INST(MakeTensorView, makeTensorView, 0, 0)
-INST(AllocateTorchTensor, allocTorchTensor, 0, 0)
-INST(TorchGetCudaStream, TorchGetCudaStream, 0, 0)
-INST(TorchTensorGetView, TorchTensorGetView, 0, 0)
-
-INST(CoopMatMapElementIFunc, CoopMatMapElementIFunc, 2, 0)
-
-INST(AllocateOpaqueHandle, allocateOpaqueHandle, 0, 0)
-
- // Return the register index thtat a resource is bound to.
- INST(GetRegisterIndex, getRegisterIndex, 1, 0)
-
- // Return the registe space that a resource is bound to.
- INST(GetRegisterSpace, getRegisterSpace, 1, 0)
-
-INST_RANGE(BindingQuery, GetRegisterIndex, GetRegisterSpace)
-
-/* Decoration */
-
- INST(HighLevelDeclDecoration, highLevelDecl, 1, 0)
- INST(LayoutDecoration, layout, 1, 0)
- INST(BranchDecoration, branch, 0, 0)
- INST(FlattenDecoration, flatten, 0, 0)
- INST(LoopControlDecoration, loopControl, 1, 0)
- INST(LoopMaxItersDecoration, loopMaxIters, 1, 0)
- INST(LoopExitPrimalValueDecoration, loopExitPrimalValue, 2, 0)
- INST(IntrinsicOpDecoration, intrinsicOp, 1, 0)
- /* TargetSpecificDecoration */
- INST(TargetDecoration, target, 1, 0)
- INST(TargetIntrinsicDecoration, targetIntrinsic, 2, 0)
- INST_RANGE(TargetSpecificDefinitionDecoration, TargetDecoration, TargetIntrinsicDecoration)
- INST(RequirePreludeDecoration, requirePrelude, 2, 0)
- INST_RANGE(TargetSpecificDecoration, TargetDecoration, RequirePreludeDecoration)
- INST(GLSLOuterArrayDecoration, glslOuterArray, 1, 0)
-
- INST(TargetSystemValueDecoration, TargetSystemValue, 2, 0)
-
- INST(InterpolationModeDecoration, interpolationMode, 1, 0)
- INST(NameHintDecoration, nameHint, 1, 0)
-
- INST(PhysicalTypeDecoration, PhysicalType, 1, 0)
-
- // Mark an address instruction as aligned to a specific byte boundary.
- INST(AlignedAddressDecoration, AlignedAddressDecoration, 1, 0)
-
- // Marks a type as being used as binary interface (e.g. shader parameters).
- // This prevents the legalizeEmptyType() pass from eliminating it on C++/CUDA targets.
- INST(BinaryInterfaceTypeDecoration, BinaryInterfaceType, 0, 0)
-
- /** The decorated _instruction_ is transitory. Such a decoration should NEVER be found on an output instruction a module.
- Typically used mark an instruction so can be specially handled - say when creating a IRConstant literal, and the payload of
- needs to be special cased for lookup. */
- INST(TransitoryDecoration, transitory, 0, 0)
-
- // The result witness table that the functon's return type is a subtype of an interface.
- // This is used to keep track of the original witness table in a function that used to
- // return an existential value but now returns a concrete type after specialization.
- INST(ResultWitnessDecoration, ResultWitness, 1, 0)
-
- INST(VulkanRayPayloadDecoration, vulkanRayPayload, 0, 0)
- INST(VulkanRayPayloadInDecoration, vulkanRayPayloadIn, 0, 0)
- INST(VulkanHitAttributesDecoration, vulkanHitAttributes, 0, 0)
- INST(VulkanHitObjectAttributesDecoration, vulkanHitObjectAttributes, 0, 0)
-
- INST(GlobalVariableShadowingGlobalParameterDecoration, GlobalVariableShadowingGlobalParameterDecoration, 2, 0)
-
- INST(RequireSPIRVVersionDecoration, requireSPIRVVersion, 1, 0)
- INST(RequireGLSLVersionDecoration, requireGLSLVersion, 1, 0)
- INST(RequireGLSLExtensionDecoration, requireGLSLExtension, 1, 0)
- INST(RequireWGSLExtensionDecoration, requireWGSLExtension, 1, 0)
- INST(RequireCUDASMVersionDecoration, requireCUDASMVersion, 1, 0)
- INST(RequireCapabilityAtomDecoration, requireCapabilityAtom, 1, 0)
-
- INST(HasExplicitHLSLBindingDecoration, HasExplicitHLSLBinding, 0, 0)
-
- INST(DefaultValueDecoration, DefaultValue, 1, 0)
- INST(ReadNoneDecoration, readNone, 0, 0)
- INST(VulkanCallablePayloadDecoration, vulkanCallablePayload, 0, 0)
- INST(VulkanCallablePayloadInDecoration, vulkanCallablePayloadIn, 0, 0)
- INST(EarlyDepthStencilDecoration, earlyDepthStencil, 0, 0)
- INST(PreciseDecoration, precise, 0, 0)
- INST(PublicDecoration, public, 0, 0)
- INST(HLSLExportDecoration, hlslExport, 0, 0)
- INST(DownstreamModuleExportDecoration, downstreamModuleExport, 0, 0)
- INST(DownstreamModuleImportDecoration, downstreamModuleImport, 0, 0)
- INST(PatchConstantFuncDecoration, patchConstantFunc, 1, 0)
- INST(MaxTessFactorDecoration, maxTessFactor, 1, 0)
- INST(OutputControlPointsDecoration, outputControlPoints, 1, 0)
- INST(OutputTopologyDecoration, outputTopology, 2, 0)
- INST(PartitioningDecoration, partioning, 1, 0)
- INST(DomainDecoration, domain, 1, 0)
- INST(MaxVertexCountDecoration, maxVertexCount, 1, 0)
- INST(InstanceDecoration, instance, 1, 0)
- INST(NumThreadsDecoration, numThreads, 3, 0)
- INST(FpDenormalPreserveDecoration, fpDenormalPreserve, 1, 0)
- INST(FpDenormalFlushToZeroDecoration, fpDenormalFlushToZero, 1, 0)
- INST(WaveSizeDecoration, waveSize, 1, 0)
-
- INST(AvailableInDownstreamIRDecoration, availableInDownstreamIR, 1, 0)
-
- // Added to IRParam parameters to an entry point
- /* GeometryInputPrimitiveTypeDecoration */
- INST(PointInputPrimitiveTypeDecoration, pointPrimitiveType, 0, 0)
- INST(LineInputPrimitiveTypeDecoration, linePrimitiveType, 0, 0)
- INST(TriangleInputPrimitiveTypeDecoration, trianglePrimitiveType, 0, 0)
- INST(LineAdjInputPrimitiveTypeDecoration, lineAdjPrimitiveType, 0, 0)
- INST(TriangleAdjInputPrimitiveTypeDecoration, triangleAdjPrimitiveType, 0, 0)
- INST_RANGE(GeometryInputPrimitiveTypeDecoration, PointInputPrimitiveTypeDecoration, TriangleAdjInputPrimitiveTypeDecoration)
-
- INST(StreamOutputTypeDecoration, streamOutputTypeDecoration, 1, 0)
-
- /// An `[entryPoint]` decoration marks a function that represents a shader entry point
- INST(EntryPointDecoration, entryPoint, 2, 0)
-
- INST(CudaKernelDecoration, CudaKernel, 0, 0)
- INST(CudaHostDecoration, CudaHost, 0, 0)
- INST(TorchEntryPointDecoration, TorchEntryPoint, 0, 0)
- INST(AutoPyBindCudaDecoration, AutoPyBindCUDA, 0, 0)
- INST(CudaKernelForwardDerivativeDecoration, CudaKernelFwdDiffRef, 0, 0)
- INST(CudaKernelBackwardDerivativeDecoration, CudaKernelBwdDiffRef, 0, 0)
- INST(AutoPyBindExportInfoDecoration, PyBindExportFuncInfo, 0, 0)
- INST(PyExportDecoration, PyExportDecoration, 0, 0)
-
- /// Used to mark parameters that are moved from entry point parameters to global params as coming from the entry point.
- INST(EntryPointParamDecoration, entryPointParam, 0, 0)
-
- /// A `[dependsOn(x)]` decoration indicates that the parent instruction depends on `x`
- /// even if it does not otherwise reference it.
- INST(DependsOnDecoration, dependsOn, 1, 0)
-
- /// A `[keepAlive]` decoration marks an instruction that should not be eliminated.
- INST(KeepAliveDecoration, keepAlive, 0, 0)
-
- /// A `[NoSideEffect]` decoration marks a callee to be side-effect free.
- INST(NoSideEffectDecoration, noSideEffect, 0, 0)
-
- INST(BindExistentialSlotsDecoration, bindExistentialSlots, 0, 0)
-
- /// A `[format(f)]` decoration specifies that the format of an image should be `f`
- INST(FormatDecoration, format, 1, 0)
-
- /// An `[unsafeForceInlineEarly]` decoration specifies that calls to this function should be inline after initial codegen
- INST(UnsafeForceInlineEarlyDecoration, unsafeForceInlineEarly, 0, 0)
-
- /// A `[ForceInline]` decoration indicates the callee should be inlined by the Slang compiler.
- INST(ForceInlineDecoration, ForceInline, 0, 0)
-
- /// A `[ForceUnroll]` decoration indicates the loop should be unrolled by the Slang compiler.
- INST(ForceUnrollDecoration, ForceUnroll, 0, 0)
-
- /// A `[SizeAndAlignment(l,s,a)]` decoration is attached to a type to indicate that is has size `s` and alignment `a` under layout rules `l`.
- INST(SizeAndAlignmentDecoration, SizeAndAlignment, 3, 0)
-
- /// A `[Offset(l, o)]` decoration is attached to a field to indicate that it has offset `o` in the parent type under layout rules `l`.
- INST(OffsetDecoration, Offset, 2, 0)
-
- /* LinkageDecoration */
- INST(ImportDecoration, import, 1, 0)
- INST(ExportDecoration, export, 1, 0)
- INST_RANGE(LinkageDecoration, ImportDecoration, ExportDecoration)
-
- /// Mark a global variable as a target builtin variable.
- INST(TargetBuiltinVarDecoration, TargetBuiltinVar, 1, 0)
-
- /// Marks an inst as coming from an `extern` symbol defined in the user code.
- INST(UserExternDecoration, UserExtern, 0, 0)
-
- /// An extern_cpp decoration marks the inst to emit its name without mangling for C++ interop.
- INST(ExternCppDecoration, externCpp, 1, 0)
-
- // An externC decoration marks a function should be emitted inside an extern "C" block.
- INST(ExternCDecoration, externC, 0, 0)
-
- /// An dllImport decoration marks a function as imported from a DLL. Slang will generate dynamic function loading logic to use this function at runtime.
- INST(DllImportDecoration, dllImport, 2, 0)
- /// An dllExport decoration marks a function as an export symbol. Slang will generate a native wrapper function that is exported to DLL.
- INST(DllExportDecoration, dllExport, 1, 0)
- /// An cudaDeviceExport decoration marks a function to be exported as a cuda __device__ function.
- INST(CudaDeviceExportDecoration, cudaDeviceExport, 1, 0)
-
- /// Marks an interface as a COM interface declaration.
- INST(ComInterfaceDecoration, COMInterface, 0, 0)
-
- /// Attaches a name to this instruction so that it can be identified
- /// later in the compiler reliably
- INST(KnownBuiltinDecoration, KnownBuiltinDecoration, 1, 0)
-
- /* Decorations for RTTI objects */
- INST(RTTITypeSizeDecoration, RTTI_typeSize, 1, 0)
- INST(AnyValueSizeDecoration, AnyValueSize, 1, 0)
- INST(SpecializeDecoration, SpecializeDecoration, 0, 0)
- INST(SequentialIDDecoration, SequentialIDDecoration, 1, 0)
- INST(DynamicDispatchWitnessDecoration, DynamicDispatchWitnessDecoration, 0, 0)
- INST(StaticRequirementDecoration, StaticRequirementDecoration, 0, 0)
- INST(DispatchFuncDecoration, DispatchFuncDecoration, 1, 0)
- INST(TypeConstraintDecoration, TypeConstraintDecoration, 1, 0)
-
-
- INST(BuiltinDecoration, BuiltinDecoration, 0, 0)
-
- /// The decorated instruction requires NVAPI to be included via prelude when compiling for D3D.
- INST(RequiresNVAPIDecoration, requiresNVAPI, 0, 0)
-
- /// The decorated instruction is part of the NVAPI "magic" and should always use its original name
- INST(NVAPIMagicDecoration, nvapiMagic, 1, 0)
-
- /// A decoration that applies to an entire IR module, and indicates the register/space binding
- /// that the NVAPI shader parameter intends to use.
- INST(NVAPISlotDecoration, nvapiSlot, 2, 0)
-
- /// Applie to an IR function and signals that inlining should not be performed unless unavoidable.
- INST(NoInlineDecoration, noInline, 0, 0)
- INST(NoRefInlineDecoration, noRefInline, 0, 0)
-
- INST(DerivativeGroupQuadDecoration, DerivativeGroupQuad, 0, 0)
- INST(DerivativeGroupLinearDecoration, DerivativeGroupLinear, 0, 0)
-
- INST(MaximallyReconvergesDecoration, MaximallyReconverges, 0, 0)
- INST(QuadDerivativesDecoration, QuadDerivatives, 0, 0)
- INST(RequireFullQuadsDecoration, RequireFullQuads, 0, 0)
- INST(TempCallArgVarDecoration, TempCallArgVar, 0, 0)
-
- // Marks a type to be non copyable, causing SSA pass to skip turning variables of the the type into SSA values.
- INST(NonCopyableTypeDecoration, nonCopyable, 0, 0)
-
- // Marks a value to be dynamically uniform.
- INST(DynamicUniformDecoration, DynamicUniform, 0, 0)
-
- /// A call to the decorated function should always be folded into its use site.
- INST(AlwaysFoldIntoUseSiteDecoration, alwaysFold, 0, 0)
-
- INST(GlobalOutputDecoration, output, 0, 0)
- INST(GlobalInputDecoration, input, 0, 0)
- INST(GLSLLocationDecoration, glslLocation, 1, 0)
- INST(GLSLOffsetDecoration, glslOffset, 1, 0)
- INST(VkStructOffsetDecoration, vkStructOffset, 1, 0)
- INST(RayPayloadDecoration, raypayload, 0, 0)
-
- /* Mesh Shader outputs */
- INST(VerticesDecoration, vertices, 1, 0)
- INST(IndicesDecoration, indices, 1, 0)
- INST(PrimitivesDecoration, primitives, 1, 0)
- INST_RANGE(MeshOutputDecoration, VerticesDecoration, PrimitivesDecoration)
- INST(HLSLMeshPayloadDecoration, payload, 0, 0)
- INST(GLSLPrimitivesRateDecoration, perprimitive, 0, 0)
- // Marks an inst that represents the gl_Position output.
- INST(GLPositionOutputDecoration, PositionOutput, 0, 0)
- // Marks an inst that represents the gl_Position input.
- INST(GLPositionInputDecoration, PositionInput, 0, 0)
-
- // Marks a fragment shader input as per-vertex.
- INST(PerVertexDecoration, PerVertex, 0, 0)
-
- /* StageAccessDecoration */
- INST(StageReadAccessDecoration, stageReadAccess, 0, 0)
- INST(StageWriteAccessDecoration, stageWriteAccess, 0, 0)
- INST_RANGE(StageAccessDecoration, StageReadAccessDecoration, StageWriteAccessDecoration)
-
- INST(SemanticDecoration, semantic, 2, 0)
- INST(ConstructorDecoration, constructor, 1, 0)
- INST(MethodDecoration, method, 0, 0)
- INST(PackOffsetDecoration, packoffset, 2, 0)
- INST(SpecializationConstantDecoration, SpecializationConstantDecoration, 1, 0)
-
- // Reflection metadata for a shader parameter that provides the original type name.
- INST(UserTypeNameDecoration, UserTypeName, 1, 0)
- // Reflection metadata for a shader parameter that refers to the associated counter buffer of a UAV.
- INST(CounterBufferDecoration, CounterBuffer, 1, 0)
-
- INST(RequireSPIRVDescriptorIndexingExtensionDecoration, RequireSPIRVDescriptorIndexingExtensionDecoration, 0, 0)
- INST(SPIRVOpDecoration, spirvOpDecoration, 1, 0)
-
- /// Decorated function is marked for the forward-mode differentiation pass.
- INST(ForwardDifferentiableDecoration, forwardDifferentiable, 0, 0)
-
- /// Decorates a auto-diff transcribed value with the original value that the inst is transcribed from.
- INST(AutoDiffOriginalValueDecoration, AutoDiffOriginalValueDecoration, 1, 0)
-
- /// Decorates a type as auto-diff builtin type.
- INST(AutoDiffBuiltinDecoration, AutoDiffBuiltinDecoration, 0, 0)
-
- /// Used by the auto-diff pass to hold a reference to the
- /// generated derivative function.
- INST(ForwardDerivativeDecoration, fwdDerivative, 1, 0)
-
- /// Used by the auto-diff pass to hold a reference to the
- /// generated derivative function.
- INST(BackwardDifferentiableDecoration, backwardDifferentiable, 1, 0)
-
- /// Used by the auto-diff pass to hold a reference to the
- /// primal substitute function.
- INST(PrimalSubstituteDecoration, primalSubstFunc, 1, 0)
-
- /// Decorations to associate an original function with compiler generated backward derivative functions.
- INST(BackwardDerivativePrimalDecoration, backwardDiffPrimalReference, 1, 0)
- INST(BackwardDerivativePropagateDecoration, backwardDiffPropagateReference, 1, 0)
- INST(BackwardDerivativeIntermediateTypeDecoration, backwardDiffIntermediateTypeReference, 1, 0)
- INST(BackwardDerivativeDecoration, backwardDiffReference, 1, 0)
-
- INST(UserDefinedBackwardDerivativeDecoration, userDefinedBackwardDiffReference, 1, 0)
- INST(BackwardDerivativePrimalContextDecoration, BackwardDerivativePrimalContextDecoration, 1, 0)
- INST(BackwardDerivativePrimalReturnDecoration, BackwardDerivativePrimalReturnDecoration, 1, 0)
-
- // Mark a parameter as autodiff primal context.
- INST(PrimalContextDecoration, PrimalContextDecoration, 0, 0)
- INST(LoopCounterDecoration, loopCounterDecoration, 0, 0)
- INST(LoopCounterUpdateDecoration, loopCounterUpdateDecoration, 0, 0)
-
- /* Auto-diff inst decorations */
- /// Used by the auto-diff pass to mark insts that compute
- /// a primal value.
- INST(PrimalInstDecoration, primalInstDecoration, 0, 0)
-
- /// Used by the auto-diff pass to mark insts that compute
- /// a differential value.
- INST(DifferentialInstDecoration, diffInstDecoration, 1, 0)
-
- /// Used by the auto-diff pass to mark insts that compute
- /// BOTH a differential and a primal value.
- INST(MixedDifferentialInstDecoration, mixedDiffInstDecoration, 1, 0)
-
- INST(RecomputeBlockDecoration, RecomputeBlockDecoration, 0, 0)
- INST_RANGE(AutodiffInstDecoration, PrimalInstDecoration, RecomputeBlockDecoration)
-
- /// Used by the auto-diff pass to mark insts whose result is stored
- /// in an intermediary struct for reuse in backward propagation phase.
- INST(PrimalValueStructKeyDecoration, primalValueKey, 1, 0)
-
- /// Used by the auto-diff pass to mark the primal element type of an
- /// forward-differentiated updateElement inst.
- INST(PrimalElementTypeDecoration, primalElementType, 1, 0)
-
- /// Used by the auto-diff pass to mark the differential type of an intermediate context field.
- INST(IntermediateContextFieldDifferentialTypeDecoration, IntermediateContextFieldDifferentialTypeDecoration, 1, 0)
-
- /// Used by the auto-diff pass to hold a reference to a
- /// differential member of a type in its associated differential type.
- INST(DerivativeMemberDecoration, derivativeMemberDecoration, 1, 0)
-
- /// Treat a function as differentiable function
- INST(TreatAsDifferentiableDecoration, treatAsDifferentiableDecoration, 0, 0)
-
- /// Treat a call to arbitrary function as a differentiable call.
- INST(TreatCallAsDifferentiableDecoration, treatCallAsDifferentiableDecoration, 0, 0)
-
- /// Mark a call as explicitly calling a differentiable function.
- INST(DifferentiableCallDecoration, differentiableCallDecoration, 0, 0)
-
- /// Mark a type as being eligible for trimming if necessary. If
- /// any fields don't have any effective loads from them, they can be
- /// removed.
- ///
- INST(OptimizableTypeDecoration, optimizableTypeDecoration, 0, 0)
-
- /// Informs the DCE pass to ignore side-effects on this call for
- /// the purposes of dead code elimination, even if the call does have
- /// side-effects.
- ///
- INST(IgnoreSideEffectsDecoration, ignoreSideEffectsDecoration, 0, 0)
-
- /// Hint that the result from a call to the decorated function should be stored in backward prop function.
- INST(PreferCheckpointDecoration, PreferCheckpointDecoration, 0, 0)
-
- /// Hint that the result from a call to the decorated function should be recomputed in backward prop function.
- INST(PreferRecomputeDecoration, PreferRecomputeDecoration, 0, 0)
-
- /// Hint that a struct is used for reverse mode checkpointing
- INST(CheckpointIntermediateDecoration, CheckpointIntermediateDecoration, 1, 0)
-
- INST_RANGE(CheckpointHintDecoration, PreferCheckpointDecoration, PreferRecomputeDecoration)
-
- /// Marks a function whose return value is never dynamic uniform.
- INST(NonDynamicUniformReturnDecoration, NonDynamicUniformReturnDecoration, 0, 0)
-
- /// Marks a class type as a COM interface implementation, which enables
- /// the witness table to be easily picked up by emit.
- INST(COMWitnessDecoration, COMWitnessDecoration, 1, 0)
-
- /* Differentiable Type Dictionary */
- INST(DifferentiableTypeDictionaryDecoration, DifferentiableTypeDictionaryDecoration, 0, PARENT)
-
- /// Overrides the floating mode for the target function
- INST(FloatingPointModeOverrideDecoration, FloatingPointModeOverride, 1, 0)
-
- /// Recognized by SPIRV-emit pass so we can emit a SPIRV `BufferBlock` decoration.
- INST(SPIRVBufferBlockDecoration, spvBufferBlock, 0, 0)
-
- /// Decorates an inst with a debug source location (IRDebugSource, IRIntLit(line), IRIntLit(col)).
- INST(DebugLocationDecoration, DebugLocation, 3, 0)
-
- /// Decorates a function with a link to its debug function representation
- INST(DebugFunctionDecoration, DebugFunction, 1, 0)
-
- /// Recognized by SPIRV-emit pass so we can emit a SPIRV `Block` decoration.
- INST(SPIRVBlockDecoration, spvBlock, 0, 0)
-
- /// Decorates a SPIRV-inst as `NonUniformResource` to guarantee non-uniform index lookup of
- /// - a resource within an array of resources via IRGetElement.
- /// - an IRLoad that takes a pointer within a memory buffer via IRGetElementPtr.
- /// - an IRIntCast to a resource that is casted from signed to unsigned or viceversa.
- /// - an IRGetElementPtr itself when using the pointer on an intrinsic operation.
- INST(SPIRVNonUniformResourceDecoration, NonUniformResource, 0, 0)
-
- // Stores flag bits of which memory qualifiers an object has
- INST(MemoryQualifierSetDecoration, MemoryQualifierSetDecoration, 1, 0)
-
- /// Marks a function as one which access a bitfield with the specified
- /// backing value key, width and offset
- INST(BitFieldAccessorDecoration, BitFieldAccessorDecoration, 3, 0)
-
- INST_RANGE(Decoration, HighLevelDeclDecoration, BitFieldAccessorDecoration)
-
- //
-
-// A `makeExistential(v : C, w) : I` instruction takes a value `v` of type `C`
-// and produces a value of interface type `I` by using the witness `w` which
-// shows that `C` conforms to `I`.
-//
-INST(MakeExistential, makeExistential, 2, 0)
-// A `MakeExistentialWithRTTI(v, w, t)` is the same with `MakeExistential`,
-// but with the type of `v` being an explict operand.
-INST(MakeExistentialWithRTTI, makeExistentialWithRTTI, 3, 0)
-
-// A 'CreateExistentialObject<I>(typeID, T)` packs user-provided `typeID` and a
-// value of any type, and constructs an existential value of type `I`.
-INST(CreateExistentialObject, createExistentialObject, 2, 0)
-
-// A `wrapExistential(v, T0,w0, T1,w0) : T` instruction is similar to `makeExistential`.
-// but applies to a value `v` that is of type `BindExistentials(T, T0,w0, ...)`. The
-// result of the `wrapExistentials` operation is a value of type `T`, allowing us to
-// "smuggle" a value of specialized type into computations that expect an unspecialized type.
-//
-INST(WrapExistential, wrapExistential, 1, 0)
-
-// A `GetValueFromBoundInterface` takes a `BindInterface<I, T, w0>` value and returns the
-// value of concrete type `T` value that is being stored.
-//
-INST(GetValueFromBoundInterface, getValueFromBoundInterface, 1, 0)
-
-INST(ExtractExistentialValue, extractExistentialValue, 1, 0)
-INST(ExtractExistentialType, extractExistentialType, 1, HOISTABLE)
-INST(ExtractExistentialWitnessTable, extractExistentialWitnessTable, 1, HOISTABLE)
-INST(IsNullExistential, isNullExistential, 1, 0)
-INST(ExtractTaggedUnionTag, extractTaggedUnionTag, 1, 0)
-INST(ExtractTaggedUnionPayload, extractTaggedUnionPayload, 1, 0)
-
-INST(BuiltinCast, BuiltinCast, 1, 0)
-INST(BitCast, bitCast, 1, 0)
-INST(Reinterpret, reinterpret, 1, 0)
-INST(Unmodified, unmodified, 1, 0)
-INST(OutImplicitCast, outImplicitCast, 1, 0)
-INST(InOutImplicitCast, inOutImplicitCast, 1, 0)
-INST(IntCast, intCast, 1, 0)
-INST(FloatCast, floatCast, 1, 0)
-INST(CastIntToFloat, castIntToFloat, 1, 0)
-INST(CastFloatToInt, castFloatToInt, 1, 0)
-INST(CastPtrToBool, CastPtrToBool, 1, 0)
-INST(CastPtrToInt, CastPtrToInt, 1, 0)
-INST(CastIntToPtr, CastIntToPtr, 1, 0)
-INST(CastToVoid, castToVoid, 1, 0)
-INST(PtrCast, PtrCast, 1, 0)
-INST(CastEnumToInt, CastEnumToInt, 1, 0)
-INST(CastIntToEnum, CastIntToEnum, 1, 0)
-INST(EnumCast, EnumCast, 1, 0)
-INST(CastUInt2ToDescriptorHandle, CastUInt2ToDescriptorHandle, 1, 0)
-INST(CastDescriptorHandleToUInt2, CastDescriptorHandleToUInt2, 1, 0)
-
-// Represents a no-op cast to convert a resource pointer to a resource on targets where the resource handles are already concrete types.
-INST(CastDescriptorHandleToResource, CastDescriptorHandleToResource, 1, 0)
-
-INST(TreatAsDynamicUniform, TreatAsDynamicUniform, 1, 0)
-
-INST(SizeOf, sizeOf, 1, 0)
-INST(AlignOf, alignOf, 1, 0)
-INST(CountOf, countOf, 1, 0)
-
-INST(GetArrayLength, GetArrayLength, 1, 0)
-INST(IsType, IsType, 3, 0)
-INST(TypeEquals, TypeEquals, 2, 0)
-INST(IsInt, IsInt, 1, 0)
-INST(IsBool, IsBool, 1, 0)
-INST(IsFloat, IsFloat, 1, 0)
-INST(IsHalf, IsHalf, 1, 0)
-INST(IsUnsignedInt, IsUnsignedInt, 1, 0)
-INST(IsSignedInt, IsSignedInt, 1, 0)
-INST(IsVector, IsVector, 1, 0)
-INST(GetDynamicResourceHeap, GetDynamicResourceHeap, 0, HOISTABLE)
-
-INST(ForwardDifferentiate, ForwardDifferentiate, 1, 0)
-
-// Produces the primal computation of backward derivatives, will return an intermediate context for
-// backward derivative func.
-INST(BackwardDifferentiatePrimal, BackwardDifferentiatePrimal, 1, 0)
-
-// Produces the actual backward derivative propagate function, using the intermediate context returned by the
-// primal func produced from `BackwardDifferentiatePrimal`.
-INST(BackwardDifferentiatePropagate, BackwardDifferentiatePropagate, 1, 0)
-
-// Represents the conceptual backward derivative function. Only produced by lower-to-ir and will be
-// replaced with `BackwardDifferentiatePrimal` and `BackwardDifferentiatePropagate`.
-INST(BackwardDifferentiate, BackwardDifferentiate, 1, 0)
-
-INST(PrimalSubstitute, PrimalSubstitute, 1, 0)
-
-INST(DispatchKernel, DispatchKernel, 3, 0)
-INST(CudaKernelLaunch, CudaKernelLaunch, 6, 0)
-
-// Converts other resources (such as ByteAddressBuffer) to the equivalent StructuredBuffer
-INST(GetEquivalentStructuredBuffer, getEquivalentStructuredBuffer, 1, 0)
-
-// Gets a T[] pointer to the underlying data of a StructuredBuffer etc...
-INST(GetStructuredBufferPtr, getStructuredBufferPtr, 1, 0)
-// Gets a uint[] pointer to the underlying data of a ByteAddressBuffer etc...
-INST(GetUntypedBufferPtr, getUntypedBufferPtr, 1, 0)
-
-/* Layout */
- INST(VarLayout, varLayout, 1, HOISTABLE)
-
- /* TypeLayout */
- INST(TypeLayoutBase, typeLayout, 0, HOISTABLE)
- INST(ParameterGroupTypeLayout, parameterGroupTypeLayout, 2, HOISTABLE)
- INST(ArrayTypeLayout, arrayTypeLayout, 1, HOISTABLE)
- INST(StreamOutputTypeLayout, streamOutputTypeLayout, 1, HOISTABLE)
- INST(MatrixTypeLayout, matrixTypeLayout, 1, HOISTABLE)
- INST(ExistentialTypeLayout, existentialTypeLayout, 0, HOISTABLE)
- INST(StructTypeLayout, structTypeLayout, 0, HOISTABLE)
- INST(TupleTypeLayout, tupleTypeLayout, 0, HOISTABLE)
- INST(StructuredBufferTypeLayout, structuredBufferTypeLayout, 1, HOISTABLE)
- // TODO(JS): Ideally we'd have the layout to the pointed to value type (ie 1 instead of 0 here). But to avoid infinite recursion we don't.
- INST(PointerTypeLayout, ptrTypeLayout, 0, HOISTABLE)
- INST_RANGE(TypeLayout, TypeLayoutBase, PointerTypeLayout)
-
- INST(EntryPointLayout, EntryPointLayout, 1, HOISTABLE)
-INST_RANGE(Layout, VarLayout, EntryPointLayout)
-
-/* Attr */
- INST(PendingLayoutAttr, pendingLayout, 1, HOISTABLE)
- INST(StageAttr, stage, 1, HOISTABLE)
- INST(StructFieldLayoutAttr, fieldLayout, 2, HOISTABLE)
- INST(TupleFieldLayoutAttr, fieldLayout, 1, HOISTABLE)
- INST(CaseTypeLayoutAttr, caseLayout, 1, HOISTABLE)
- INST(UNormAttr, unorm, 0, HOISTABLE)
- INST(SNormAttr, snorm, 0, HOISTABLE)
- INST(NoDiffAttr, no_diff, 0, HOISTABLE)
- INST(NonUniformAttr, nonuniform, 0, HOISTABLE)
- INST(AlignedAttr, Aligned, 1, HOISTABLE)
-
- /* SemanticAttr */
- INST(UserSemanticAttr, userSemantic, 2, HOISTABLE)
- INST(SystemValueSemanticAttr, systemValueSemantic, 2, HOISTABLE)
- INST_RANGE(SemanticAttr, UserSemanticAttr, SystemValueSemanticAttr)
- /* LayoutResourceInfoAttr */
- INST(TypeSizeAttr, size, 2, HOISTABLE)
- INST(VarOffsetAttr, offset, 2, HOISTABLE)
- INST_RANGE(LayoutResourceInfoAttr, TypeSizeAttr, VarOffsetAttr)
- INST(FuncThrowTypeAttr, FuncThrowType, 1, HOISTABLE)
-
-INST_RANGE(Attr, PendingLayoutAttr, FuncThrowTypeAttr)
-
-/* Liveness */
- INST(LiveRangeStart, liveRangeStart, 2, 0)
- INST(LiveRangeEnd, liveRangeEnd, 0, 0)
-INST_RANGE(LiveRangeMarker, LiveRangeStart, LiveRangeEnd)
-
-/* IRSpecialization */
-INST(SpecializationDictionaryItem, SpecializationDictionaryItem, 0, 0)
-INST(GenericSpecializationDictionary, GenericSpecializationDictionary, 0, PARENT)
-INST(ExistentialFuncSpecializationDictionary, ExistentialFuncSpecializationDictionary, 0, PARENT)
-INST(ExistentialTypeSpecializationDictionary, ExistentialTypeSpecializationDictionary, 0, PARENT)
-
-/* Differentiable Type Dictionary */
-INST(DifferentiableTypeDictionaryItem, DifferentiableTypeDictionaryItem, 0, 0)
-
-/* Differentiable Type Annotation (for run-time types)*/
-INST(DifferentiableTypeAnnotation, DifferentiableTypeAnnotation, 2, HOISTABLE)
-
-INST(BeginFragmentShaderInterlock, BeginFragmentShaderInterlock, 0, 0)
-INST(EndFragmentShaderInterlock, BeginFragmentShaderInterlock, 0, 0)
-
-/* DebugInfo */
-INST(DebugSource, DebugSource, 2, HOISTABLE)
-INST(DebugLine, DebugLine, 5, 0)
-INST(DebugVar, DebugVar, 4, 0)
-INST(DebugValue, DebugValue, 2, 0)
-INST(DebugInlinedAt, DebugInlinedAt, 5, 0)
-INST(DebugFunction, DebugFunction, 5, 0)
-INST(DebugInlinedVariable, DebugInlinedVariable, 2, 0)
-INST(DebugScope, DebugScope, 2, 0)
-INST(DebugNoScope, DebugNoScope, 1, 0)
-INST(DebugBuildIdentifier, DebugBuildIdentifier, 2, 0)
-
-/* Embedded Precompiled Libraries */
-INST(EmbeddedDownstreamIR, EmbeddedDownstreamIR, 2, 0)
-
-/* Inline assembly */
-
-INST(SPIRVAsm, SPIRVAsm, 0, PARENT)
-INST(SPIRVAsmInst, SPIRVAsmInst, 1, 0)
- // These instruction serve to inform the backend precisely how to emit each
- // instruction, consider the difference between emitting a literal integer
- // and a reference to a literal integer instruction
- //
- // A literal string or 32-bit integer to be passed as operands
- INST(SPIRVAsmOperandLiteral, SPIRVAsmOperandLiteral, 1, HOISTABLE)
- // A reference to a slang IRInst, either a value or a type
- // This isn't hoistable, as we sometimes need to change the used value and
- // instructions around the specific asm block
- INST(SPIRVAsmOperandInst, SPIRVAsmOperandInst, 1, 0)
- INST(SPIRVAsmOperandConvertTexel, SPIRVAsmOperandConvertTexel, 1, 0)
- //a late resolving type to handle the case of ray objects (resolving late due to constexpr data requirment)
- INST(SPIRVAsmOperandRayPayloadFromLocation, SPIRVAsmOperandRayPayloadFromLocation, 1, 0)
- INST(SPIRVAsmOperandRayAttributeFromLocation, SPIRVAsmOperandRayAttributeFromLocation, 1, 0)
- INST(SPIRVAsmOperandRayCallableFromLocation, SPIRVAsmOperandRayCallableFromLocation, 1, 0)
- // A named enumerator, the value is stored as a constant operand
- // It may have a second operand, which if present is a type with which to
- // construct a constant id to pass, instead of a literal constant
- INST(SPIRVAsmOperandEnum, SPIRVAsmOperandEnum, 1, HOISTABLE)
- // A reference to a builtin variable.
- INST(SPIRVAsmOperandBuiltinVar, SPIRVAsmOperandBuiltinVar, 1, HOISTABLE)
- // A reference to the glsl450 instruction set.
- INST(SPIRVAsmOperandGLSL450Set, SPIRVAsmOperandGLSL450Set, 0, HOISTABLE)
- INST(SPIRVAsmOperandDebugPrintfSet, SPIRVAsmOperandDebugPrintfSet, 0, HOISTABLE)
- // A string which is given a unique ID in the backend, used to refer to
- // results of other instrucions in the same asm block
- INST(SPIRVAsmOperandId, SPIRVAsmOperandId, 1, HOISTABLE)
- // A special instruction which marks the place to insert the generated
- // result operand
- INST(SPIRVAsmOperandResult, SPIRVAsmOperandResult, 0, HOISTABLE)
- // A special instruction which represents a type directed truncation
- // operation where extra components are dropped
- INST(SPIRVAsmOperandTruncate, __truncate, 0, HOISTABLE)
-
- // A special instruction which represents an ID of an entry point that references the current function.
- INST(SPIRVAsmOperandEntryPoint, __entryPoint, 0, HOISTABLE)
-
- // A type function which returns the result type of sampling an image of
- // this component type
- INST(SPIRVAsmOperandSampledType, __sampledType, 1, HOISTABLE)
-
- // A type function which returns the equivalent OpTypeImage type of sampled image value
- INST(SPIRVAsmOperandImageType, __imageType, 1, HOISTABLE)
-
- // A type function which returns the equivalent OpTypeImage type of sampled image value
- INST(SPIRVAsmOperandSampledImageType, __sampledImageType, 1, HOISTABLE)
-
-INST_RANGE(SPIRVAsmOperand, SPIRVAsmOperandLiteral, SPIRVAsmOperandSampledImageType)
-
-
-#undef PARENT
-#undef USE_OTHER
-#undef INST_RANGE
-#undef INST
diff --git a/source/slang/slang-ir-insts-enum.h b/source/slang/slang-ir-insts-enum.h
new file mode 100644
index 000000000..061b1c18e
--- /dev/null
+++ b/source/slang/slang-ir-insts-enum.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <cstdint>
+
+namespace Slang
+{
+
+/* Bit usage of IROp is as follows
+
+ MainOp | Other
+Bit range: 0-10 | Remaining bits
+
+For doing range checks (for example for doing isa tests), the value is masked by kIROpMask_OpMask,
+such that the Other bits don't interfere. The other bits can be used for storage for anything that
+needs to identify as a different 'op' or 'type'. It is currently used currently for storing the
+TextureFlavor of a IRResourceTypeBase derived types for example.
+
+TODO: We should eliminate the use of the "other" bits so that the entire value/state
+of an instruction is manifest in its opcode, operands, and children.
+*/
+enum IROp : int32_t
+{
+
+#if 0 // FIDDLE TEMPLATE:
+% require("source/slang/slang-ir.h.lua").instEnums()
+#else // FIDDLE OUTPUT:
+#define FIDDLE_GENERATED_OUTPUT_ID 0
+#include "slang-ir-insts-enum.h.fiddle"
+#endif // FIDDLE END
+
+ /// The total number of valid opcodes
+ kIROpCount,
+
+ /// An invalid opcode used to represent a missing or unknown opcode value.
+ kIROp_Invalid = kIROpCount,
+};
+} // namespace Slang
diff --git a/source/slang/slang-ir-insts-info.cpp b/source/slang/slang-ir-insts-info.cpp
new file mode 100644
index 000000000..5b03c3dbe
--- /dev/null
+++ b/source/slang/slang-ir-insts-info.cpp
@@ -0,0 +1,63 @@
+#include "core/slang-basic.h"
+#include "slang-ir.h"
+
+namespace Slang
+{
+
+struct IROpMapEntry
+{
+ IROp op;
+ IROpInfo info;
+};
+
+// TODO: We should ideally be speeding up the name->inst
+// mapping by using a dictionary, or even by pre-computing
+// a hash table to be stored as a `static const` array.
+//
+// NOTE! That this array is now constructed in such a way that looking up
+// an entry from an op is fast, by keeping blocks of main, and pseudo ops in same order
+// as the ops themselves. Care must be taken to keep this constraint.
+static const IROpMapEntry kIROps[] = {
+
+// Main ops in order
+
+#if 0 // FIDDLE TEMPLATE:
+% require("source/slang/slang-ir.h.lua").instInfoEntries()
+#else // FIDDLE OUTPUT:
+#define FIDDLE_GENERATED_OUTPUT_ID 0
+#include "slang-ir-insts-info.cpp.fiddle"
+#endif // FIDDLE END
+
+ // Invalid op sentinel value comes after all the valid ones
+ {kIROp_Invalid, {"invalid", 0, 0}},
+};
+
+IROpInfo getIROpInfo(IROp opIn)
+{
+ const int op = opIn & kIROpMask_OpMask;
+ if (op < kIROpCount)
+ {
+ // It's a main op
+ const auto& entry = kIROps[op];
+ SLANG_ASSERT(entry.op == op);
+ return entry.info;
+ }
+
+ // Don't know what this is
+ SLANG_ASSERT(!"Invalid op");
+ SLANG_ASSERT(kIROps[kIROpCount].op == kIROp_Invalid);
+ return kIROps[kIROpCount].info;
+}
+
+IROp findIROp(const UnownedStringSlice& name)
+{
+ for (auto ee : kIROps)
+ {
+ if (name == ee.info.name)
+ return ee.op;
+ }
+
+ return IROp(kIROp_Invalid);
+}
+
+} // namespace Slang
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index bb57c082c..8ce4e46cd 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -1,6 +1,5 @@
// slang-ir-insts.h
-#ifndef SLANG_IR_INSTS_H_INCLUDED
-#define SLANG_IR_INSTS_H_INCLUDED
+#pragma once
// This file extends the core definitions in `ir.h`
// with a wider variety of concrete instructions,
@@ -14,21 +13,27 @@
#include "slang-syntax.h"
#include "slang-type-layout.h"
+//
+#include "slang-ir-insts.h.fiddle"
+
+FIDDLE()
namespace Slang
{
class Decl;
+FIDDLE()
struct IRCapabilitySet : IRInst
{
- IR_PARENT_ISA(CapabilitySet);
+ FIDDLE(baseInst())
CapabilitySet getCaps();
};
+FIDDLE()
struct IRDecoration : IRInst
{
- IR_PARENT_ISA(Decoration)
+ FIDDLE(baseInst())
IRDecoration* getNextDecoration() { return as<IRDecoration>(getNextInst()); }
};
@@ -36,13 +41,10 @@ struct IRDecoration : IRInst
// Associates an IR-level decoration with a source declaration
// in the high-level AST, that can be used to extract
// additional information that informs code emission.
+FIDDLE()
struct IRHighLevelDeclDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_HighLevelDeclDecoration
- };
- IR_LEAF_ISA(HighLevelDeclDecoration)
+ FIDDLE(leafInst())
IRPtrLit* getDeclOperand() { return cast<IRPtrLit>(getOperand(0)); }
Decl* getDecl() { return (Decl*)getDeclOperand()->getValue(); }
@@ -54,34 +56,29 @@ enum IRLoopControl
kIRLoopControl_Loop,
};
+FIDDLE()
struct IRLoopControlDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_LoopControlDecoration
- };
- IR_LEAF_ISA(LoopControlDecoration)
+ FIDDLE(leafInst())
IRConstant* getModeOperand() { return cast<IRConstant>(getOperand(0)); }
IRLoopControl getMode() { return IRLoopControl(getModeOperand()->value.intVal); }
};
+FIDDLE()
struct IRLoopMaxItersDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_LoopMaxItersDecoration
- };
- IR_LEAF_ISA(LoopMaxItersDecoration)
+ FIDDLE(leafInst())
IRConstant* getMaxItersInst() { return cast<IRConstant>(getOperand(0)); }
IRIntegerValue getMaxIters() { return as<IRIntLit>(getOperand(0))->getValue(); }
};
+FIDDLE()
struct IRTargetSpecificDecoration : IRDecoration
{
- IR_PARENT_ISA(TargetSpecificDecoration)
+ FIDDLE(baseInst())
IRCapabilitySet* getTargetCapsOperand() { return cast<IRCapabilitySet>(getOperand(0)); }
@@ -108,79 +105,67 @@ struct IRTargetSpecificDecoration : IRDecoration
}
};
+FIDDLE()
struct IRTargetSpecificDefinitionDecoration : IRTargetSpecificDecoration
{
- IR_PARENT_ISA(TargetSpecificDefinitionDecoration)
+ FIDDLE(baseInst())
};
+FIDDLE()
struct IRTargetDecoration : IRTargetSpecificDefinitionDecoration
{
- enum
- {
- kOp = kIROp_TargetDecoration
- };
- IR_LEAF_ISA(TargetDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRTargetSystemValueDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_TargetSystemValueDecoration
- };
- IR_LEAF_ISA(TargetSystemValueDecoration)
+ FIDDLE(leafInst())
IRStringLit* getSemanticOperand() { return cast<IRStringLit>(getOperand(0)); }
UnownedStringSlice getSemantic() { return getSemanticOperand()->getStringSlice(); }
};
+FIDDLE()
struct IRTargetIntrinsicDecoration : IRTargetSpecificDefinitionDecoration
{
- enum
- {
- kOp = kIROp_TargetIntrinsicDecoration
- };
- IR_LEAF_ISA(TargetIntrinsicDecoration)
+ FIDDLE(leafInst())
IRStringLit* getDefinitionOperand() { return cast<IRStringLit>(getOperand(1)); }
UnownedStringSlice getDefinition() { return getDefinitionOperand()->getStringSlice(); }
};
+FIDDLE()
struct IRRequirePreludeDecoration : IRTargetSpecificDecoration
{
- IR_LEAF_ISA(RequirePreludeDecoration)
+ FIDDLE(leafInst())
UnownedStringSlice getPrelude() { return as<IRStringLit>(getOperand(1))->getStringSlice(); }
};
+FIDDLE()
struct IRIntrinsicOpDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_IntrinsicOpDecoration
- };
- IR_LEAF_ISA(IntrinsicOpDecoration)
+ FIDDLE(leafInst())
IRIntLit* getIntrinsicOpOperand() { return cast<IRIntLit>(getOperand(0)); }
IROp getIntrinsicOp() { return (IROp)getIntrinsicOpOperand()->getValue(); }
};
+FIDDLE()
struct IRAlignedAddressDecoration : IRDecoration
{
- IR_LEAF_ISA(AlignedAddressDecoration)
+ FIDDLE(leafInst())
IRInst* getAlignment() { return getOperand(0); }
};
+FIDDLE()
struct IRGLSLOuterArrayDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_GLSLOuterArrayDecoration
- };
- IR_LEAF_ISA(GLSLOuterArrayDecoration)
+ FIDDLE(leafInst())
IRStringLit* getOuterArrayNameOperand() { return cast<IRStringLit>(getOperand(0)); }
@@ -210,13 +195,10 @@ enum class IRTargetBuiltinVarName
SpvBaseVertex,
};
+FIDDLE()
struct IRInterpolationModeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_InterpolationModeDecoration
- };
- IR_LEAF_ISA(InterpolationModeDecoration)
+ FIDDLE(leafInst())
IRConstant* getModeOperand() { return cast<IRConstant>(getOperand(0)); }
@@ -227,13 +209,10 @@ struct IRInterpolationModeDecoration : IRDecoration
/// in conjunction with the given instruction. Back-end
/// code generation may use this to help derive symbol
/// names, emit debug information, etc.
+FIDDLE()
struct IRNameHintDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_NameHintDecoration
- };
- IR_LEAF_ISA(NameHintDecoration)
+ FIDDLE(leafInst())
IRStringLit* getNameOperand() { return cast<IRStringLit>(getOperand(0)); }
@@ -241,13 +220,10 @@ struct IRNameHintDecoration : IRDecoration
};
/// A decoration on a RTTIObject providing type size information.
+FIDDLE()
struct IRRTTITypeSizeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_RTTITypeSizeDecoration
- };
- IR_LEAF_ISA(RTTITypeSizeDecoration)
+ FIDDLE(leafInst())
IRIntLit* getTypeSizeOperand() { return cast<IRIntLit>(getOperand(0)); }
IRIntegerValue getTypeSize() { return getTypeSizeOperand()->getValue(); }
@@ -255,54 +231,39 @@ struct IRRTTITypeSizeDecoration : IRDecoration
/// A decoration on `IRInterfaceType` that marks the size of `AnyValue` that should
/// be used to represent a polymorphic value of the interface.
+FIDDLE()
struct IRAnyValueSizeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_AnyValueSizeDecoration
- };
- IR_LEAF_ISA(AnyValueSizeDecoration)
+ FIDDLE(leafInst())
IRIntLit* getSizeOperand() { return cast<IRIntLit>(getOperand(0)); }
IRIntegerValue getSize() { return getSizeOperand()->getValue(); }
};
+FIDDLE()
struct IRDispatchFuncDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_DispatchFuncDecoration
- };
- IR_LEAF_ISA(DispatchFuncDecoration)
+ FIDDLE(leafInst())
IRInst* getFunc() { return getOperand(0); }
};
+FIDDLE()
struct IRSpecializeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_SpecializeDecoration
- };
- IR_LEAF_ISA(SpecializeDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRComInterfaceDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_ComInterfaceDecoration
- };
- IR_LEAF_ISA(ComInterfaceDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRCOMWitnessDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_COMWitnessDecoration
- };
- IR_LEAF_ISA(COMWitnessDecoration)
+ FIDDLE(leafInst())
IRInst* getWitnessTable() { return getOperand(0); }
};
@@ -310,78 +271,30 @@ struct IRCOMWitnessDecoration : IRDecoration
/// A decoration on `IRParam`s that represent generic parameters,
/// marking the interface type that the generic parameter conforms to.
/// A generic parameter can have more than one `IRTypeConstraintDecoration`s
+FIDDLE()
struct IRTypeConstraintDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_TypeConstraintDecoration
- };
- IR_LEAF_ISA(TypeConstraintDecoration)
+ FIDDLE(leafInst())
IRInst* getConstraintType() { return getOperand(0); }
};
-#define IR_SIMPLE_DECORATION(NAME) \
- struct IR##NAME : IRDecoration \
- { \
- enum \
- { \
- kOp = kIROp_##NAME \
- }; \
- IR_LEAF_ISA(NAME) \
- }; \
- /**/
-
bool isSimpleDecoration(IROp op);
-/// A decoration that indicates that a variable represents
-/// a vulkan ray payload, and should have a location assigned
-/// to it.
-IR_SIMPLE_DECORATION(VulkanRayPayloadDecoration)
-IR_SIMPLE_DECORATION(VulkanRayPayloadInDecoration)
-
-/// A decoration that indicates that a variable represents
-/// a vulkan callable shader payload, and should have a location assigned
-/// to it.
-IR_SIMPLE_DECORATION(VulkanCallablePayloadDecoration)
-IR_SIMPLE_DECORATION(VulkanCallablePayloadInDecoration)
-
-/// A decoration that indicates that a variable represents
-/// vulkan hit attributes, and should have a location assigned
-/// to it.
-IR_SIMPLE_DECORATION(VulkanHitAttributesDecoration)
-
-/// A decoration that indicates that a variable represents
-/// vulkan hit object attributes, and should have a location assigned
-/// to it.
-IR_SIMPLE_DECORATION(VulkanHitObjectAttributesDecoration)
-
-IR_SIMPLE_DECORATION(PerVertexDecoration)
-
-IR_SIMPLE_DECORATION(SPIRVBlockDecoration)
-
-IR_SIMPLE_DECORATION(DefaultValueDecoration)
-
+FIDDLE()
struct IRRequireGLSLVersionDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_RequireGLSLVersionDecoration
- };
- IR_LEAF_ISA(RequireGLSLVersionDecoration)
+ FIDDLE(leafInst())
IRConstant* getLanguageVersionOperand() { return cast<IRConstant>(getOperand(0)); }
Int getLanguageVersion() { return Int(getLanguageVersionOperand()->value.intVal); }
};
+FIDDLE()
struct IRSPIRVNonUniformResourceDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_SPIRVNonUniformResourceDecoration
- };
- IR_LEAF_ISA(SPIRVNonUniformResourceDecoration)
+ FIDDLE(leafInst())
IRConstant* getSPIRVNonUniformResourceOperand() { return cast<IRConstant>(getOperand(0)); }
IntegerLiteralValue getSPIRVNonUniformResource()
@@ -390,13 +303,10 @@ struct IRSPIRVNonUniformResourceDecoration : IRDecoration
}
};
+FIDDLE()
struct IRRequireSPIRVVersionDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_RequireSPIRVVersionDecoration
- };
- IR_LEAF_ISA(RequireGLSLVersionDecoration)
+ FIDDLE(leafInst())
IRConstant* getSPIRVVersionOperand() { return cast<IRConstant>(getOperand(0)); }
SemanticVersion getSPIRVVersion()
@@ -405,25 +315,19 @@ struct IRRequireSPIRVVersionDecoration : IRDecoration
}
};
+FIDDLE()
struct IRRequireCapabilityAtomDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_RequireCapabilityAtomDecoration
- };
- IR_LEAF_ISA(RequireCapabilityAtomDecoration)
+ FIDDLE(leafInst())
IRConstant* getCapabilityAtomOperand() { return cast<IRConstant>(getOperand(0)); }
CapabilityName getAtom() { return (CapabilityName)getCapabilityAtomOperand()->value.intVal; }
};
+FIDDLE()
struct IRRequireCUDASMVersionDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_RequireCUDASMVersionDecoration
- };
- IR_LEAF_ISA(RequireCUDASMVersionDecoration)
+ FIDDLE(leafInst())
IRConstant* getCUDASMVersionOperand() { return cast<IRConstant>(getOperand(0)); }
SemanticVersion getCUDASMVersion()
@@ -432,111 +336,78 @@ struct IRRequireCUDASMVersionDecoration : IRDecoration
}
};
+FIDDLE()
struct IRRequireGLSLExtensionDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_RequireGLSLExtensionDecoration
- };
- IR_LEAF_ISA(RequireGLSLExtensionDecoration)
+ FIDDLE(leafInst())
IRStringLit* getExtensionNameOperand() { return cast<IRStringLit>(getOperand(0)); }
UnownedStringSlice getExtensionName() { return getExtensionNameOperand()->getStringSlice(); }
};
+FIDDLE()
struct IRRequireWGSLExtensionDecoration : IRDecoration
{
- IR_LEAF_ISA(RequireWGSLExtensionDecoration)
+ FIDDLE(leafInst())
IRStringLit* getExtensionNameOperand() { return cast<IRStringLit>(getOperand(0)); }
UnownedStringSlice getExtensionName() { return getExtensionNameOperand()->getStringSlice(); }
};
+FIDDLE()
struct IRMemoryQualifierSetDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_MemoryQualifierSetDecoration
- };
- IR_LEAF_ISA(MemoryQualifierSetDecoration)
+ FIDDLE(leafInst())
IRIntegerValue getMemoryQualifierBit() { return cast<IRIntLit>(getOperand(0))->getValue(); }
};
-IR_SIMPLE_DECORATION(HasExplicitHLSLBindingDecoration)
-IR_SIMPLE_DECORATION(ReadNoneDecoration)
-IR_SIMPLE_DECORATION(NoSideEffectDecoration)
-IR_SIMPLE_DECORATION(EarlyDepthStencilDecoration)
-IR_SIMPLE_DECORATION(PreciseDecoration)
-IR_SIMPLE_DECORATION(PublicDecoration)
-IR_SIMPLE_DECORATION(HLSLExportDecoration)
-IR_SIMPLE_DECORATION(KeepAliveDecoration)
-IR_SIMPLE_DECORATION(RequiresNVAPIDecoration)
-IR_SIMPLE_DECORATION(NoInlineDecoration)
-IR_SIMPLE_DECORATION(NoRefInlineDecoration)
-IR_SIMPLE_DECORATION(DerivativeGroupQuadDecoration)
-IR_SIMPLE_DECORATION(DerivativeGroupLinearDecoration)
-IR_SIMPLE_DECORATION(AlwaysFoldIntoUseSiteDecoration)
-IR_SIMPLE_DECORATION(StaticRequirementDecoration)
-IR_SIMPLE_DECORATION(NonCopyableTypeDecoration)
-IR_SIMPLE_DECORATION(HLSLMeshPayloadDecoration)
-IR_SIMPLE_DECORATION(GlobalInputDecoration)
-IR_SIMPLE_DECORATION(GlobalOutputDecoration)
-IR_SIMPLE_DECORATION(DownstreamModuleExportDecoration)
-IR_SIMPLE_DECORATION(DownstreamModuleImportDecoration)
-IR_SIMPLE_DECORATION(MaximallyReconvergesDecoration)
-IR_SIMPLE_DECORATION(QuadDerivativesDecoration)
-IR_SIMPLE_DECORATION(RequireFullQuadsDecoration)
-IR_SIMPLE_DECORATION(TempCallArgVarDecoration)
-
+FIDDLE()
struct IRAvailableInDownstreamIRDecoration : IRDecoration
{
- IR_LEAF_ISA(AvailableInDownstreamIRDecoration)
+ FIDDLE(leafInst())
CodeGenTarget getTarget()
{
return static_cast<CodeGenTarget>(cast<IRIntLit>(getOperand(0))->getValue());
}
};
+FIDDLE()
struct IRGLSLLocationDecoration : IRDecoration
{
- IR_LEAF_ISA(GLSLLocationDecoration)
+ FIDDLE(leafInst())
IRIntLit* getLocation() { return cast<IRIntLit>(getOperand(0)); }
};
+FIDDLE()
struct IRGLSLOffsetDecoration : IRDecoration
{
- IR_LEAF_ISA(GLSLOffsetDecoration)
+ FIDDLE(leafInst())
IRIntLit* getOffset() { return cast<IRIntLit>(getOperand(0)); }
};
+FIDDLE()
struct IRVkStructOffsetDecoration : IRDecoration
{
- IR_LEAF_ISA(VkStructOffsetDecoration)
+ FIDDLE(leafInst())
IRIntLit* getOffset() { return cast<IRIntLit>(getOperand(0)); }
};
+FIDDLE()
struct IRNVAPIMagicDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_NVAPIMagicDecoration
- };
- IR_LEAF_ISA(NVAPIMagicDecoration)
+ FIDDLE(leafInst())
IRStringLit* getNameOperand() { return cast<IRStringLit>(getOperand(0)); }
UnownedStringSlice getName() { return getNameOperand()->getStringSlice(); }
};
+FIDDLE()
struct IRNVAPISlotDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_NVAPISlotDecoration
- };
- IR_LEAF_ISA(NVAPISlotDecoration)
+ FIDDLE(leafInst())
IRStringLit* getRegisterNameOperand() { return cast<IRStringLit>(getOperand(0)); }
UnownedStringSlice getRegisterName() { return getRegisterNameOperand()->getStringSlice(); }
@@ -545,94 +416,70 @@ struct IRNVAPISlotDecoration : IRDecoration
UnownedStringSlice getSpaceName() { return getSpaceNameOperand()->getStringSlice(); }
};
+FIDDLE()
struct IRMaxTessFactorDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_MaxTessFactorDecoration
- };
- IR_LEAF_ISA(MaxTessFactorDecoration)
+ FIDDLE(leafInst())
IRFloatLit* getMaxTessFactor() { return cast<IRFloatLit>(getOperand(0)); }
};
+FIDDLE()
struct IROutputControlPointsDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_OutputControlPointsDecoration
- };
- IR_LEAF_ISA(OutputControlPointsDecoration)
+ FIDDLE(leafInst())
IRIntLit* getControlPointCount() { return cast<IRIntLit>(getOperand(0)); }
};
// This is used for mesh shaders too
+FIDDLE()
struct IROutputTopologyDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_OutputTopologyDecoration
- };
- IR_LEAF_ISA(OutputTopologyDecoration)
+ FIDDLE(leafInst())
IRStringLit* getTopology() { return cast<IRStringLit>(getOperand(0)); }
IRIntegerValue getTopologyType() { return cast<IRIntLit>(getOperand(1))->getValue(); }
};
+FIDDLE()
struct IRPartitioningDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_PartitioningDecoration
- };
- IR_LEAF_ISA(PartitioningDecoration)
+ FIDDLE(leafInst())
IRStringLit* getPartitioning() { return cast<IRStringLit>(getOperand(0)); }
};
+FIDDLE()
struct IRDomainDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_DomainDecoration
- };
- IR_LEAF_ISA(DomainDecoration)
+ FIDDLE(leafInst())
IRStringLit* getDomain() { return cast<IRStringLit>(getOperand(0)); }
};
+FIDDLE()
struct IRMaxVertexCountDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_MaxVertexCountDecoration
- };
- IR_LEAF_ISA(MaxVertexCountDecoration)
+ FIDDLE(leafInst())
IRIntLit* getCount() { return cast<IRIntLit>(getOperand(0)); }
};
+FIDDLE()
struct IRInstanceDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_InstanceDecoration
- };
- IR_LEAF_ISA(InstanceDecoration)
+ FIDDLE(leafInst())
IRIntLit* getCount() { return cast<IRIntLit>(getOperand(0)); }
};
struct IRGlobalParam;
+FIDDLE()
struct IRNumThreadsDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_NumThreadsDecoration
- };
- IR_LEAF_ISA(NumThreadsDecoration)
+ FIDDLE(leafInst())
IRIntLit* getX() { return as<IRIntLit>(getOperand(0)); }
IRIntLit* getY() { return as<IRIntLit>(getOperand(1)); }
@@ -643,46 +490,33 @@ struct IRNumThreadsDecoration : IRDecoration
IRGlobalParam* getZSpecConst() { return as<IRGlobalParam>(getOperand(2)); }
};
+FIDDLE()
struct IRFpDenormalPreserveDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_FpDenormalPreserveDecoration
- };
- IR_LEAF_ISA(FpDenormalPreserveDecoration)
-
+ FIDDLE(leafInst())
IRIntLit* getWidth() { return cast<IRIntLit>(getOperand(0)); }
};
+FIDDLE()
struct IRFpDenormalFlushToZeroDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_FpDenormalFlushToZeroDecoration
- };
- IR_LEAF_ISA(FpDenormalFlushToZeroDecoration)
+ FIDDLE(leafInst())
IRIntLit* getWidth() { return cast<IRIntLit>(getOperand(0)); }
};
+FIDDLE()
struct IRWaveSizeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_WaveSizeDecoration
- };
- IR_LEAF_ISA(WaveSizeDecoration)
+ FIDDLE(leafInst())
IRIntLit* getNumLanes() { return cast<IRIntLit>(getOperand(0)); }
};
+FIDDLE()
struct IREntryPointDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_EntryPointDecoration
- };
- IR_LEAF_ISA(EntryPointDecoration)
+ FIDDLE(leafInst())
IRIntLit* getProfileInst() { return cast<IRIntLit>(getOperand(0)); }
Profile getProfile() { return Profile(Profile::RawVal(getIntVal(getProfileInst()))); }
@@ -692,55 +526,38 @@ struct IREntryPointDecoration : IRDecoration
void setName(IRStringLit* name) { setOperand(1, name); }
};
-IR_SIMPLE_DECORATION(CudaHostDecoration)
-IR_SIMPLE_DECORATION(CudaKernelDecoration)
-
+FIDDLE()
struct IRCudaKernelForwardDerivativeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_CudaKernelForwardDerivativeDecoration
- };
- IR_LEAF_ISA(CudaKernelForwardDerivativeDecoration)
+ FIDDLE(leafInst())
IRInst* getForwardDerivativeFunc() { return getOperand(0); }
};
+FIDDLE()
struct IRCudaKernelBackwardDerivativeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_CudaKernelBackwardDerivativeDecoration
- };
- IR_LEAF_ISA(CudaKernelBackwardDerivativeDecoration)
+ FIDDLE(leafInst())
IRInst* getBackwardDerivativeFunc() { return getOperand(0); }
};
+FIDDLE()
struct IRGeometryInputPrimitiveTypeDecoration : IRDecoration
{
- IR_PARENT_ISA(GeometryInputPrimitiveTypeDecoration)
+ FIDDLE(baseInst())
};
-IR_SIMPLE_DECORATION(PointInputPrimitiveTypeDecoration)
-IR_SIMPLE_DECORATION(LineInputPrimitiveTypeDecoration)
-IR_SIMPLE_DECORATION(TriangleInputPrimitiveTypeDecoration)
-IR_SIMPLE_DECORATION(LineAdjInputPrimitiveTypeDecoration)
-IR_SIMPLE_DECORATION(TriangleAdjInputPrimitiveTypeDecoration)
-
/// This is a bit of a hack. The problem is that when GLSL legalization takes place
/// the parameters from the entry point are globalized *and* potentially split
/// So even if we did copy a suitable decoration onto the globalized parameters,
/// it would potentially output multiple times without extra logic.
/// Using this decoration we can copy the StreamOut type to the entry point, and then
/// emit as part of entry point attribute emitting.
+FIDDLE()
struct IRStreamOutputTypeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_StreamOutputTypeDecoration
- };
- IR_LEAF_ISA(StreamOutputTypeDecoration)
+ FIDDLE(leafInst())
IRHLSLStreamOutputType* getStreamType() { return cast<IRHLSLStreamOutputType>(getOperand(0)); }
};
@@ -750,9 +567,10 @@ struct IRStreamOutputTypeDecoration : IRDecoration
/// or will have a definition imported from another module.
/// In either case, it requires a mangled name to use when
/// matching imports and exports.
+FIDDLE()
struct IRLinkageDecoration : IRDecoration
{
- IR_PARENT_ISA(LinkageDecoration)
+ FIDDLE(baseInst())
IRStringLit* getMangledNameOperand() { return cast<IRStringLit>(getOperand(0)); }
@@ -760,9 +578,10 @@ struct IRLinkageDecoration : IRDecoration
};
// Mark a global variable as a target buitlin variable.
+FIDDLE()
struct IRTargetBuiltinVarDecoration : IRDecoration
{
- IR_LEAF_ISA(TargetBuiltinVarDecoration)
+ FIDDLE(leafInst())
IRIntLit* getBuiltinVarOperand() { return cast<IRIntLit>(getOperand(0)); }
IRTargetBuiltinVarName getBuiltinVarName()
@@ -771,62 +590,44 @@ struct IRTargetBuiltinVarDecoration : IRDecoration
}
};
+FIDDLE()
struct IRUserExternDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_UserExternDecoration
- };
- IR_LEAF_ISA(UserExternDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRImportDecoration : IRLinkageDecoration
{
- enum
- {
- kOp = kIROp_ImportDecoration
- };
- IR_LEAF_ISA(ImportDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRExportDecoration : IRLinkageDecoration
{
- enum
- {
- kOp = kIROp_ExportDecoration
- };
- IR_LEAF_ISA(ExportDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRExternCppDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_ExternCppDecoration
- };
- IR_LEAF_ISA(ExternCppDecoration)
+ FIDDLE(leafInst())
IRStringLit* getNameOperand() { return cast<IRStringLit>(getOperand(0)); }
UnownedStringSlice getName() { return getNameOperand()->getStringSlice(); }
};
+FIDDLE()
struct IRExternCDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_ExternCDecoration
- };
- IR_LEAF_ISA(ExternCDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRDllImportDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_DllImportDecoration
- };
- IR_LEAF_ISA(DllImportDecoration)
+ FIDDLE(leafInst())
IRStringLit* getLibraryNameOperand() { return cast<IRStringLit>(getOperand(0)); }
UnownedStringSlice getLibraryName() { return getLibraryNameOperand()->getStringSlice(); }
@@ -835,101 +636,75 @@ struct IRDllImportDecoration : IRDecoration
UnownedStringSlice getFunctionName() { return getFunctionNameOperand()->getStringSlice(); }
};
+FIDDLE()
struct IRDllExportDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_DllExportDecoration
- };
- IR_LEAF_ISA(DllExportDecoration)
+ FIDDLE(leafInst())
IRStringLit* getFunctionNameOperand() { return cast<IRStringLit>(getOperand(0)); }
UnownedStringSlice getFunctionName() { return getFunctionNameOperand()->getStringSlice(); }
};
+FIDDLE()
struct IRTorchEntryPointDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_TorchEntryPointDecoration
- };
- IR_LEAF_ISA(TorchEntryPointDecoration)
+ FIDDLE(leafInst())
IRStringLit* getFunctionNameOperand() { return cast<IRStringLit>(getOperand(0)); }
UnownedStringSlice getFunctionName() { return getFunctionNameOperand()->getStringSlice(); }
};
+FIDDLE()
struct IRAutoPyBindCudaDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_AutoPyBindCudaDecoration
- };
- IR_LEAF_ISA(AutoPyBindCudaDecoration)
+ FIDDLE(leafInst())
IRStringLit* getFunctionNameOperand() { return cast<IRStringLit>(getOperand(0)); }
UnownedStringSlice getFunctionName() { return getFunctionNameOperand()->getStringSlice(); }
};
-IR_SIMPLE_DECORATION(AutoPyBindExportInfoDecoration)
-
+FIDDLE()
struct IRPyExportDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_PyExportDecoration
- };
- IR_LEAF_ISA(PyExportDecoration)
+ FIDDLE(leafInst())
IRStringLit* getExportNameOperand() { return cast<IRStringLit>(getOperand(0)); }
UnownedStringSlice getExportName() { return getExportNameOperand()->getStringSlice(); }
};
+FIDDLE()
struct IRKnownBuiltinDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_KnownBuiltinDecoration
- };
- IR_LEAF_ISA(KnownBuiltinDecoration)
+ FIDDLE(leafInst())
IRStringLit* getNameOperand() { return cast<IRStringLit>(getOperand(0)); }
UnownedStringSlice getName() { return getNameOperand()->getStringSlice(); }
};
+FIDDLE()
struct IREntryPointParamDecoration : IRDecoration
{
- IR_LEAF_ISA(EntryPointParamDecoration)
+ FIDDLE(leafInst())
/// Get the entry point that this parameter orignates from.
IRFunc* getEntryPoint() { return cast<IRFunc>(getOperand(0)); }
};
+FIDDLE()
struct IRFormatDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_FormatDecoration
- };
- IR_LEAF_ISA(FormatDecoration)
+ FIDDLE(leafInst())
IRConstant* getFormatOperand() { return cast<IRConstant>(getOperand(0)); }
ImageFormat getFormat() { return ImageFormat(getFormatOperand()->value.intVal); }
};
-IR_SIMPLE_DECORATION(UnsafeForceInlineEarlyDecoration)
-
-IR_SIMPLE_DECORATION(ForceInlineDecoration)
-
-IR_SIMPLE_DECORATION(ForceUnrollDecoration)
-
-IR_SIMPLE_DECORATION(PhysicalTypeDecoration)
-
+FIDDLE()
struct IRSizeAndAlignmentDecoration : IRDecoration
{
- IR_LEAF_ISA(SizeAndAlignmentDecoration)
+ FIDDLE(leafInst())
IRTypeLayoutRuleName getLayoutName()
{
@@ -942,9 +717,10 @@ struct IRSizeAndAlignmentDecoration : IRDecoration
IRIntegerValue getAlignment() { return getAlignmentOperand()->getValue(); }
};
+FIDDLE()
struct IROffsetDecoration : IRDecoration
{
- IR_LEAF_ISA(OffsetDecoration)
+ FIDDLE(leafInst())
IRTypeLayoutRuleName getLayoutName()
{
@@ -955,215 +731,158 @@ struct IROffsetDecoration : IRDecoration
IRIntegerValue getOffset() { return getOffsetOperand()->getValue(); }
};
-IR_SIMPLE_DECORATION(DynamicUniformDecoration)
-
+FIDDLE()
struct IRBuiltinDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_BuiltinDecoration
- };
- IR_LEAF_ISA(BuiltinDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRSequentialIDDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_SequentialIDDecoration
- };
- IR_LEAF_ISA(SequentialIDDecoration)
+ FIDDLE(leafInst())
IRIntLit* getSequentialIDOperand() { return cast<IRIntLit>(getOperand(0)); }
IRIntegerValue getSequentialID() { return getSequentialIDOperand()->getValue(); }
};
+FIDDLE()
struct IRResultWitnessDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_ResultWitnessDecoration
- };
- IR_LEAF_ISA(ResultWitnessDecoration)
+ FIDDLE(leafInst())
IRInst* getWitness() { return getOperand(0); }
};
+FIDDLE()
struct IRDynamicDispatchWitnessDecoration : IRDecoration
{
- IR_LEAF_ISA(DynamicDispatchWitnessDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRAutoDiffOriginalValueDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_AutoDiffOriginalValueDecoration
- };
- IR_LEAF_ISA(AutoDiffOriginalValueDecoration)
+ FIDDLE(leafInst())
IRInst* getOriginalValue() { return getOperand(0); }
};
+FIDDLE()
struct IRForwardDifferentiableDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_ForwardDifferentiableDecoration
- };
- IR_LEAF_ISA(ForwardDifferentiableDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRForwardDerivativeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_ForwardDerivativeDecoration
- };
- IR_LEAF_ISA(ForwardDerivativeDecoration)
+ FIDDLE(leafInst())
IRInst* getForwardDerivativeFunc() { return getOperand(0); }
};
+FIDDLE()
struct IRPrimalSubstituteDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_PrimalSubstituteDecoration
- };
- IR_LEAF_ISA(PrimalSubstituteDecoration)
+ FIDDLE(leafInst())
IRInst* getPrimalSubstituteFunc() { return getOperand(0); }
};
+FIDDLE()
struct IRBackwardDerivativeIntermediateTypeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_BackwardDerivativeIntermediateTypeDecoration
- };
- IR_LEAF_ISA(BackwardDerivativeIntermediateTypeDecoration)
+ FIDDLE(leafInst())
IRInst* getBackwardDerivativeIntermediateType() { return getOperand(0); }
};
+FIDDLE()
struct IRBackwardDerivativePrimalDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_BackwardDerivativePrimalDecoration
- };
- IR_LEAF_ISA(BackwardDerivativePrimalDecoration)
+ FIDDLE(leafInst())
IRInst* getBackwardDerivativePrimalFunc() { return getOperand(0); }
};
// Used to associate the restore context var to use in a call to splitted backward propgate
// function.
+FIDDLE()
struct IRBackwardDerivativePrimalContextDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_BackwardDerivativePrimalContextDecoration
- };
- IR_LEAF_ISA(BackwardDerivativePrimalContextDecoration)
+ FIDDLE(leafInst())
IRUse primalContextVar;
IRInst* getBackwardDerivativePrimalContextVar() { return getOperand(0); }
};
+FIDDLE()
struct IRBackwardDerivativePrimalReturnDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_BackwardDerivativePrimalReturnDecoration
- };
- IR_LEAF_ISA(BackwardDerivativePrimalReturnDecoration)
+ FIDDLE(leafInst())
IRInst* getBackwardDerivativePrimalReturnValue() { return getOperand(0); }
};
+FIDDLE()
struct IRBackwardDerivativePropagateDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_BackwardDerivativePropagateDecoration
- };
- IR_LEAF_ISA(BackwardDerivativePropagateDecoration)
+ FIDDLE(leafInst())
IRInst* getBackwardDerivativePropagateFunc() { return getOperand(0); }
};
+FIDDLE()
struct IRBackwardDerivativeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_BackwardDerivativeDecoration
- };
- IR_LEAF_ISA(BackwardDerivativeDecoration)
+ FIDDLE(leafInst())
IRInst* getBackwardDerivativeFunc() { return getOperand(0); }
};
+FIDDLE()
struct IRCheckpointHintDecoration : public IRDecoration
{
- IR_PARENT_ISA(CheckpointHintDecoration)
+ FIDDLE(baseInst())
};
+FIDDLE()
struct IRPreferRecomputeDecoration : IRCheckpointHintDecoration
{
- enum
- {
- kOp = kIROp_PreferRecomputeDecoration
- };
- IR_LEAF_ISA(PreferRecomputeDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRPreferCheckpointDecoration : IRCheckpointHintDecoration
{
- enum
- {
- kOp = kIROp_PreferCheckpointDecoration
- };
- IR_LEAF_ISA(PreferCheckpointDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRCheckpointIntermediateDecoration : IRCheckpointHintDecoration
{
- enum
- {
- kOp = kIROp_CheckpointIntermediateDecoration
- };
- IR_LEAF_ISA(CheckpointIntermediateDecoration)
+ FIDDLE(leafInst())
IRInst* getSourceFunction() { return getOperand(0); }
};
+FIDDLE()
struct IRLoopCounterDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_LoopCounterDecoration
- };
- IR_LEAF_ISA(LoopCounterDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRLoopCounterUpdateDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_LoopCounterUpdateDecoration
- };
- IR_LEAF_ISA(LoopCounterUpdateDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRLoopExitPrimalValueDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_LoopExitPrimalValueDecoration
- };
- IR_LEAF_ISA(LoopExitPrimalValueDecoration)
+ FIDDLE(leafInst())
IRUse target;
IRUse exitVal;
@@ -1171,193 +890,143 @@ struct IRLoopExitPrimalValueDecoration : IRDecoration
IRInst* getLoopExitValInst() { return getOperand(1); }
};
+FIDDLE()
struct IRAutodiffInstDecoration : IRDecoration
{
- IR_PARENT_ISA(AutodiffInstDecoration)
+ FIDDLE(baseInst())
};
+FIDDLE()
struct IRDifferentialInstDecoration : IRAutodiffInstDecoration
{
- enum
- {
- kOp = kIROp_DifferentialInstDecoration
- };
+ FIDDLE(leafInst())
IRUse primalType;
- IR_LEAF_ISA(DifferentialInstDecoration)
IRType* getPrimalType() { return (IRType*)(getOperand(0)); }
IRInst* getPrimalInst() { return getOperand(1); }
IRInst* getWitness() { return getOperand(2); }
};
+FIDDLE()
struct IRPrimalInstDecoration : IRAutodiffInstDecoration
{
- enum
- {
- kOp = kIROp_PrimalInstDecoration
- };
-
- IR_LEAF_ISA(PrimalInstDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRMixedDifferentialInstDecoration : IRAutodiffInstDecoration
{
- enum
- {
- kOp = kIROp_MixedDifferentialInstDecoration
- };
+ FIDDLE(leafInst())
IRUse pairType;
- IR_LEAF_ISA(MixedDifferentialInstDecoration)
IRType* getPairType() { return (IRType*)(getOperand(0)); }
};
+FIDDLE()
struct IRRecomputeBlockDecoration : IRAutodiffInstDecoration
{
- enum
- {
- kOp = kIROp_RecomputeBlockDecoration
- };
-
- IR_LEAF_ISA(RecomputeBlockDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRPrimalValueStructKeyDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_PrimalValueStructKeyDecoration
- };
+ FIDDLE(leafInst())
- IR_LEAF_ISA(PrimalValueStructKeyDecoration)
IRStructKey* getStructKey() { return as<IRStructKey>(getOperand(0)); }
};
+FIDDLE()
struct IRPrimalElementTypeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_PrimalElementTypeDecoration
- };
+ FIDDLE(leafInst())
- IR_LEAF_ISA(PrimalElementTypeDecoration)
IRInst* getPrimalElementType() { return getOperand(0); }
};
+FIDDLE()
struct IRIntermediateContextFieldDifferentialTypeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_IntermediateContextFieldDifferentialTypeDecoration
- };
+ FIDDLE(leafInst())
- IR_LEAF_ISA(IntermediateContextFieldDifferentialTypeDecoration)
IRInst* getDifferentialWitness() { return getOperand(0); }
};
+FIDDLE()
struct IRBackwardDifferentiableDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_BackwardDifferentiableDecoration
- };
- IR_LEAF_ISA(BackwardDifferentiableDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRUserDefinedBackwardDerivativeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_UserDefinedBackwardDerivativeDecoration
- };
- IR_LEAF_ISA(UserDefinedBackwardDerivativeDecoration)
+ FIDDLE(leafInst())
IRInst* getBackwardDerivativeFunc() { return getOperand(0); }
};
+FIDDLE()
struct IRTreatAsDifferentiableDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_TreatAsDifferentiableDecoration
- };
- IR_LEAF_ISA(TreatAsDifferentiableDecoration)
+ FIDDLE(leafInst())
};
// Mark a call as explicitly calling a differentiable function.
+FIDDLE()
struct IRDifferentiableCallDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_DifferentiableCallDecoration
- };
- IR_LEAF_ISA(DifferentiableCallDecoration)
+ FIDDLE(leafInst())
};
// Mark a type as being eligible for trimming if necessary. If
// any fields don't have any effective loads from them, they can be
// removed.
//
+FIDDLE()
struct IROptimizableTypeDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_OptimizableTypeDecoration
- };
- IR_LEAF_ISA(OptimizableTypeDecoration)
+ FIDDLE(leafInst())
};
// Informs the DCE pass to ignore side-effects on this call for
// the purposes of dead code elimination, even if the call does have
// side-effects.
//
+FIDDLE()
struct IRIgnoreSideEffectsDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_IgnoreSideEffectsDecoration
- };
- IR_LEAF_ISA(IgnoreSideEffectsDecoration)
+ FIDDLE(leafInst())
};
// Treat a call to a non-differentiable function as a differentiable call.
+FIDDLE()
struct IRTreatCallAsDifferentiableDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_TreatCallAsDifferentiableDecoration
- };
- IR_LEAF_ISA(TreatCallAsDifferentiableDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRDerivativeMemberDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_DerivativeMemberDecoration
- };
- IR_LEAF_ISA(DerivativeMemberDecoration)
+ FIDDLE(leafInst())
IRInst* getDerivativeMemberStructKey() { return getOperand(0); }
};
// An instruction that replaces the function symbol
// with it's derivative function.
+FIDDLE()
struct IRForwardDifferentiate : IRInst
{
- enum
- {
- kOp = kIROp_ForwardDifferentiate
- };
+ FIDDLE(leafInst())
// The base function for the call.
IRUse base;
IRInst* getBaseFn() { return getOperand(0); }
-
- IR_LEAF_ISA(ForwardDifferentiate)
};
// An instruction that replaces the function symbol
@@ -1366,94 +1035,68 @@ struct IRForwardDifferentiate : IRInst
// of backward derivative computation. It performs the primal
// computations and returns the intermediates that will be used
// by the actual backward derivative function.
+FIDDLE()
struct IRBackwardDifferentiatePrimal : IRInst
{
- enum
- {
- kOp = kIROp_BackwardDifferentiatePrimal
- };
+ FIDDLE(leafInst())
// The base function for the call.
IRUse base;
IRInst* getBaseFn() { return getOperand(0); }
-
- IR_LEAF_ISA(BackwardDifferentiatePrimal)
};
// An instruction that replaces the function symbol with its backward derivative propagate function.
// A backward derivative propagate function is the second pass of backward derivative computation.
// It uses the intermediates computed in the bacward derivative primal function to perform the
// actual backward derivative propagation.
+FIDDLE()
struct IRBackwardDifferentiatePropagate : IRInst
{
- enum
- {
- kOp = kIROp_BackwardDifferentiatePropagate
- };
+ FIDDLE(leafInst())
// The base function for the call.
IRUse base;
IRInst* getBaseFn() { return getOperand(0); }
-
- IR_LEAF_ISA(BackwardDifferentiatePropagate)
};
// An instruction that replaces the function symbol with its backward derivative function.
// A backward derivative function is a concept that combines both passes of backward derivative
// computation. This inst should only be produced by lower-to-ir, and will be replaced with calls to
// the primal function followed by the propagate function in the auto-diff pass.
+FIDDLE()
struct IRBackwardDifferentiate : IRInst
{
- enum
- {
- kOp = kIROp_BackwardDifferentiate
- };
+ FIDDLE(leafInst())
// The base function for the call.
IRUse base;
IRInst* getBaseFn() { return getOperand(0); }
-
- IR_LEAF_ISA(BackwardDifferentiate)
};
+FIDDLE()
struct IRIsDifferentialNull : IRInst
{
- enum
- {
- kOp = kIROp_IsDifferentialNull
- };
+ FIDDLE(leafInst())
IRInst* getBase() { return getOperand(0); }
-
- IR_LEAF_ISA(IsDifferentialNull)
};
// Retrieves the primal substitution function for the given function.
+FIDDLE()
struct IRPrimalSubstitute : IRInst
{
- enum
- {
- kOp = kIROp_PrimalSubstitute
- };
+ FIDDLE(leafInst())
IRInst* getBaseFn() { return getOperand(0); }
-
- IR_LEAF_ISA(PrimalSubstitute)
};
+FIDDLE()
struct IRDifferentiableTypeAnnotation : IRInst
{
- enum
- {
- kOp = kIROp_DifferentiableTypeAnnotation
- };
+ FIDDLE(leafInst())
IRInst* getBaseType() { return getOperand(0); }
IRInst* getWitness() { return getOperand(1); }
-
- IR_LEAF_ISA(DifferentiableTypeAnnotation)
};
+FIDDLE()
struct IRDispatchKernel : IRInst
{
- enum
- {
- kOp = kIROp_DispatchKernel
- };
+ FIDDLE(leafInst())
IRInst* getBaseFn() { return getOperand(0); }
IRInst* getThreadGroupSize() { return getOperand(1); }
IRInst* getDispatchSize() { return getOperand(2); }
@@ -1463,38 +1106,36 @@ struct IRDispatchKernel : IRInst
{
return IROperandList<IRInst>(getOperands() + 3, getOperands() + getOperandCount());
}
-
- IR_LEAF_ISA(DispatchKernel)
};
+FIDDLE()
struct IRTorchTensorGetView : IRInst
{
- enum
- {
- kOp = kIROp_TorchTensorGetView
- };
- IR_LEAF_ISA(TorchTensorGetView)
+ FIDDLE(leafInst())
};
// Dictionary item mapping a type with a corresponding
// IDifferentiable witness table
//
+FIDDLE()
struct IRDifferentiableTypeDictionaryItem : IRInst
{
- IR_LEAF_ISA(DifferentiableTypeDictionaryItem)
+ FIDDLE(leafInst())
IRInst* getConcreteType() { return getOperand(0); }
IRInst* getWitness() { return getOperand(1); }
};
+FIDDLE()
struct IRDifferentiableTypeDictionaryDecoration : IRDecoration
{
- IR_LEAF_ISA(DifferentiableTypeDictionaryDecoration)
+ FIDDLE(leafInst())
};
-struct IRFloatingModeOverrideDecoration : IRDecoration
+FIDDLE()
+struct IRFloatingPointModeOverrideDecoration : IRDecoration
{
- IR_LEAF_ISA(FloatingPointModeOverrideDecoration)
+ FIDDLE(leafInst())
FloatingPointMode getFloatingPointMode()
{
@@ -1505,8 +1146,10 @@ struct IRFloatingModeOverrideDecoration : IRDecoration
// An instruction that specializes another IR value
// (representing a generic) to a particular set of generic arguments
// (instructions representing types, witness tables, etc.)
+FIDDLE()
struct IRSpecialize : IRInst
{
+ FIDDLE(leafInst())
// The "base" for the call is the generic to be specialized
IRUse base;
IRInst* getBase() { return getOperand(0); }
@@ -1515,38 +1158,38 @@ struct IRSpecialize : IRInst
UInt getArgCount() { return getOperandCount() - 1; }
IRInst* getArg(UInt index) { return getOperand(index + 1); }
IRUse* getArgOperand(Index i) { return getOperands() + 1 + i; }
-
- IR_LEAF_ISA(Specialize)
};
// An instruction that looks up the implementation
// of an interface operation identified by `requirementDeclRef`
// in the witness table `witnessTable` which should
// hold the conformance information for a specific type.
+FIDDLE()
struct IRLookupWitnessMethod : IRInst
{
+ FIDDLE(leafInst())
IRUse witnessTable;
IRUse requirementKey;
IRInst* getWitnessTable() { return witnessTable.get(); }
IRInst* getRequirementKey() { return requirementKey.get(); }
-
- IR_LEAF_ISA(LookupWitness)
};
// Returns the sequential ID of an RTTI object.
+FIDDLE()
struct IRGetSequentialID : IRInst
{
- IR_LEAF_ISA(GetSequentialID)
+ FIDDLE(leafInst())
IRInst* getRTTIOperand() { return getOperand(0); }
};
/// Allocates space from local stack.
///
+FIDDLE()
struct IRAlloca : IRInst
{
- IR_LEAF_ISA(Alloca)
+ FIDDLE(leafInst())
IRInst* getAllocSize() { return getOperand(0); }
};
@@ -1555,32 +1198,36 @@ struct IRAlloca : IRInst
/// on `value` can be emitted as local insts instead of global insts, as required by targets (e.g.
/// spirv) that doesn't allow the dependent computation in the global scope.
///
+FIDDLE()
struct IRGlobalValueRef : IRInst
{
- IR_LEAF_ISA(GlobalValueRef)
+ FIDDLE(leafInst())
IRInst* getValue() { return getOperand(0); }
};
/// Packs a value into an `AnyValue`.
/// Return type is `IRAnyValueType`.
+FIDDLE()
struct IRPackAnyValue : IRInst
{
- IR_LEAF_ISA(PackAnyValue)
+ FIDDLE(leafInst())
IRInst* getValue() { return getOperand(0); }
};
/// Unpacks a `AnyValue` value into a concrete type.
/// Operand must have `IRAnyValueType`.
+FIDDLE()
struct IRUnpackAnyValue : IRInst
{
- IR_LEAF_ISA(UnpackAnyValue)
+ FIDDLE(leafInst())
IRInst* getValue() { return getOperand(0); }
};
+FIDDLE()
struct IRBitFieldAccessorDecoration : IRDecoration
{
- IR_LEAF_ISA(BitFieldAccessorDecoration);
+ FIDDLE(leafInst())
IRStructKey* getBackingMemberKey() { return cast<IRStructKey>(getOperand(0)); }
IRIntegerValue getFieldWidth() { return as<IRIntLit>(getOperand(1))->getValue(); }
IRIntegerValue getFieldOffset() { return as<IRIntLit>(getOperand(2))->getValue(); }
@@ -1597,9 +1244,10 @@ struct IRBitFieldAccessorDecoration : IRDecoration
/// case where some amount of "layout" information can't just come
/// in via the `TypeLayout` part of things.
///
+FIDDLE()
struct IRSemanticDecoration : public IRDecoration
{
- IR_LEAF_ISA(SemanticDecoration)
+ FIDDLE(leafInst())
IRStringLit* getSemanticNameOperand() { return cast<IRStringLit>(getOperand(0)); }
UnownedStringSlice getSemanticName() { return getSemanticNameOperand()->getStringSlice(); }
@@ -1608,143 +1256,147 @@ struct IRSemanticDecoration : public IRDecoration
int getSemanticIndex() { return int(getIntVal(getSemanticIndexOperand())); }
};
-struct IRConstructorDecorartion : IRDecoration
+FIDDLE()
+struct IRConstructorDecoration : IRDecoration
{
- IR_LEAF_ISA(ConstructorDecoration)
+ FIDDLE(leafInst())
bool getSynthesizedStatus() { return cast<IRBoolLit>(getOperand(0))->getValue(); }
};
-IR_SIMPLE_DECORATION(MethodDecoration)
-
+FIDDLE()
struct IRPackOffsetDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_PackOffsetDecoration
- };
- IR_LEAF_ISA(PackOffsetDecoration)
+ FIDDLE(leafInst())
IRIntLit* getRegisterOffset() { return cast<IRIntLit>(getOperand(0)); }
IRIntLit* getComponentOffset() { return cast<IRIntLit>(getOperand(1)); }
};
+FIDDLE()
struct IRUserTypeNameDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_UserTypeNameDecoration
- };
- IR_LEAF_ISA(UserTypeNameDecoration)
+ FIDDLE(leafInst())
IRStringLit* getUserTypeName() { return cast<IRStringLit>(getOperand(0)); }
};
+FIDDLE()
struct IRCounterBufferDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_CounterBufferDecoration
- };
- IR_LEAF_ISA(CounterBufferDecoration)
+ FIDDLE(leafInst())
IRInst* getCounterBuffer() { return getOperand(0); }
};
+FIDDLE()
struct IRStageAccessDecoration : public IRDecoration
{
- IR_PARENT_ISA(StageAccessDecoration)
-
+ FIDDLE(baseInst())
Int getStageCount() { return (Int)getOperandCount(); }
IRStringLit* getStageOperand(Int index) { return cast<IRStringLit>(getOperand(index)); }
UnownedStringSlice getStageName(Int index) { return getStageOperand(index)->getStringSlice(); }
};
+FIDDLE()
struct IRStageReadAccessDecoration : public IRStageAccessDecoration
{
- IR_LEAF_ISA(StageReadAccessDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRStageWriteAccessDecoration : public IRStageAccessDecoration
{
- IR_LEAF_ISA(StageWriteAccessDecoration)
+ FIDDLE(leafInst())
};
-
+FIDDLE()
struct IRRayPayloadDecoration : public IRDecoration
{
- IR_LEAF_ISA(RayPayloadDecoration)
+ FIDDLE(leafInst())
};
// Mesh shader decorations
+FIDDLE()
struct IRMeshOutputDecoration : public IRDecoration
{
- IR_PARENT_ISA(MeshOutputDecoration)
+ FIDDLE(baseInst())
IRIntLit* getMaxSize() { return cast<IRIntLit>(getOperand(0)); }
};
+FIDDLE()
struct IRVerticesDecoration : public IRMeshOutputDecoration
{
- IR_LEAF_ISA(VerticesDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRIndicesDecoration : public IRMeshOutputDecoration
{
- IR_LEAF_ISA(IndicesDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRPrimitivesDecoration : public IRMeshOutputDecoration
{
- IR_LEAF_ISA(PrimitivesDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRGLSLPrimitivesRateDecoration : public IRDecoration
{
- IR_LEAF_ISA(GLSLPrimitivesRateDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRGLPositionOutputDecoration : public IRDecoration
{
- IR_LEAF_ISA(GLPositionOutputDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRGLPositionInputDecoration : public IRDecoration
{
- IR_LEAF_ISA(GLPositionInputDecoration)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRMeshOutputRef : public IRInst
{
- IR_LEAF_ISA(MeshOutputRef)
+ FIDDLE(leafInst())
IRInst* getBase() { return getOperand(0); }
IRInst* getIndex() { return getOperand(1); }
IRInst* getOutputType() { return cast<IRPtrTypeBase>(getFullType())->getValueType(); }
};
+FIDDLE()
struct IRMeshOutputSet : public IRInst
{
- IR_LEAF_ISA(MeshOutputSet)
+ FIDDLE(leafInst())
IRInst* getBase() { return getOperand(0); }
IRInst* getIndex() { return getOperand(1); }
IRInst* getElementValue() { return getOperand(2); }
};
+FIDDLE()
struct IRMetalSetVertex : public IRInst
{
- IR_LEAF_ISA(MetalSetVertex)
+ FIDDLE(leafInst())
IRInst* getIndex() { return getOperand(0); }
IRInst* getElementValue() { return getOperand(1); }
};
+FIDDLE()
struct IRMetalSetPrimitive : public IRInst
{
- IR_LEAF_ISA(MetalSetPrimitive)
+ FIDDLE(leafInst())
IRInst* getIndex() { return getOperand(0); }
IRInst* getElementValue() { return getOperand(1); }
};
+FIDDLE()
struct IRMetalSetIndices : public IRInst
{
- IR_LEAF_ISA(MetalSetIndices)
+ FIDDLE(leafInst())
IRInst* getIndex() { return getOperand(0); }
IRInst* getElementValue() { return getOperand(1); }
};
@@ -1765,15 +1417,17 @@ struct IRMetalSetIndices : public IRInst
/// they can affect the conceptual value/identity of an instruction
/// in cases where we deduplicate/hash instructions by value.
///
+FIDDLE()
struct IRAttr : public IRInst
{
- IR_PARENT_ISA(Attr);
+ FIDDLE(baseInst())
};
/// An attribute that specifies layout information for a single resource kind.
+FIDDLE()
struct IRLayoutResourceInfoAttr : public IRAttr
{
- IR_PARENT_ISA(LayoutResourceInfoAttr);
+ FIDDLE(baseInst())
IRIntLit* getResourceKindInst() { return cast<IRIntLit>(getOperand(0)); }
LayoutResourceKind getResourceKind()
@@ -1788,9 +1442,10 @@ struct IRLayoutResourceInfoAttr : public IRAttr
/// `varOffset(kind, offset, space)`. The latter form is only
/// used when `space` is non-zero.
///
+FIDDLE()
struct IRVarOffsetAttr : public IRLayoutResourceInfoAttr
{
- IR_LEAF_ISA(VarOffsetAttr);
+ FIDDLE(leafInst())
IRIntLit* getOffsetInst() { return cast<IRIntLit>(getOperand(1)); }
UInt getOffset() { return UInt(getIntVal(getOffsetInst())); }
@@ -1811,22 +1466,25 @@ struct IRVarOffsetAttr : public IRLayoutResourceInfoAttr
};
/// An attribute that specifies the error type a function is throwing
+FIDDLE()
struct IRFuncThrowTypeAttr : IRAttr
{
- IR_LEAF_ISA(FuncThrowTypeAttr)
+ FIDDLE(leafInst())
IRType* getErrorType() { return (IRType*)getOperand(0); }
};
+FIDDLE()
struct IRNoDiffAttr : IRAttr
{
- IR_LEAF_ISA(NoDiffAttr)
+ FIDDLE(leafInst())
};
/// An attribute that specifies size information for a single resource kind.
+FIDDLE()
struct IRTypeSizeAttr : public IRLayoutResourceInfoAttr
{
- IR_LEAF_ISA(TypeSizeAttr);
+ FIDDLE(leafInst())
IRIntLit* getSizeInst() { return cast<IRIntLit>(getOperand(1)); }
LayoutSize getSize()
@@ -1842,9 +1500,10 @@ struct IRTypeSizeAttr : public IRLayoutResourceInfoAttr
///
/// Layout instructions are effectively just meta-data constants.
///
+FIDDLE()
struct IRLayout : IRInst
{
- IR_PARENT_ISA(Layout)
+ FIDDLE(baseInst())
};
struct IRVarLayout;
@@ -1856,9 +1515,10 @@ struct IRVarLayout;
/// type slots were filled in. The layout of pending data may not
/// be contiguous with the layout of the original type/variable.
///
+FIDDLE()
struct IRPendingLayoutAttr : IRAttr
{
- IR_LEAF_ISA(PendingLayoutAttr);
+ FIDDLE(leafInst())
IRLayout* getLayout() { return cast<IRLayout>(getOperand(0)); }
};
@@ -1873,9 +1533,10 @@ struct IRPendingLayoutAttr : IRAttr
/// operands or attributes. For example, a type layout for a
/// `struct` type will include offset information for its fields.
///
+FIDDLE()
struct IRTypeLayout : IRLayout
{
- IR_PARENT_ISA(TypeLayout);
+ FIDDLE(baseInst())
/// Find the attribute that stores offset information for `kind`.
///
@@ -1953,14 +1614,14 @@ struct IRTypeLayout : IRLayout
};
/// Type layout for parameter groups (constant buffers and parameter blocks)
+FIDDLE()
struct IRParameterGroupTypeLayout : IRTypeLayout
{
+ FIDDLE(leafInst())
private:
typedef IRTypeLayout Super;
public:
- IR_LEAF_ISA(ParameterGroupTypeLayout)
-
IRVarLayout* getContainerVarLayout() { return cast<IRVarLayout>(getOperand(0)); }
IRVarLayout* getElementVarLayout() { return cast<IRVarLayout>(getOperand(1)); }
@@ -2002,11 +1663,12 @@ public:
};
/// Specialized layout information for array types
+FIDDLE()
struct IRArrayTypeLayout : IRTypeLayout
{
+ FIDDLE(leafInst())
typedef IRTypeLayout Super;
- IR_LEAF_ISA(ArrayTypeLayout)
IRTypeLayout* getElementTypeLayout() { return cast<IRTypeLayout>(getOperand(0)); }
@@ -2028,11 +1690,12 @@ struct IRArrayTypeLayout : IRTypeLayout
};
/// Specialized layout information for structured buffer types
+FIDDLE()
struct IRStructuredBufferTypeLayout : IRTypeLayout
{
+ FIDDLE(leafInst())
typedef IRTypeLayout Super;
- IR_LEAF_ISA(StructuredBufferTypeLayout)
IRTypeLayout* getElementTypeLayout() { return cast<IRTypeLayout>(getOperand(0)); }
@@ -2080,11 +1743,12 @@ infinite recursion in lookup.
The work around for now is to observe that layout of a Ptr doesn't depend on what is being pointed
to and as such we don't store the this in the pointer.
*/
+FIDDLE()
struct IRPointerTypeLayout : IRTypeLayout
{
+ FIDDLE(leafInst())
typedef IRTypeLayout Super;
- IR_LEAF_ISA(PointerTypeLayout)
struct Builder : Super::Builder
{
@@ -2102,11 +1766,12 @@ struct IRPointerTypeLayout : IRTypeLayout
};
/// Specialized layout information for stream-output types
+FIDDLE()
struct IRStreamOutputTypeLayout : IRTypeLayout
{
+ FIDDLE(leafInst())
typedef IRTypeLayout Super;
- IR_LEAF_ISA(StreamOutputTypeLayout)
IRTypeLayout* getElementTypeLayout() { return cast<IRTypeLayout>(getOperand(0)); }
@@ -2128,11 +1793,12 @@ struct IRStreamOutputTypeLayout : IRTypeLayout
};
/// Specialized layout information for matrix types
+FIDDLE()
struct IRMatrixTypeLayout : IRTypeLayout
{
+ FIDDLE(leafInst())
typedef IRTypeLayout Super;
- IR_LEAF_ISA(MatrixTypeLayout)
MatrixLayoutMode getMode()
{
@@ -2154,9 +1820,10 @@ struct IRMatrixTypeLayout : IRTypeLayout
};
/// Attribute that specifies the layout for one field of a structure type.
+FIDDLE()
struct IRStructFieldLayoutAttr : IRAttr
{
- IR_LEAF_ISA(StructFieldLayoutAttr)
+ FIDDLE(leafInst())
IRInst* getFieldKey() { return getOperand(0); }
@@ -2164,9 +1831,10 @@ struct IRStructFieldLayoutAttr : IRAttr
};
/// Specialized layout information for structure types.
+FIDDLE()
struct IRStructTypeLayout : IRTypeLayout
{
- IR_LEAF_ISA(StructTypeLayout)
+ FIDDLE(leafInst())
typedef IRTypeLayout Super;
@@ -2215,17 +1883,19 @@ struct IRStructTypeLayout : IRTypeLayout
};
/// Attribute that specifies the layout for one field of a structure type.
+FIDDLE()
struct IRTupleFieldLayoutAttr : IRAttr
{
- IR_LEAF_ISA(TupleFieldLayoutAttr)
+ FIDDLE(leafInst())
IRTypeLayout* getLayout() { return cast<IRTypeLayout>(getOperand(1)); }
};
/// Specialized layout information for tuple types.
+FIDDLE()
struct IRTupleTypeLayout : IRTypeLayout
{
- IR_LEAF_ISA(TupleTypeLayout)
+ FIDDLE(leafInst())
typedef IRTypeLayout Super;
@@ -2272,19 +1942,21 @@ struct IRTupleTypeLayout : IRTypeLayout
};
/// Attribute that represents the layout for one case of a union type
+FIDDLE()
struct IRCaseTypeLayoutAttr : IRAttr
{
- IR_LEAF_ISA(CaseTypeLayoutAttr);
+ FIDDLE(leafInst())
IRTypeLayout* getTypeLayout() { return cast<IRTypeLayout>(getOperand(0)); }
};
/// Type layout for an existential/interface type.
+FIDDLE()
struct IRExistentialTypeLayout : IRTypeLayout
{
+ FIDDLE(leafInst())
typedef IRTypeLayout Super;
- IR_LEAF_ISA(ExistentialTypeLayout)
struct Builder : Super::Builder
{
@@ -2305,9 +1977,10 @@ struct IRExistentialTypeLayout : IRTypeLayout
/// Layout information for an entry point
+FIDDLE()
struct IREntryPointLayout : IRLayout
{
- IR_LEAF_ISA(EntryPointLayout)
+ FIDDLE(leafInst())
/// Get the layout information for the entry point parameters.
///
@@ -2332,18 +2005,20 @@ struct IREntryPointLayout : IRLayout
IRStructTypeLayout* getScopeStructLayout(IREntryPointLayout* scopeLayout);
/// Attribute that associates a variable layout with a known stage.
+FIDDLE()
struct IRStageAttr : IRAttr
{
- IR_LEAF_ISA(StageAttr);
+ FIDDLE(leafInst())
IRIntLit* getStageOperand() { return cast<IRIntLit>(getOperand(0)); }
Stage getStage() { return Stage(getIntVal(getStageOperand())); }
};
/// Base type for attributes that associate a variable layout with a semantic name and index.
+FIDDLE()
struct IRSemanticAttr : IRAttr
{
- IR_PARENT_ISA(SemanticAttr);
+ FIDDLE(baseInst())
IRStringLit* getNameOperand() { return cast<IRStringLit>(getOperand(0)); }
UnownedStringSlice getName() { return getNameOperand()->getStringSlice(); }
@@ -2353,21 +2028,24 @@ struct IRSemanticAttr : IRAttr
};
/// Attribute that associates a variable with a system-value semantic name and index
+FIDDLE()
struct IRSystemValueSemanticAttr : IRSemanticAttr
{
- IR_LEAF_ISA(SystemValueSemanticAttr);
+ FIDDLE(leafInst())
};
/// Attribute that associates a variable with a user-defined semantic name and index
+FIDDLE()
struct IRUserSemanticAttr : IRSemanticAttr
{
- IR_LEAF_ISA(UserSemanticAttr);
+ FIDDLE(leafInst())
};
/// Layout infromation for a single parameter/field
+FIDDLE()
struct IRVarLayout : IRLayout
{
- IR_LEAF_ISA(VarLayout)
+ FIDDLE(leafInst())
/// Get the type layout information for this variable
IRTypeLayout* getTypeLayout() { return cast<IRTypeLayout>(getOperand(0)); }
@@ -2470,27 +2148,27 @@ bool isVaryingParameter(IRVarLayout* varLayout);
/// * To attach an `IREntryPointLayout` to an `IRFunc` representing an entry point
/// * To attach an `IRTaggedUnionTypeLayout` to an `IRTaggedUnionType`
///
+FIDDLE()
struct IRLayoutDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_LayoutDecoration
- };
- IR_LEAF_ISA(LayoutDecoration)
+ FIDDLE(leafInst())
/// Get the layout that is being attached to the parent instruction
IRLayout* getLayout() { return cast<IRLayout>(getOperand(0)); }
};
//
+FIDDLE()
struct IRAlignOf : IRInst
{
+ FIDDLE(leafInst())
IRInst* getBaseOp() { return getOperand(0); }
};
+FIDDLE()
struct IRCall : IRInst
{
- IR_LEAF_ISA(Call)
+ FIDDLE(leafInst())
IRInst* getCallee() { return getOperand(0); }
IRUse* getCalleeUse() { return getOperands(); }
@@ -2504,40 +2182,45 @@ struct IRCall : IRInst
void setArg(UInt index, IRInst* arg) { setOperand(index + 1, arg); }
};
+FIDDLE()
struct IRAlignedAttr : IRAttr
{
- IR_LEAF_ISA(AlignedAttr)
+ FIDDLE(leafInst())
IRInst* getAlignment() { return getOperand(0); }
};
+FIDDLE()
struct IRLoad : IRInst
{
+ FIDDLE(leafInst())
IRUse ptr;
- IR_LEAF_ISA(Load)
IRInst* getPtr() { return ptr.get(); }
};
+FIDDLE()
struct IRAtomicOperation : IRInst
{
- IR_PARENT_ISA(AtomicOperation);
+ FIDDLE(baseInst())
IRInst* getPtr() { return getOperand(0); }
};
+FIDDLE()
struct IRAtomicLoad : IRAtomicOperation
{
+ FIDDLE(leafInst())
IRUse ptr;
- IR_LEAF_ISA(AtomicLoad)
IRInst* getPtr() { return ptr.get(); }
};
+FIDDLE()
struct IRStore : IRInst
{
+ FIDDLE(leafInst())
IRUse ptr;
IRUse val;
- IR_LEAF_ISA(Store)
IRInst* getPtr() { return ptr.get(); }
IRInst* getVal() { return val.get(); }
@@ -2546,150 +2229,171 @@ struct IRStore : IRInst
IRUse* getValUse() { return &val; }
};
+FIDDLE()
struct IRAtomicStore : IRAtomicOperation
{
+ FIDDLE(leafInst())
IRUse ptr;
IRUse val;
- IR_LEAF_ISA(AtomicStore)
IRInst* getPtr() { return ptr.get(); }
IRInst* getVal() { return val.get(); }
};
+FIDDLE()
struct IRRWStructuredBufferStore : IRInst
{
- IR_LEAF_ISA(RWStructuredBufferStore)
+ FIDDLE(leafInst())
IRInst* getStructuredBuffer() { return getOperand(0); }
IRInst* getIndex() { return getOperand(1); }
IRInst* getVal() { return getOperand(2); }
};
+FIDDLE()
struct IRFieldExtract : IRInst
{
+ FIDDLE(leafInst())
IRUse base;
IRUse field;
IRInst* getBase() { return base.get(); }
IRInst* getField() { return field.get(); }
- IR_LEAF_ISA(FieldExtract)
};
+FIDDLE()
struct IRFieldAddress : IRInst
{
+ FIDDLE(leafInst())
IRUse base;
IRUse field;
IRInst* getBase() { return base.get(); }
IRInst* getField() { return field.get(); }
- IR_LEAF_ISA(FieldAddress)
};
+FIDDLE()
struct IRGetElement : IRInst
{
- IR_LEAF_ISA(GetElement);
+ FIDDLE(leafInst())
IRInst* getBase() { return getOperand(0); }
IRInst* getIndex() { return getOperand(1); }
};
+FIDDLE()
struct IRGetElementPtr : IRInst
{
- IR_LEAF_ISA(GetElementPtr);
+ FIDDLE(leafInst())
IRInst* getBase() { return getOperand(0); }
IRInst* getIndex() { return getOperand(1); }
};
+FIDDLE()
struct IRGetOffsetPtr : IRInst
{
- IR_LEAF_ISA(GetOffsetPtr);
+ FIDDLE(leafInst())
IRInst* getBase() { return getOperand(0); }
IRInst* getOffset() { return getOperand(1); }
};
+FIDDLE()
struct IRRWStructuredBufferGetElementPtr : IRInst
{
- IR_LEAF_ISA(RWStructuredBufferGetElementPtr);
+ FIDDLE(leafInst())
IRInst* getBase() { return getOperand(0); }
IRInst* getIndex() { return getOperand(1); }
};
+FIDDLE()
struct IRStructuredBufferAppend : IRInst
{
- IR_LEAF_ISA(StructuredBufferAppend);
+ FIDDLE(leafInst())
IRInst* getBuffer() { return getOperand(0); }
IRInst* getElement() { return getOperand(1); }
};
+FIDDLE()
struct IRStructuredBufferConsume : IRInst
{
- IR_LEAF_ISA(StructuredBufferConsume);
+ FIDDLE(leafInst())
IRInst* getBuffer() { return getOperand(0); }
};
+FIDDLE()
struct IRStructuredBufferGetDimensions : IRInst
{
- IR_LEAF_ISA(StructuredBufferGetDimensions);
+ FIDDLE(leafInst())
IRInst* getBuffer() { return getOperand(0); }
};
+FIDDLE()
struct IRNonUniformResourceIndex : IRInst
{
- IR_LEAF_ISA(NonUniformResourceIndex);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRLoadReverseGradient : IRInst
{
- IR_LEAF_ISA(LoadReverseGradient)
+ FIDDLE(leafInst())
IRInst* getValue() { return getOperand(0); }
};
+FIDDLE()
struct IRReverseGradientDiffPairRef : IRInst
{
- IR_LEAF_ISA(ReverseGradientDiffPairRef)
+ FIDDLE(leafInst())
IRInst* getPrimal() { return getOperand(0); }
IRInst* getDiff() { return getOperand(1); }
};
+FIDDLE()
struct IRPrimalParamRef : IRInst
{
- IR_LEAF_ISA(PrimalParamRef)
+ FIDDLE(leafInst())
IRInst* getReferencedParam() { return getOperand(0); }
};
+FIDDLE()
struct IRDiffParamRef : IRInst
{
- IR_LEAF_ISA(DiffParamRef)
+ FIDDLE(leafInst())
IRInst* getReferencedParam() { return getOperand(0); }
};
+FIDDLE()
struct IRGetNativePtr : IRInst
{
- IR_LEAF_ISA(GetNativePtr);
+ FIDDLE(leafInst())
IRInst* getElementType() { return getOperand(0); }
};
+FIDDLE()
struct IRGetManagedPtrWriteRef : IRInst
{
- IR_LEAF_ISA(GetManagedPtrWriteRef);
+ FIDDLE(leafInst())
IRInst* getPtrToManagedPtr() { return getOperand(0); }
};
+FIDDLE()
struct IRGetAddress : IRInst
{
- IR_LEAF_ISA(GetAddr);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRImageSubscript : IRInst
{
- IR_LEAF_ISA(ImageSubscript);
+ FIDDLE(leafInst())
IRInst* getImage() { return getOperand(0); }
IRInst* getCoord() { return getOperand(1); }
bool hasSampleCoord() { return getOperandCount() > 2 && getOperand(2) != nullptr; }
IRInst* getSampleCoord() { return getOperand(2); }
};
+FIDDLE()
struct IRImageLoad : IRInst
{
- IR_LEAF_ISA(ImageLoad);
+ FIDDLE(leafInst())
IRInst* getImage() { return getOperand(0); }
IRInst* getCoord() { return getOperand(1); }
@@ -2703,9 +2407,10 @@ struct IRImageLoad : IRInst
IRInst* getAuxCoord2() { return getOperand(3); }
};
+FIDDLE()
struct IRImageStore : IRInst
{
- IR_LEAF_ISA(ImageStore);
+ FIDDLE(leafInst())
IRInst* getImage() { return getOperand(0); }
IRInst* getCoord() { return getOperand(1); }
IRInst* getValue() { return getOperand(2); }
@@ -2717,22 +2422,26 @@ struct IRImageStore : IRInst
};
// Terminators
+FIDDLE()
struct IRReturn : IRTerminatorInst
{
- IR_LEAF_ISA(Return);
+ FIDDLE(leafInst())
IRInst* getVal() { return getOperand(0); }
};
+FIDDLE()
struct IRYield : IRTerminatorInst
{
- IR_LEAF_ISA(Yield);
+ FIDDLE(leafInst())
IRInst* getVal() { return getOperand(0); }
};
+FIDDLE()
struct IRDiscard : IRTerminatorInst
{
+ FIDDLE(leafInst())
};
// Used for representing a distinct copy of an object.
@@ -2744,16 +2453,18 @@ struct IRDiscard : IRTerminatorInst
// we need to make distinct copies of the inst for its uses
// within the loop body and outside of it.
//
+FIDDLE()
struct IRCheckpointObject : IRInst
{
- IR_LEAF_ISA(CheckpointObject);
+ FIDDLE(leafInst())
IRInst* getVal() { return getOperand(0); }
};
+FIDDLE()
struct IRLoopExitValue : IRInst
{
- IR_LEAF_ISA(LoopExitValue);
+ FIDDLE(leafInst())
IRInst* getVal() { return getOperand(0); }
};
@@ -2762,20 +2473,24 @@ struct IRLoopExitValue : IRInst
// We can/should emit a dataflow error if we can ever determine
// that a block ending in one of these can actually be
// executed.
+FIDDLE()
struct IRUnreachable : IRTerminatorInst
{
- IR_PARENT_ISA(Unreachable);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRMissingReturn : IRUnreachable
{
- IR_LEAF_ISA(MissingReturn);
+ FIDDLE(leafInst())
};
struct IRBlock;
+FIDDLE()
struct IRUnconditionalBranch : IRTerminatorInst
{
+ FIDDLE(baseInst())
IRUse block;
IRBlock* getTargetBlock() { return (IRBlock*)block.get(); }
@@ -2784,25 +2499,15 @@ struct IRUnconditionalBranch : IRTerminatorInst
IRUse* getArgs();
IRInst* getArg(UInt index);
void removeArgument(UInt index);
- IR_PARENT_ISA(UnconditionalBranch);
-};
-
-// Special cases of unconditional branch, to handle
-// structured control flow:
-struct IRBreak : IRUnconditionalBranch
-{
-};
-struct IRContinue : IRUnconditionalBranch
-{
};
// The start of a loop is a special control-flow
// instruction, that records relevant information
// about the loop structure:
+FIDDLE()
struct IRLoop : IRUnconditionalBranch
{
- IR_LEAF_ISA(loop);
-
+ FIDDLE(leafInst())
// The next block after the loop, which
// is where we expect control flow to
// re-converge, and also where a
@@ -2817,9 +2522,10 @@ struct IRLoop : IRUnconditionalBranch
IRBlock* getContinueBlock() { return (IRBlock*)continueBlock.get(); }
};
+FIDDLE()
struct IRConditionalBranch : IRTerminatorInst
{
- IR_PARENT_ISA(ConditionalBranch)
+ FIDDLE(baseInst())
IRUse condition;
IRUse trueBlock;
@@ -2836,17 +2542,20 @@ struct IRConditionalBranch : IRTerminatorInst
// else { <falseBlock> }
// <afterBlock>
//
+FIDDLE()
struct IRIfElse : IRConditionalBranch
{
+ FIDDLE(leafInst())
IRUse afterBlock;
IRBlock* getAfterBlock() { return (IRBlock*)afterBlock.get(); }
};
// A multi-way branch that represents a source-level `switch`
+FIDDLE()
struct IRSwitch : IRTerminatorInst
{
- IR_LEAF_ISA(Switch);
+ FIDDLE(leafInst())
IRUse condition;
IRUse breakLabel;
@@ -2865,25 +2574,28 @@ struct IRSwitch : IRTerminatorInst
};
// A compile-time switch based on the current code generation target.
+FIDDLE()
struct IRTargetSwitch : IRTerminatorInst
{
- IR_LEAF_ISA(TargetSwitch)
+ FIDDLE(leafInst())
IRInst* getBreakBlock() { return getOperand(0); }
UInt getCaseCount() { return (getOperandCount() - 1) / 2; }
IRBlock* getCaseBlock(UInt index) { return (IRBlock*)getOperand(index * 2 + 2); }
IRInst* getCaseValue(UInt index) { return getOperand(index * 2 + 1); }
};
+FIDDLE()
struct IRThrow : IRTerminatorInst
{
- IR_LEAF_ISA(Throw);
+ FIDDLE(leafInst())
IRInst* getValue() { return getOperand(0); }
};
+FIDDLE()
struct IRTryCall : IRTerminatorInst
{
- IR_LEAF_ISA(TryCall);
+ FIDDLE(leafInst())
IRBlock* getSuccessBlock() { return cast<IRBlock>(getOperand(0)); }
IRBlock* getFailureBlock() { return cast<IRBlock>(getOperand(1)); }
@@ -2893,19 +2605,20 @@ struct IRTryCall : IRTerminatorInst
IRInst* getArg(UInt index) { return getOperand(index + 3); }
};
+FIDDLE()
struct IRDefer : IRTerminatorInst
{
- IR_LEAF_ISA(Defer);
+ FIDDLE(leafInst())
IRBlock* getDeferBlock() { return cast<IRBlock>(getOperand(0)); }
IRBlock* getMergeBlock() { return cast<IRBlock>(getOperand(1)); }
IRBlock* getScopeBlock() { return cast<IRBlock>(getOperand(2)); }
};
+FIDDLE()
struct IRSwizzle : IRInst
{
- IR_LEAF_ISA(swizzle);
-
+ FIDDLE(leafInst())
IRUse base;
IRInst* getBase() { return base.get(); }
@@ -2913,10 +2626,10 @@ struct IRSwizzle : IRInst
IRInst* getElementIndex(UInt index) { return getOperand(index + 1); }
};
+FIDDLE()
struct IRSwizzleSet : IRInst
{
- IR_LEAF_ISA(swizzleSet);
-
+ FIDDLE(leafInst())
IRUse base;
IRUse source;
@@ -2926,35 +2639,32 @@ struct IRSwizzleSet : IRInst
IRInst* getElementIndex(UInt index) { return getOperand(index + 2); }
};
+FIDDLE()
struct IRSwizzledStore : IRInst
{
+ FIDDLE(leafInst())
IRInst* getDest() { return getOperand(0); }
IRInst* getSource() { return getOperand(1); }
UInt getElementCount() { return getOperandCount() - 2; }
IRInst* getElementIndex(UInt index) { return getOperand(index + 2); }
-
- IR_LEAF_ISA(SwizzledStore)
};
+FIDDLE()
struct IRPatchConstantFuncDecoration : IRDecoration
{
- enum
- {
- kOp = kIROp_PatchConstantFuncDecoration
- };
- IR_LEAF_ISA(PatchConstantFuncDecoration)
+ FIDDLE(leafInst())
IRInst* getFunc() { return getOperand(0); }
};
// An IR `var` instruction conceptually represents
// a stack allocation of some memory.
+FIDDLE()
struct IRVar : IRInst
{
+ FIDDLE(leafInst())
IRPtrType* getDataType() { return cast<IRPtrType>(IRInst::getDataType()); }
-
- static bool isaImpl(IROp op) { return op == kIROp_Var; }
};
/// @brief A global variable.
@@ -2963,9 +2673,10 @@ struct IRVar : IRInst
/// If the variable has an initializer, then
/// it is represented by the code in the basic
/// blocks nested inside this value.
+FIDDLE()
struct IRGlobalVar : IRGlobalValueWithCode
{
- IR_LEAF_ISA(GlobalVar)
+ FIDDLE(leafInst())
IRPtrType* getDataType() { return cast<IRPtrType>(IRInst::getDataType()); }
};
@@ -2982,9 +2693,10 @@ struct IRGlobalVar : IRGlobalValueWithCode
/// immutable, and subject to various SSA simplifications that
/// do not work for global variables.
///
+FIDDLE()
struct IRGlobalParam : IRInst
{
- IR_LEAF_ISA(GlobalParam)
+ FIDDLE(leafInst())
};
/// @brief A global constnat.
@@ -2995,17 +2707,20 @@ struct IRGlobalParam : IRInst
/// represents an "extern" constant that will be defined in another
/// module, and which is thus expected to have linkage.
///
+FIDDLE()
struct IRGlobalConstant : IRInst
{
- IR_LEAF_ISA(GlobalConstant);
+ FIDDLE(leafInst())
/// Get the value of this global constant, or null if the value is not known.
IRInst* getValue() { return getOperandCount() != 0 ? getOperand(0) : nullptr; }
};
// An entry in a witness table (see below)
+FIDDLE()
struct IRWitnessTableEntry : IRInst
{
+ FIDDLE(leafInst())
// The AST-level requirement
IRUse requirementKey;
@@ -3014,8 +2729,6 @@ struct IRWitnessTableEntry : IRInst
IRInst* getRequirementKey() { return getOperand(0); }
IRInst* getSatisfyingVal() { return getOperand(1); }
-
- IR_LEAF_ISA(WitnessTableEntry)
};
// A witness table is a global value that stores
@@ -3023,8 +2736,10 @@ struct IRWitnessTableEntry : IRInst
// interface. It basically takes the form of a
// map from the required members of the interface
// to the IR values that satisfy those requirements.
+FIDDLE()
struct IRWitnessTable : IRInst
{
+ FIDDLE(leafInst())
IRInstList<IRWitnessTableEntry> getEntries()
{
return IRInstList<IRWitnessTableEntry>(getChildren());
@@ -3036,8 +2751,6 @@ struct IRWitnessTable : IRInst
}
IRType* getConcreteType() { return (IRType*)getOperand(0); }
-
- IR_LEAF_ISA(WitnessTable)
};
/// Represents an RTTI object.
@@ -3045,9 +2758,10 @@ struct IRWitnessTable : IRInst
/// this RTTI object provides info for.
/// All type info are encapsualted as `IRRTTI*Decoration`s attached
/// to the object.
+FIDDLE()
struct IRRTTIObject : IRInst
{
- IR_LEAF_ISA(RTTIObject)
+ FIDDLE(leafInst())
};
// An instruction that yields an undefined value.
@@ -3055,114 +2769,132 @@ struct IRRTTIObject : IRInst
// Note that we make this an instruction rather than a value,
// so that we will be able to identify a variable that is
// used when undefined.
+FIDDLE()
struct IRUndefined : IRInst
{
+ FIDDLE(leafInst())
};
// Special inst for targets that support default initialization,
// like the braces '= {}' in C/HLSL
+FIDDLE()
struct IRDefaultConstruct : IRInst
{
- IR_LEAF_ISA(DefaultConstruct)
+ FIDDLE(leafInst())
};
// A global-scope generic parameter (a type parameter, a
// constraint parameter, etc.)
+FIDDLE()
struct IRGlobalGenericParam : IRInst
{
- IR_LEAF_ISA(GlobalGenericParam)
+ FIDDLE(leafInst())
};
// An instruction that binds a global generic parameter
// to a particular value.
+FIDDLE()
struct IRBindGlobalGenericParam : IRInst
{
+ FIDDLE(leafInst())
IRGlobalGenericParam* getParam() { return cast<IRGlobalGenericParam>(getOperand(0)); }
IRInst* getVal() { return getOperand(1); }
-
- IR_LEAF_ISA(BindGlobalGenericParam)
};
+FIDDLE()
struct IRExpand : IRInst
{
- IR_LEAF_ISA(Expand)
+ FIDDLE(leafInst())
UInt getCaptureCount() { return getOperandCount(); }
IRInst* getCapture(UInt index) { return getOperand(index); }
IRInstList<IRBlock> getBlocks() { return IRInstList<IRBlock>(getChildren()); }
};
+FIDDLE()
struct IREach : IRInst
{
- IR_LEAF_ISA(Each)
+ FIDDLE(leafInst())
IRInst* getElement() { return getOperand(0); }
};
+FIDDLE()
struct IRMakeArray : IRInst
{
- IR_LEAF_ISA(MakeArray)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRMakeArrayFromElement : IRInst
{
- IR_LEAF_ISA(MakeArrayFromElement)
+ FIDDLE(leafInst())
};
// An Instruction that creates a tuple value.
+FIDDLE()
struct IRMakeTuple : IRInst
{
- IR_LEAF_ISA(MakeTuple)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRMakeValuePack : IRInst
{
- IR_LEAF_ISA(MakeValuePack)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRMakeStruct : IRInst
{
- IR_LEAF_ISA(MakeStruct)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRMakeWitnessPack : IRInst
{
- IR_LEAF_ISA(MakeWitnessPack)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRGetTupleElement : IRInst
{
- IR_LEAF_ISA(GetTupleElement)
+ FIDDLE(leafInst())
IRInst* getTuple() { return getOperand(0); }
IRInst* getElementIndex() { return getOperand(1); }
};
+FIDDLE()
struct IRGetTargetTupleElement : IRInst
{
- IR_LEAF_ISA(GetTargetTupleElement)
+ FIDDLE(leafInst())
IRInst* getTuple() { return getOperand(0); }
IRInst* getElementIndex() { return getOperand(1); }
};
+FIDDLE()
struct IRMakeVector : IRInst
{
- IR_LEAF_ISA(MakeVector)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRMakeVectorFromScalar : IRInst
{
- IR_LEAF_ISA(MakeVectorFromScalar)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRMakeCoopVector : IRInst
{
- IR_LEAF_ISA(MakeCoopVector)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRCoopMatMapElementIFunc : IRInst
{
- IR_LEAF_ISA(CoopMatMapElementIFunc)
+ FIDDLE(leafInst())
IRInst* getCoopMat() { return getOperand(0); }
IRInst* getTuple() { return getOperand(0); }
IRFunc* getIFuncCall() { return as<IRFunc>(getOperand(1)); }
@@ -3175,70 +2907,84 @@ struct IRCoopMatMapElementIFunc : IRInst
// An Instruction that creates a differential pair value from a
// primal and differential.
+FIDDLE()
struct IRMakeDifferentialPairBase : IRInst
{
- IR_PARENT_ISA(MakeDifferentialPairBase)
+ FIDDLE(baseInst())
IRInst* getPrimalValue() { return getOperand(0); }
IRInst* getDifferentialValue() { return getOperand(1); }
};
+FIDDLE()
struct IRMakeDifferentialPair : IRMakeDifferentialPairBase
{
- IR_LEAF_ISA(MakeDifferentialPair)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRMakeDifferentialPairUserCode : IRMakeDifferentialPairBase
{
- IR_LEAF_ISA(MakeDifferentialPairUserCode)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRMakeDifferentialPtrPair : IRMakeDifferentialPairBase
{
- IR_LEAF_ISA(MakeDifferentialPtrPair)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRDifferentialPairGetDifferentialBase : IRInst
{
- IR_PARENT_ISA(DifferentialPairGetDifferentialBase)
+ FIDDLE(baseInst())
IRInst* getBase() { return getOperand(0); }
};
+FIDDLE()
struct IRDifferentialPairGetDifferential : IRDifferentialPairGetDifferentialBase
{
- IR_LEAF_ISA(DifferentialPairGetDifferential)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRDifferentialPairGetDifferentialUserCode : IRDifferentialPairGetDifferentialBase
{
- IR_LEAF_ISA(DifferentialPairGetDifferentialUserCode)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRDifferentialPtrPairGetDifferential : IRDifferentialPairGetDifferentialBase
{
- IR_LEAF_ISA(DifferentialPtrPairGetDifferential)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRDifferentialPairGetPrimalBase : IRInst
{
- IR_PARENT_ISA(DifferentialPairGetPrimalBase)
+ FIDDLE(baseInst())
IRInst* getBase() { return getOperand(0); }
};
+FIDDLE()
struct IRDifferentialPairGetPrimal : IRDifferentialPairGetPrimalBase
{
- IR_LEAF_ISA(DifferentialPairGetPrimal)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRDifferentialPairGetPrimalUserCode : IRDifferentialPairGetPrimalBase
{
- IR_LEAF_ISA(DifferentialPairGetPrimalUserCode)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRDifferentialPtrPairGetPrimal : IRDifferentialPairGetPrimalBase
{
- IR_LEAF_ISA(DifferentialPtrPairGetPrimal)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRDetachDerivative : IRInst
{
- IR_LEAF_ISA(DetachDerivative)
+ FIDDLE(leafInst())
IRInst* getBase() { return getOperand(0); }
};
+FIDDLE()
struct IRUpdateElement : IRInst
{
- IR_LEAF_ISA(UpdateElement)
+ FIDDLE(leafInst())
IRInst* getOldValue() { return getOperand(0); }
IRInst* getElementValue() { return getOperand(1); }
@@ -3254,141 +3000,155 @@ struct IRUpdateElement : IRInst
};
// Constructs an `Result<T,E>` value from an error code.
+FIDDLE()
struct IRMakeResultError : IRInst
{
- IR_LEAF_ISA(MakeResultError)
+ FIDDLE(leafInst())
IRInst* getErrorValue() { return getOperand(0); }
};
// Constructs an `Result<T,E>` value from an valid value.
+FIDDLE()
struct IRMakeResultValue : IRInst
{
- IR_LEAF_ISA(MakeResultValue)
+ FIDDLE(leafInst())
IRInst* getValue() { return getOperand(0); }
};
// Determines if a `Result` value represents an error.
+FIDDLE()
struct IRIsResultError : IRInst
{
- IR_LEAF_ISA(IsResultError)
+ FIDDLE(leafInst())
IRInst* getResultOperand() { return getOperand(0); }
};
// Extract the value from a `Result`.
+FIDDLE()
struct IRGetResultValue : IRInst
{
- IR_LEAF_ISA(GetResultValue)
+ FIDDLE(leafInst())
IRInst* getResultOperand() { return getOperand(0); }
};
// Extract the error code from a `Result`.
+FIDDLE()
struct IRGetResultError : IRInst
{
- IR_LEAF_ISA(GetResultError)
+ FIDDLE(leafInst())
IRInst* getResultOperand() { return getOperand(0); }
};
+FIDDLE()
struct IROptionalHasValue : IRInst
{
- IR_LEAF_ISA(OptionalHasValue)
+ FIDDLE(leafInst())
IRInst* getOptionalOperand() { return getOperand(0); }
};
+FIDDLE()
struct IRGetOptionalValue : IRInst
{
- IR_LEAF_ISA(GetOptionalValue)
+ FIDDLE(leafInst())
IRInst* getOptionalOperand() { return getOperand(0); }
};
+FIDDLE()
struct IRMakeOptionalValue : IRInst
{
- IR_LEAF_ISA(MakeOptionalValue)
+ FIDDLE(leafInst())
IRInst* getValue() { return getOperand(0); }
};
+FIDDLE()
struct IRMakeOptionalNone : IRInst
{
- IR_LEAF_ISA(MakeOptionalNone)
+ FIDDLE(leafInst())
IRInst* getDefaultValue() { return getOperand(0); }
};
/// An instruction that packs a concrete value into an existential-type "box"
+FIDDLE()
struct IRMakeExistential : IRInst
{
+ FIDDLE(leafInst())
IRInst* getWrappedValue() { return getOperand(0); }
IRInst* getWitnessTable() { return getOperand(1); }
-
- IR_LEAF_ISA(MakeExistential)
};
+FIDDLE()
struct IRMakeExistentialWithRTTI : IRInst
{
+ FIDDLE(leafInst())
IRInst* getWrappedValue() { return getOperand(0); }
IRInst* getWitnessTable() { return getOperand(1); }
IRInst* getRTTI() { return getOperand(2); }
-
-
- IR_LEAF_ISA(MakeExistentialWithRTTI)
};
+FIDDLE()
struct IRCreateExistentialObject : IRInst
{
+ FIDDLE(leafInst())
IRInst* getTypeID() { return getOperand(0); }
IRInst* getValue() { return getOperand(1); }
-
- IR_LEAF_ISA(CreateExistentialObject)
};
/// Generalizes `IRMakeExistential` by allowing a type with existential sub-fields to be boxed
+FIDDLE()
struct IRWrapExistential : IRInst
{
+ FIDDLE(leafInst())
IRInst* getWrappedValue() { return getOperand(0); }
UInt getSlotOperandCount() { return getOperandCount() - 1; }
IRInst* getSlotOperand(UInt index) { return getOperand(index + 1); }
IRUse* getSlotOperands() { return getOperands() + 1; }
-
- IR_LEAF_ISA(WrapExistential)
};
+FIDDLE()
struct IRGetValueFromBoundInterface : IRInst
{
- IR_LEAF_ISA(GetValueFromBoundInterface);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRExtractExistentialValue : IRInst
{
- IR_LEAF_ISA(ExtractExistentialValue);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRExtractExistentialType : IRInst
{
- IR_LEAF_ISA(ExtractExistentialType);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRExtractExistentialWitnessTable : IRInst
{
- IR_LEAF_ISA(ExtractExistentialWitnessTable);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRIsNullExistential : IRInst
{
- IR_LEAF_ISA(IsNullExistential);
+ FIDDLE(leafInst())
};
/* Base class for instructions that track liveness */
+FIDDLE()
struct IRLiveRangeMarker : IRInst
{
- IR_PARENT_ISA(LiveRangeMarker)
+ FIDDLE(baseInst())
// TODO(JS): It might be useful to track how many bytes are live in the item referenced.
// It's not entirely clear how that will work across different targets, or even what such a
@@ -3405,14 +3165,16 @@ struct IRLiveRangeMarker : IRInst
};
/// Identifies then the item references starts being live.
+FIDDLE()
struct IRLiveRangeStart : IRLiveRangeMarker
{
- IR_LEAF_ISA(LiveRangeStart);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRIsType : IRInst
{
- IR_LEAF_ISA(IsType);
+ FIDDLE(leafInst())
IRInst* getValue() { return getOperand(0); }
IRInst* getValueWitness() { return getOperand(1); }
@@ -3429,67 +3191,78 @@ struct IRIsType : IRInst
/// the store will never be seen (by a load) and so can be ignored.
///
/// In general there can be one or more 'ends' for every start.
+FIDDLE()
struct IRLiveRangeEnd : IRLiveRangeMarker
{
- IR_LEAF_ISA(LiveRangeEnd);
+ FIDDLE(leafInst())
};
/// An instruction that queries binding information about an opaque/resource value.
///
+FIDDLE()
struct IRBindingQuery : IRInst
{
- IR_PARENT_ISA(BindingQuery);
+ FIDDLE(baseInst())
IRInst* getOpaqueValue() { return getOperand(0); }
};
+FIDDLE()
struct IRGetRegisterIndex : IRBindingQuery
{
- IR_LEAF_ISA(GetRegisterIndex);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRGetRegisterSpace : IRBindingQuery
{
- IR_LEAF_ISA(GetRegisterSpace);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRIntCast : IRInst
{
- IR_LEAF_ISA(IntCast)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRFloatCast : IRInst
{
- IR_LEAF_ISA(FloatCast)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRCastIntToFloat : IRInst
{
- IR_LEAF_ISA(CastIntToFloat)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRCastFloatToInt : IRInst
{
- IR_LEAF_ISA(CastFloatToInt)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRDebugSource : IRInst
{
- IR_LEAF_ISA(DebugSource)
+ FIDDLE(leafInst())
IRInst* getFileName() { return getOperand(0); }
IRInst* getSource() { return getOperand(1); }
};
+FIDDLE()
struct IRDebugBuildIdentifier : IRInst
{
- IR_LEAF_ISA(DebugBuildIdentifier)
+ FIDDLE(leafInst())
IRInst* getBuildIdentifier() { return getOperand(0); }
IRInst* getFlags() { return getOperand(1); }
};
+FIDDLE()
struct IRDebugLine : IRInst
{
- IR_LEAF_ISA(DebugLine)
+ FIDDLE(leafInst())
IRInst* getSource() { return getOperand(0); }
IRInst* getLineStart() { return getOperand(1); }
IRInst* getLineEnd() { return getOperand(2); }
@@ -3497,25 +3270,28 @@ struct IRDebugLine : IRInst
IRInst* getColEnd() { return getOperand(4); }
};
+FIDDLE()
struct IRDebugVar : IRInst
{
- IR_LEAF_ISA(DebugVar)
+ FIDDLE(leafInst())
IRInst* getSource() { return getOperand(0); }
IRInst* getLine() { return getOperand(1); }
IRInst* getCol() { return getOperand(2); }
IRInst* getArgIndex() { return getOperandCount() >= 4 ? getOperand(3) : nullptr; }
};
+FIDDLE()
struct IRDebugValue : IRInst
{
- IR_LEAF_ISA(DebugValue)
+ FIDDLE(leafInst())
IRInst* getDebugVar() { return getOperand(0); }
IRInst* getValue() { return getOperand(1); }
};
+FIDDLE()
struct IRDebugInlinedAt : IRInst
{
- IR_LEAF_ISA(DebugInlinedAt)
+ FIDDLE(leafInst())
IRInst* getLine() { return getOperand(0); }
IRInst* getCol() { return getOperand(1); }
IRInst* getFile() { return getOperand(2); }
@@ -3530,30 +3306,34 @@ struct IRDebugInlinedAt : IRInst
bool isOuterInlinedPresent() { return operandCount == 5; }
};
+FIDDLE()
struct IRDebugScope : IRInst
{
- IR_LEAF_ISA(DebugScope)
+ FIDDLE(leafInst())
IRInst* getScope() { return getOperand(0); }
IRInst* getInlinedAt() { return getOperand(1); }
void setInlinedAt(IRInst* inlinedAt) { setOperand(1, inlinedAt); }
};
+FIDDLE()
struct IRDebugNoScope : IRInst
{
- IR_LEAF_ISA(DebugNoScope)
+ FIDDLE(leafInst())
IRInst* getScope() { return getOperand(0); }
};
+FIDDLE()
struct IRDebugInlinedVariable : IRInst
{
- IR_LEAF_ISA(DebugInlinedVariable)
+ FIDDLE(leafInst())
IRInst* getVariable() { return getOperand(0); }
IRInst* getInlinedAt() { return getOperand(1); }
};
+FIDDLE()
struct IRDebugFunction : IRInst
{
- IR_LEAF_ISA(DebugFunction)
+ FIDDLE(leafInst())
IRInst* getName() { return getOperand(0); }
IRInst* getLine() { return getOperand(1); }
IRInst* getCol() { return getOperand(2); }
@@ -3561,26 +3341,28 @@ struct IRDebugFunction : IRInst
IRInst* getDebugType() { return getOperand(4); }
};
+FIDDLE()
struct IRDebugFuncDecoration : IRInst
{
- IR_LEAF_ISA(DebugFunctionDecoration)
+ FIDDLE(leafInst())
IRInst* getDebugFunc() { return getOperand(0); }
};
+FIDDLE()
struct IRDebugLocationDecoration : IRDecoration
{
+ FIDDLE(leafInst())
IRInst* getSource() { return getOperand(0); }
IRInst* getLine() { return getOperand(1); }
IRInst* getCol() { return getOperand(2); }
-
- IR_LEAF_ISA(DebugLocationDecoration)
};
struct IRSPIRVAsm;
+FIDDLE()
struct IRSPIRVAsmOperand : IRInst
{
- IR_PARENT_ISA(SPIRVAsmOperand);
+ FIDDLE(baseInst())
IRInst* getValue()
{
if (getOp() == kIROp_SPIRVAsmOperandResult)
@@ -3595,14 +3377,16 @@ struct IRSPIRVAsmOperand : IRInst
}
};
+FIDDLE()
struct IRSPIRVAsmOperandInst : IRSPIRVAsmOperand
{
- IR_LEAF_ISA(SPIRVAsmOperandInst);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRSPIRVAsmInst : IRInst
{
- IR_LEAF_ISA(SPIRVAsmInst);
+ FIDDLE(leafInst())
IRSPIRVAsmOperand* getOpcodeOperand()
{
@@ -3640,59 +3424,68 @@ struct IRSPIRVAsmInst : IRInst
}
};
+FIDDLE()
struct IRSPIRVAsm : IRInst
{
- IR_LEAF_ISA(SPIRVAsm);
+ FIDDLE(leafInst())
IRFilteredInstList<IRSPIRVAsmInst> getInsts()
{
return IRFilteredInstList<IRSPIRVAsmInst>(getFirstChild(), getLastChild());
}
};
+FIDDLE()
struct IRGenericAsm : IRTerminatorInst
{
- IR_LEAF_ISA(GenericAsm)
+ FIDDLE(leafInst())
UnownedStringSlice getAsm() { return as<IRStringLit>(getOperand(0))->getStringSlice(); }
};
+FIDDLE()
struct IRRequirePrelude : IRInst
{
- IR_LEAF_ISA(RequirePrelude)
+ FIDDLE(leafInst())
UnownedStringSlice getPrelude() { return as<IRStringLit>(getOperand(0))->getStringSlice(); }
};
+FIDDLE()
struct IRRequireTargetExtension : IRInst
{
- IR_LEAF_ISA(RequireTargetExtension)
+ FIDDLE(leafInst())
UnownedStringSlice getExtensionName()
{
return as<IRStringLit>(getOperand(0))->getStringSlice();
}
};
+FIDDLE()
struct IRRequireComputeDerivative : IRInst
{
- IR_LEAF_ISA(RequireComputeDerivative)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRRequireMaximallyReconverges : IRInst
{
- IR_LEAF_ISA(RequireMaximallyReconverges)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRRequireQuadDerivatives : IRInst
{
- IR_LEAF_ISA(RequireQuadDerivatives)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRStaticAssert : IRInst
{
- IR_LEAF_ISA(StaticAssert)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IREmbeddedDownstreamIR : IRInst
{
- IR_LEAF_ISA(EmbeddedDownstreamIR)
+ FIDDLE(leafInst())
CodeGenTarget getTarget()
{
return static_cast<CodeGenTarget>(cast<IRIntLit>(getOperand(0))->getValue());
@@ -3700,6 +3493,8 @@ struct IREmbeddedDownstreamIR : IRInst
IRBlobLit* getBlob() { return cast<IRBlobLit>(getOperand(1)); }
};
+FIDDLE(allOtherInstStructs())
+
struct IRBuilderSourceLocRAII;
struct IRBuilder
@@ -3895,7 +3690,10 @@ public:
IRTypePack* getTypePack(UInt count, IRType* const* types);
- IRExpandType* getExpandTypeOrVal(IRType* type, IRInst* pattern, ArrayView<IRInst*> capture);
+ IRExpandTypeOrVal* getExpandTypeOrVal(
+ IRType* type,
+ IRInst* pattern,
+ ArrayView<IRInst*> capture);
IRResultType* getResultType(IRType* valueType, IRType* errorType);
IROptionalType* getOptionalType(IRType* valueType);
@@ -5165,7 +4963,7 @@ public:
void addDebugFunctionDecoration(IRInst* value, IRInst* debugFunction)
{
- addDecoration(value, kIROp_DebugFunctionDecoration, debugFunction);
+ addDecoration(value, kIROp_DebugFuncDecoration, debugFunction);
}
void addUnsafeForceInlineDecoration(IRInst* value)
@@ -5622,5 +5420,3 @@ inline IRTargetIntrinsicDecoration* findBestTargetIntrinsicDecoration(
void addHoistableInst(IRBuilder* builder, IRInst* inst);
} // namespace Slang
-
-#endif
diff --git a/source/slang/slang-ir-insts.h.lua b/source/slang/slang-ir-insts.h.lua
new file mode 100644
index 000000000..ad084e997
--- /dev/null
+++ b/source/slang/slang-ir-insts.h.lua
@@ -0,0 +1,2 @@
+-- so we can use leafInst and baseInst in both slang-ir.h and slang-ir-insts.h
+return require("source/slang/slang-ir.h.lua")
diff --git a/source/slang/slang-ir-insts.lua b/source/slang/slang-ir-insts.lua
new file mode 100644
index 000000000..44dbc1ade
--- /dev/null
+++ b/source/slang/slang-ir-insts.lua
@@ -0,0 +1,2260 @@
+--
+-- This file contains the canonical definitions for the instions to the Slang IR.
+-- Add new instructions here
+--
+-- The instructions struct name, i.e. something like "IRVoidType" can be specified with struct_name, otherwise it will be a PascalCase version of the instruction key
+--
+-- Flags, such as hoistable, global, parent, use_other are inherited from a parent abstract type
+--
+-- min_operands specifies the number of required operands for an instruction, it defaults to 0
+--
+-- Instructions here will automatically be given a struct definition in slang-ir-insts.h if it is no handwritten
+--
+
+local insts = {
+ { nop = {} },
+ {
+ Type = {
+ {
+ BasicType = {
+ hoistable = true,
+ { Void = { struct_name = "VoidType" } },
+ { Bool = { struct_name = "BoolType" } },
+ { Int8 = { struct_name = "Int8Type" } },
+ { Int16 = { struct_name = "Int16Type" } },
+ { Int = { struct_name = "IntType" } },
+ { Int64 = { struct_name = "Int64Type" } },
+ { UInt8 = { struct_name = "UInt8Type" } },
+ { UInt16 = { struct_name = "UInt16Type" } },
+ { UInt = { struct_name = "UIntType" } },
+ { UInt64 = { struct_name = "UInt64Type" } },
+ { Half = { struct_name = "HalfType" } },
+ { Float = { struct_name = "FloatType" } },
+ { Double = { struct_name = "DoubleType" } },
+ { Char = { struct_name = "CharType" } },
+ { IntPtr = { struct_name = "IntPtrType" } },
+ { UIntPtr = { struct_name = "UIntPtrType" } },
+ },
+ },
+ { AfterBaseType = {} },
+ {
+ StringTypeBase = {
+ hoistable = true,
+ { String = { struct_name = "StringType" } },
+ { NativeString = { struct_name = "NativeStringType" } },
+ },
+ },
+ { CapabilitySet = { struct_name = "CapabilitySetType", hoistable = true } },
+ { DynamicType = { hoistable = true } },
+ { AnyValueType = { min_operands = 1, hoistable = true } },
+ {
+ RawPointerTypeBase = {
+ hoistable = true,
+ { RawPointerType = {} },
+ { RTTIPointerType = { min_operands = 1 } },
+ { AfterRawPointerTypeBase = {} },
+ },
+ },
+ {
+ ArrayTypeBase = {
+ hoistable = true,
+ { Array = { struct_name = "ArrayType", min_operands = 2 } },
+ { UnsizedArray = { struct_name = "UnsizedArrayType", min_operands = 1 } },
+ },
+ },
+ { Func = { struct_name = "FuncType", hoistable = true } },
+ { BasicBlock = { struct_name = "BasicBlockType", hoistable = true } },
+ { Vec = { struct_name = "VectorType", min_operands = 2, hoistable = true } },
+ { Mat = { struct_name = "MatrixType", min_operands = 4, hoistable = true } },
+ { Conjunction = { struct_name = "ConjunctionType", hoistable = true } },
+ { Attributed = { struct_name = "AttributedType", hoistable = true } },
+ { Result = { struct_name = "ResultType", min_operands = 2, hoistable = true } },
+ { Optional = { struct_name = "OptionalType", min_operands = 1, hoistable = true } },
+ { Enum = { struct_name = "EnumType", min_operands = 1, parent = true } },
+ {
+ DifferentialPairTypeBase = {
+ hoistable = true,
+ { DiffPair = { struct_name = "DifferentialPairType", min_operands = 1 } },
+ { DiffPairUserCode = { struct_name = "DifferentialPairUserCodeType", min_operands = 1 } },
+ { DiffRefPair = { struct_name = "DifferentialPtrPairType", min_operands = 1 } },
+ },
+ },
+ {
+ BwdDiffIntermediateCtxType = {
+ struct_name = "BackwardDiffIntermediateContextType",
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ { TensorView = { struct_name = "TensorViewType", min_operands = 1, hoistable = true } },
+ { TorchTensor = { struct_name = "TorchTensorType", hoistable = true } },
+ { ArrayListVector = { struct_name = "ArrayListType", min_operands = 1, hoistable = true } },
+ { Atomic = { struct_name = "AtomicType", min_operands = 1, hoistable = true } },
+ {
+ BindExistentialsTypeBase = {
+ hoistable = true,
+ {
+ BindExistentials = {
+ -- A `BindExistentials<B, T0,w0, T1,w1, ...>` represents
+ -- taking type `B` and binding each of its existential type
+ -- parameters, recursively, with the specified arguments,
+ -- where each `Ti, wi` pair represents the concrete type
+ -- and witness table to plug in for parameter `i`.
+ struct_name = "BindExistentialsType",
+ min_operands = 1,
+ },
+ },
+ {
+ BoundInterface = {
+ -- An `BindInterface<B, T0, w0>` represents the special case
+ -- of a `BindExistentials` where the type `B` is known to be
+ -- an interface type.
+ struct_name = "BoundInterfaceType",
+ min_operands = 3,
+ },
+ },
+ },
+ },
+ {
+ Rate = {
+ hoistable = true,
+ { ConstExpr = { struct_name = "ConstExprRate" } },
+ { SpecConst = { struct_name = "SpecConstRate" } },
+ { GroupShared = { struct_name = "GroupSharedRate" } },
+ { ActualGlobalRate = {} },
+ },
+ },
+ { RateQualified = { struct_name = "RateQualifiedType", min_operands = 2, hoistable = true } },
+ {
+ Kind = {
+ -- Kinds represent the "types of types."
+ -- They should not really be nested under `IRType`
+ -- in the overall hierarchy, but we can fix that later.
+ hoistable = true,
+ { Type = { struct_name = "TypeKind" } },
+ { TypeParameterPack = { struct_name = "TypeParameterPackKind" } },
+ { Rate = { struct_name = "RateKind" } },
+ { Generic = { struct_name = "GenericKind" } },
+ },
+ },
+ {
+ PtrTypeBase = {
+ hoistable = true,
+ { Ptr = { struct_name = "PtrType", min_operands = 1 } },
+ { Ref = { struct_name = "RefType", min_operands = 1 } },
+ { ConstRef = { struct_name = "ConstRefType", min_operands = 1 } },
+ {
+ PseudoPtr = {
+ -- A `PsuedoPtr<T>` logically represents a pointer to a value of type
+ -- `T` on a platform that cannot support pointers. The expectation
+ -- is that the "pointer" will be legalized away by storing a value
+ -- of type `T` somewhere out-of-line.
+ struct_name = "PseudoPtrType",
+ min_operands = 1,
+ },
+ },
+ {
+ OutTypeBase = {
+ { Out = { struct_name = "OutType", min_operands = 1 } },
+ { InOut = { struct_name = "InOutType", min_operands = 1 } },
+ },
+ },
+ },
+ },
+ {
+ ComPtr = {
+ -- A ComPtr<T> type is treated as a opaque type that represents a reference-counted handle to a COM object.
+ struct_name = "ComPtrType",
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ {
+ NativePtr = {
+ -- A NativePtr<T> type represents a native pointer to a managed resource.
+ struct_name = "NativePtrType",
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ {
+ DescriptorHandle = {
+ -- A DescriptorHandle<T> type represents a bindless handle to an opaue resource type.
+ struct_name = "DescriptorHandleType",
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ {
+ GLSLAtomicUint = {
+ -- An AtomicUint is a placeholder type for a storage buffer, and will be mangled during compiling.
+ struct_name = "GLSLAtomicUintType",
+ hoistable = true,
+ },
+ },
+ {
+ SamplerStateTypeBase = {
+ hoistable = true,
+ { SamplerState = { struct_name = "SamplerStateType" } },
+ { SamplerComparisonState = { struct_name = "SamplerComparisonStateType" } },
+ },
+ },
+ { DefaultLayout = { struct_name = "DefaultBufferLayoutType", hoistable = true } },
+ { Std140Layout = { struct_name = "Std140BufferLayoutType", hoistable = true } },
+ { Std430Layout = { struct_name = "Std430BufferLayoutType", hoistable = true } },
+ { ScalarLayout = { struct_name = "ScalarBufferLayoutType", hoistable = true } },
+ { SubpassInputType = { min_operands = 2, hoistable = true } },
+ { TextureFootprintType = { min_operands = 1, hoistable = true } },
+ { TextureShape1DType = { hoistable = true } },
+ { TextureShape2DType = { struct_name = "TextureShape2DType", hoistable = true } },
+ { TextureShape3DType = { struct_name = "TextureShape3DType", hoistable = true } },
+ { TextureShapeCubeDType = { struct_name = "TextureShapeCubeType", hoistable = true } },
+ { TextureShapeBufferType = { hoistable = true } },
+ {
+ ResourceTypeBase = {
+ -- TODO: Why do we have all this hierarchy here, when everything
+ -- that actually matters is currently nested under `TextureTypeBase`?
+ {
+ ResourceType = {
+ {
+ TextureTypeBase = {
+ {
+ TextureType = { min_operands = 8, hoistable = true },
+ },
+ { GLSLImageType = { use_other = true, hoistable = true } },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ UntypedBufferResourceType = {
+ hoistable = true,
+ {
+ ByteAddressBufferTypeBase = {
+ { ByteAddressBuffer = { struct_name = "HLSLByteAddressBufferType" } },
+ { RWByteAddressBuffer = { struct_name = "HLSLRWByteAddressBufferType" } },
+ {
+ RasterizerOrderedByteAddressBuffer = {
+ struct_name = "HLSLRasterizerOrderedByteAddressBufferType",
+ },
+ },
+ },
+ },
+ { RaytracingAccelerationStructure = { struct_name = "RaytracingAccelerationStructureType" } },
+ },
+ },
+ {
+ HLSLPatchType = {
+ hoistable = true,
+ { InputPatch = { struct_name = "HLSLInputPatchType", min_operands = 2 } },
+ { OutputPatch = { struct_name = "HLSLOutputPatchType", min_operands = 2 } },
+ },
+ },
+ { GLSLInputAttachment = { struct_name = "GLSLInputAttachmentType", hoistable = true } },
+ {
+ BuiltinGenericType = {
+ hoistable = true,
+ {
+ HLSLStreamOutputType = {
+ { PointStream = { struct_name = "HLSLPointStreamType", min_operands = 1 } },
+ { LineStream = { struct_name = "HLSLLineStreamType", min_operands = 1 } },
+ { TriangleStream = { struct_name = "HLSLTriangleStreamType", min_operands = 1 } },
+ },
+ },
+ {
+ MeshOutputType = {
+ { Vertices = { struct_name = "VerticesType", min_operands = 2 } },
+ { Indices = { struct_name = "IndicesType", min_operands = 2 } },
+ { Primitives = { struct_name = "PrimitivesType", min_operands = 2 } },
+ },
+ },
+ { ["metal::mesh"] = { struct_name = "MetalMeshType", min_operands = 5 } },
+ { mesh_grid_properties = { struct_name = "MetalMeshGridPropertiesType" } },
+ {
+ HLSLStructuredBufferTypeBase = {
+ { StructuredBuffer = { struct_name = "HLSLStructuredBufferType" } },
+ { RWStructuredBuffer = { struct_name = "HLSLRWStructuredBufferType" } },
+ {
+ RasterizerOrderedStructuredBuffer = {
+ struct_name = "HLSLRasterizerOrderedStructuredBufferType",
+ },
+ },
+ { AppendStructuredBuffer = { struct_name = "HLSLAppendStructuredBufferType" } },
+ { ConsumeStructuredBuffer = { struct_name = "HLSLConsumeStructuredBufferType" } },
+ },
+ },
+ {
+ PointerLikeType = {
+ {
+ ParameterGroupType = {
+ {
+ UniformParameterGroupType = {
+ {
+ ConstantBuffer = {
+ struct_name = "ConstantBufferType",
+ min_operands = 1,
+ },
+ },
+ { TextureBuffer = { struct_name = "TextureBufferType", min_operands = 1 } },
+ {
+ ParameterBlock = {
+ struct_name = "ParameterBlockType",
+ min_operands = 1,
+ },
+ },
+ },
+ },
+ {
+ VaryingParameterGroupType = {
+ {
+ GLSLInputParameterGroup = {
+ struct_name = "GLSLInputParameterGroupType",
+ },
+ },
+ {
+ GLSLOutputParameterGroup = {
+ struct_name = "GLSLOutputParameterGroupType",
+ },
+ },
+ },
+ },
+ {
+ GLSLShaderStorageBuffer = {
+ struct_name = "GLSLShaderStorageBufferType",
+ min_operands = 1,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ RayQuery = {
+ -- Types
+ struct_name = "RayQueryType",
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ {
+ HitObject = {
+ struct_name = "HitObjectType",
+ hoistable = true,
+ },
+ },
+ { CoopVectorType = { min_operands = 2, hoistable = true } },
+ { CoopMatrixType = { min_operands = 5, hoistable = true } },
+ {
+ TensorAddressingTensorLayoutType = { min_operands = 2, hoistable = true },
+ },
+ {
+ TensorAddressingTensorViewType = {
+ min_operands = 3,
+ hoistable = true,
+ },
+ },
+ { MakeTensorAddressingTensorLayout = {} },
+ { MakeTensorAddressingTensorView = {} },
+ {
+ DynamicResource = {
+ -- Opaque type that can be dynamically cast to other resource types.
+ struct_name = "DynamicResourceType",
+ hoistable = true,
+ },
+ },
+ {
+ struct = {
+ -- A user-defined structure declaration at the IR level.
+ -- Unlike in the AST where there is a distinction between
+ -- a `StructDecl` and a `DeclRefType` that refers to it,
+ -- at the IR level the struct declaration and the type
+ -- are the same IR instruction.
+ --
+ -- This is a parent instruction that holds zero or more
+ -- `field` instructions.
+ struct_name = "StructType",
+ parent = true,
+ },
+ },
+ {
+ class = { struct_name = "ClassType", parent = true },
+ },
+ { interface = { struct_name = "InterfaceType", global = true } },
+ { associated_type = { hoistable = true } },
+ { this_type = { hoistable = true } },
+ { rtti_type = { struct_name = "RTTIType", hoistable = true } },
+ {
+ rtti_handle_type = {
+ struct_name = "RTTIHandleType",
+ hoistable = true,
+ },
+ },
+ {
+ TupleTypeBase = {
+ hoistable = true,
+ { tuple_type = {} },
+ { TypePack = {} },
+ },
+ },
+ { TargetTuple = { struct_name = "TargetTupleType", hoistable = true } },
+ { ExpandTypeOrVal = { min_operands = 1, hoistable = true } },
+ {
+ spirvLiteralType = {
+ -- A type that identifies it's contained type as being emittable as `spirv_literal.
+ struct_name = "SPIRVLiteralType",
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ {
+ type_t = {
+ -- A TypeType-typed IRValue represents a IRType.
+ -- It is used to represent a type parameter/argument in a generics.
+ struct_name = "TypeType",
+ hoistable = true,
+ },
+ },
+ {
+ WitnessTableTypeBase = {
+ -- IRWitnessTableTypeBase
+ hoistable = true,
+ {
+ witness_table_t = {
+ -- An `IRWitnessTable` has type `WitnessTableType`.
+ struct_name = "WitnessTableType",
+ min_operands = 1,
+ },
+ },
+ {
+ witness_table_id_t = {
+ -- An integer type representing a witness table for targets where
+ -- witness tables are represented as integer IDs. This type is used
+ -- during the lower-generics pass while generating dynamic dispatch
+ -- code and will eventually lower into an uint type.
+ struct_name = "WitnessTableIDType",
+ min_operands = 1,
+ },
+ },
+ },
+ },
+ },
+ },
+ -- IRGlobalValueWithCode
+ {
+ GlobalValueWithCode = {
+ {
+ GlobalValueWithParams = {
+ -- IRGlobalValueWithParams
+ parent = true,
+ { func = {} },
+ { generic = {} },
+ },
+ },
+ { global_var = { global = true } },
+ },
+ },
+ { global_param = { global = true } },
+ {
+ globalConstant = { global = true },
+ },
+ { key = { struct_name = "StructKey", global = true } },
+ { global_generic_param = { global = true } },
+ { witness_table = { hoistable = true } },
+ { indexedFieldKey = { min_operands = 2, hoistable = true } },
+ -- A placeholder witness that ThisType implements the enclosing interface.
+ -- Used only in interface definitions.
+ { thisTypeWitness = { min_operands = 1 } },
+ -- A placeholder witness for the fact that two types are equal.
+ { TypeEqualityWitness = { min_operands = 2, hoistable = true } },
+ { global_hashed_string_literals = {} },
+ {
+ module = { struct_name = "ModuleInst", parent = true },
+ },
+ { block = { parent = true } },
+ -- IRConstant
+ {
+ Constant = {
+ { boolConst = { struct_name = "BoolLit" } },
+ {
+ integer_constant = { struct_name = "IntLit" },
+ },
+ { float_constant = { struct_name = "FloatLit" } },
+ {
+ ptr_constant = { struct_name = "PtrLit" },
+ },
+ { string_constant = { struct_name = "StringLit" } },
+ {
+ blob_constant = { struct_name = "BlobLit" },
+ },
+ { void_constant = { struct_name = "VoidLit" } },
+ },
+ },
+ { CapabilitySet = { hoistable = true, { capabilityConjunction = {} }, { capabilityDisjunction = {} } } },
+ { undefined = {} },
+ -- A `defaultConstruct` operation creates an initialized
+ -- value of the result type, and can only be used for types
+ -- where default construction is a meaningful thing to do.
+ { defaultConstruct = {} },
+ {
+ MakeDifferentialPairBase = {
+ { MakeDiffPair = { struct_name = "MakeDifferentialPair", min_operands = 2 } },
+ { MakeDiffPairUserCode = { struct_name = "MakeDifferentialPairUserCode", min_operands = 2 } },
+ {
+ MakeDiffRefPair = { struct_name = "MakeDifferentialPtrPair", min_operands = 2 },
+ },
+ },
+ },
+ {
+ DifferentialPairGetDifferentialBase = {
+ { GetDifferential = { struct_name = "DifferentialPairGetDifferential", min_operands = 1 } },
+ {
+ GetDifferentialUserCode = { struct_name = "DifferentialPairGetDifferentialUserCode", min_operands = 1 },
+ },
+ {
+ GetDifferentialPtr = {
+ struct_name = "DifferentialPtrPairGetDifferential",
+ min_operands = 1,
+ },
+ },
+ },
+ },
+ {
+ DifferentialPairGetPrimalBase = {
+ {
+ GetPrimal = { struct_name = "DifferentialPairGetPrimal", min_operands = 1 },
+ },
+ {
+ GetPrimalUserCode = {
+ struct_name = "DifferentialPairGetPrimalUserCode",
+ min_operands = 1,
+ },
+ },
+ { GetPrimalRef = { struct_name = "DifferentialPtrPairGetPrimal", min_operands = 1 } },
+ },
+ },
+ { specialize = { min_operands = 2, hoistable = true } },
+ { lookupWitness = { struct_name = "LookupWitnessMethod", min_operands = 2, hoistable = true } },
+ { GetSequentialID = { min_operands = 1, hoistable = true } },
+ {
+ bind_global_generic_param = {
+ min_operands = 2,
+ },
+ },
+ { allocObj = {} },
+ { globalValueRef = { min_operands = 1 } },
+ { makeUInt64 = { min_operands = 2 } },
+ { makeVector = {} },
+ { makeMatrix = {} },
+ {
+ makeMatrixFromScalar = {
+ min_operands = 1,
+ },
+ },
+ { matrixReshape = { min_operands = 1 } },
+ {
+ vectorReshape = {
+ min_operands = 1,
+ },
+ },
+ { makeArray = {} },
+ { makeArrayFromElement = { min_operands = 1 } },
+ { makeCoopVector = {} },
+ { makeCoopVectorFromValuePack = { min_operands = 1 } },
+ { makeStruct = {} },
+ { makeTuple = {} },
+ { makeTargetTuple = { struct_name = "MakeTargetTuple" } },
+ { makeValuePack = {} },
+ { getTargetTupleElement = {} },
+ {
+ getTupleElement = {
+ min_operands = 2,
+ },
+ },
+ { LoadResourceDescriptorFromHeap = { min_operands = 1 } },
+ {
+ LoadSamplerDescriptorFromHeap = {
+ min_operands = 1,
+ },
+ },
+ { MakeCombinedTextureSamplerFromHandle = { min_operands = 1 } },
+ {
+ MakeWitnessPack = {
+ hoistable = true,
+ },
+ },
+ { Expand = { min_operands = 1 } },
+ {
+ Each = {
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ { makeResultValue = { min_operands = 1 } },
+ { makeResultError = { min_operands = 1 } },
+ { isResultError = { min_operands = 1 } },
+ { getResultError = { min_operands = 1 } },
+ { getResultValue = { min_operands = 1 } },
+ { getOptionalValue = { min_operands = 1 } },
+ { optionalHasValue = { min_operands = 1 } },
+ { makeOptionalValue = { min_operands = 1 } },
+ { makeOptionalNone = { min_operands = 1 } },
+ { CombinedTextureSamplerGetTexture = { min_operands = 1 } },
+ { CombinedTextureSamplerGetSampler = { min_operands = 1 } },
+ { call = { min_operands = 1 } },
+ { rtti_object = { struct_name = "RTTIObject" } },
+ { alloca = { min_operands = 1 } },
+ { updateElement = { min_operands = 2 } },
+ { detachDerivative = { min_operands = 1 } },
+ { bitfieldExtract = { min_operands = 3 } },
+ { bitfieldInsert = { min_operands = 4 } },
+ { packAnyValue = { min_operands = 1 } },
+ { unpackAnyValue = { min_operands = 1 } },
+ { witness_table_entry = { min_operands = 2 } },
+ { interface_req_entry = { struct_name = "InterfaceRequirementEntry", min_operands = 2, global = true } },
+ -- An inst to represent the workgroup size of the calling entry point.
+ -- We will materialize this inst during `translateGlobalVaryingVar`.
+ { GetWorkGroupSize = { hoistable = true } },
+ -- An inst that returns the current stage of the calling entry point.
+ { GetCurrentStage = {} },
+ { param = {} },
+ { field = { struct_name = "StructField", min_operands = 2 } },
+ { var = {} },
+ { load = { min_operands = 1 } },
+ { store = { min_operands = 2 } },
+ -- Atomic Operations
+ {
+ AtomicOperation = {
+ { atomicLoad = { min_operands = 1 } },
+ {
+ atomicStore = { min_operands = 2 },
+ },
+ { atomicExchange = { min_operands = 2 } },
+ {
+ atomicCompareExchange = { min_operands = 3 },
+ },
+ { atomicAdd = { min_operands = 2 } },
+ {
+ atomicSub = { min_operands = 2 },
+ },
+ { atomicAnd = { min_operands = 2 } },
+ {
+ atomicOr = { min_operands = 2 },
+ },
+ { atomicXor = { min_operands = 2 } },
+ {
+ atomicMin = { min_operands = 2 },
+ },
+ { atomicMax = { min_operands = 2 } },
+ {
+ atomicInc = { min_operands = 1 },
+ },
+ { atomicDec = { min_operands = 1 } },
+ },
+ },
+ -- Produced and removed during backward auto-diff pass as a temporary placeholder representing the
+ -- currently accumulated derivative to pass to some dOut argument in a nested call.
+ { LoadReverseGradient = { min_operands = 1 } },
+ -- Produced and removed during backward auto-diff pass as a temporary placeholder containing the
+ -- primal and accumulated derivative values to pass to an inout argument in a nested call.
+ { ReverseGradientDiffPairRef = { min_operands = 2 } },
+ -- Produced and removed during backward auto-diff pass. This inst is generated by the splitting step
+ -- to represent a reference to an inout parameter for use in the primal part of the computation.
+ { PrimalParamRef = { min_operands = 1 } },
+ -- Produced and removed during backward auto-diff pass. This inst is generated by the splitting step
+ -- to represent a reference to an inout parameter for use in the back-prop part of the computation.
+ { DiffParamRef = { min_operands = 1 } },
+ -- Check that the value is a differential null value.
+ { IsDifferentialNull = { min_operands = 1 } },
+ {
+ get_field = {
+ struct_name = "FieldExtract",
+ min_operands = 2,
+ },
+ },
+ { get_field_addr = { struct_name = "FieldAddress", min_operands = 2 } },
+ { getElement = { min_operands = 2 } },
+ { getElementPtr = { min_operands = 2 } },
+ -- Pointer offset: computes pBase + offset_in_elements
+ { getOffsetPtr = { min_operands = 2 } },
+ { getAddr = { struct_name = "GetAddress", min_operands = 1 } },
+ { castDynamicResource = { min_operands = 1 } },
+ -- Get an unowned NativeString from a String.
+ { getNativeStr = { min_operands = 1 } },
+ -- Make String from a NativeString.
+ { makeString = { min_operands = 1 } },
+ -- Get a native ptr from a ComPtr or RefPtr
+ { getNativePtr = { min_operands = 1 } },
+ -- Get a write reference to a managed ptr var (operand must be Ptr<ComPtr<T>> or Ptr<RefPtr<T>>).
+ { getManagedPtrWriteRef = { min_operands = 1 } },
+ -- Attach a managedPtr var to a NativePtr without changing its ref count.
+ { ManagedPtrAttach = { min_operands = 1 } },
+ -- Attach a managedPtr var to a NativePtr without changing its ref count.
+ { ManagedPtrDetach = { min_operands = 1 } },
+ -- "Subscript" an image at a pixel coordinate to get pointer
+ { imageSubscript = { min_operands = 2 } },
+ -- Load from an Image.
+ { imageLoad = { min_operands = 2 } },
+ -- Store into an Image.
+ { imageStore = { min_operands = 3 } },
+ -- Load (almost) arbitrary-type data from a byte-address buffer
+ -- %dst = byteAddressBufferLoad(%buffer, %offset, %alignment)
+ -- where
+ -- - `buffer` is a value of some `ByteAddressBufferTypeBase` type
+ -- - `offset` is an `int`
+ -- - `alignment` is an `int`
+ -- - `dst` is a value of some type containing only ordinary data
+ { byteAddressBufferLoad = { min_operands = 3 } },
+ -- Store (almost) arbitrary-type data to a byte-address buffer
+ -- byteAddressBufferLoad(%buffer, %offset, %alignment, %src)
+ -- where
+ -- - `buffer` is a value of some `ByteAddressBufferTypeBase` type
+ -- - `offset` is an `int`
+ -- - `alignment` is an `int`
+ -- - `src` is a value of some type containing only ordinary data
+ { byteAddressBufferStore = { min_operands = 4 } },
+ -- Load data from a structured buffer
+ -- %dst = structuredBufferLoad(%buffer, %index)
+ -- where
+ -- - `buffer` is a value of some `StructuredBufferTypeBase` type with element type T
+ -- - `offset` is an `int`
+ -- - `dst` is a value of type T
+ { structuredBufferLoad = { min_operands = 2 } },
+ { structuredBufferLoadStatus = { min_operands = 3 } },
+ { rwstructuredBufferLoad = { struct_name = "RWStructuredBufferLoad", min_operands = 2 } },
+ {
+ rwstructuredBufferLoadStatus = {
+ struct_name = "RWStructuredBufferLoadStatus",
+ min_operands = 3,
+ },
+ },
+ -- Store data to a structured buffer
+ -- structuredBufferLoad(%buffer, %offset, %src)
+ -- where
+ -- - `buffer` is a value of some `StructuredBufferTypeBase` type with element type T
+ -- - `offset` is an `int`
+ -- - `src` is a value of type T
+ { rwstructuredBufferStore = { struct_name = "RWStructuredBufferStore", min_operands = 3 } },
+ {
+ rwstructuredBufferGetElementPtr = {
+ struct_name = "RWStructuredBufferGetElementPtr",
+ min_operands = 2,
+ },
+ },
+ -- Append/Consume-StructuredBuffer operations
+ { StructuredBufferAppend = { min_operands = 1 } },
+ { StructuredBufferConsume = { min_operands = 1 } },
+ { StructuredBufferGetDimensions = { min_operands = 1 } },
+ -- Resource qualifiers for dynamically varying index
+ { nonUniformResourceIndex = { min_operands = 1 } },
+ { getNaturalStride = { min_operands = 1 } },
+ { meshOutputRef = { min_operands = 2 } },
+ { meshOutputSet = { min_operands = 3 } },
+ -- only two parameters as they are effectively static
+ -- TODO: make them reference the _slang_mesh object directly
+ { metalSetVertex = { min_operands = 2 } },
+ { metalSetPrimitive = { min_operands = 2 } },
+ { metalSetIndices = { min_operands = 2 } },
+ { MetalCastToDepthTexture = { min_operands = 1 } },
+ -- Construct a vector from a scalar
+ -- %dst = MakeVectorFromScalar %T %N %val
+ -- where
+ -- - `T` is a `Type`
+ -- - `N` is a (compile-time) `Int`
+ -- - `val` is a `T`
+ -- - dst is a `Vec<T,N>`
+ { MakeVectorFromScalar = { min_operands = 3 } },
+ -- A swizzle of a vector:
+ -- %dst = swizzle %src %idx0 %idx1 ...
+ -- where:
+ -- - `src` is a vector<T,N>
+ -- - `dst` is a vector<T,M>
+ -- - `idx0` through `idx[M-1]` are literal integers
+ { swizzle = { min_operands = 1 } },
+ -- Setting a vector via swizzle
+ --
+ -- %dst = swizzle %base %src %idx0 %idx1 ...
+ --
+ -- where:
+ -- - `base` is a vector<T,N>
+ -- - `dst` is a vector<T,N>
+ -- - `src` is a vector<T,M>
+ -- - `idx0` through `idx[M-1]` are literal integers
+ --
+ -- The semantics of the op is:
+ --
+ -- dst = base;
+ -- for(ii : 0 ... M-1 )
+ -- dst[ii] = src[idx[ii]];
+ { swizzleSet = { min_operands = 2 } },
+ -- Store to memory with a swizzle
+ --
+ -- TODO: eventually this should be reduced to just
+ -- a write mask by moving the actual swizzle to the RHS.
+ --
+ -- swizzleStore %dst %src %idx0 %idx1 ...
+ --
+ -- where:
+ -- - `dst` is a vector<T,N>
+ -- - `src` is a vector<T,M>
+ -- - `idx0` through `idx[M-1]` are literal integers
+ --
+ -- The semantics of the op is:
+ --
+ -- for(ii : 0 ... M-1 )
+ -- dst[ii] = src[idx[ii]];
+ { swizzledStore = { min_operands = 2 } },
+ {
+ TerminatorInst = {
+ { return_val = { struct_name = "Return", min_operands = 1 } },
+ { yield = { min_operands = 1 } },
+ {
+ UnconditionalBranch = {
+ -- IRUnconditionalBranch
+ {
+ unconditionalBranch = {
+ -- unconditionalBranch <target>
+ min_operands = 1,
+ },
+ },
+ {
+ loop = {
+ -- loop <target> <breakLabel> <continueLabel>
+ min_operands = 3,
+ },
+ },
+ },
+ },
+ {
+ ConditionalBranch = {
+ -- IRTerminatorInst
+ {
+ conditionalBranch = {
+ -- conditionalBranch <condition> <trueBlock> <falseBlock>
+ struct_name = "ConditionalBranch",
+ min_operands = 3,
+ },
+ },
+ {
+ ifElse = {
+ -- ifElse <condition> <trueBlock> <falseBlock> <mergeBlock>
+ struct_name = "IfElse",
+ min_operands = 4,
+ },
+ },
+ },
+ },
+ {
+ throw = {
+ -- IRConditionalbranch
+ min_operands = 1,
+ },
+ },
+ {
+ tryCall = {
+ -- tryCall <successBlock> <failBlock> <callee> <args>...
+ min_operands = 3,
+ },
+ },
+ {
+ switch = {
+ -- switch <val> <break> <default> <caseVal1> <caseBlock1> ...
+ min_operands = 3,
+ },
+ },
+ {
+ targetSwitch = {
+ -- target_switch <break> <targetName1> <block1> ...
+ min_operands = 1,
+ },
+ },
+ {
+ GenericAsm = {
+ -- A generic asm inst has an return semantics that terminates the control flow.
+ min_operands = 1,
+ },
+ },
+ {
+ Unreachable = {
+ {
+ missingReturn = {
+ -- IRUnreachable
+ },
+ },
+ { unreachable = {} },
+ },
+ },
+ { defer = { min_operands = 3 } },
+ },
+ },
+ { discard = {} },
+ {
+ RequirePrelude = { min_operands = 1 },
+ },
+ { RequireTargetExtension = { min_operands = 1 } },
+ { RequireComputeDerivative = {} },
+ { StaticAssert = { min_operands = 2 } },
+ { Printf = { min_operands = 1 } },
+ -- Quad control execution modes.
+ { RequireMaximallyReconverges = {} },
+ { RequireQuadDerivatives = {} },
+ -- TODO: We should consider splitting the basic arithmetic/comparison
+ -- ops into cases for signed integers, unsigned integers, and floating-point
+ -- values, to better match downstream targets that want to treat them
+ -- all differently ().
+ { add = { min_operands = 2 } },
+ { sub = { min_operands = 2 } },
+ { mul = { min_operands = 2 } },
+ { div = { min_operands = 2 } },
+ -- Remainder of division.
+ -- Note: this is distinct from modulus, and we should have a separate
+ -- opcode for `mod` if we ever need to support it.
+ { irem = { struct_name = "IRem", min_operands = 2 } },
+ {
+ frem = {
+ struct_name = "FRem",
+ min_operands = 2,
+ },
+ },
+ {
+ shl = { struct_name = "Lsh", min_operands = 2 },
+ },
+ { shr = { struct_name = "Rsh", min_operands = 2 } },
+ { cmpEQ = { struct_name = "Eql", min_operands = 2 } },
+ {
+ cmpNE = {
+ struct_name = "Neq",
+ min_operands = 2,
+ },
+ },
+ {
+ cmpGT = { struct_name = "Greater", min_operands = 2 },
+ },
+ { cmpLT = { struct_name = "Less", min_operands = 2 } },
+ { cmpGE = { struct_name = "Geq", min_operands = 2 } },
+ {
+ cmpLE = {
+ struct_name = "Leq",
+ min_operands = 2,
+ },
+ },
+ {
+ ["and"] = { struct_name = "BitAnd", min_operands = 2 },
+ },
+ { xor = { struct_name = "BitXor", min_operands = 2 } },
+ { ["or"] = { struct_name = "BitOr", min_operands = 2 } },
+ {
+ logicalAnd = {
+ struct_name = "And",
+ min_operands = 2,
+ },
+ },
+ {
+ logicalOr = { struct_name = "Or", min_operands = 2 },
+ },
+ { neg = { min_operands = 1 } },
+ {
+ ["not"] = { min_operands = 1 },
+ },
+ { bitnot = { struct_name = "BitNot", min_operands = 1 } },
+ { select = { min_operands = 3 } },
+ {
+ checkpointObj = {
+ struct_name = "CheckpointObject",
+ min_operands = 1,
+ },
+ },
+ { loopExitValue = { min_operands = 1 } },
+ {
+ getStringHash = {
+ min_operands = 1,
+ },
+ },
+ { waveGetActiveMask = {} },
+ -- trueMask = waveMaskBallot(mask, condition)
+ { waveMaskBallot = { min_operands = 2 } },
+ -- matchMask = waveMaskBallot(mask, value)
+ { waveMaskMatch = { min_operands = 2 } },
+ -- Texture sampling operation of the form `t.Sample(s,u)`
+ { sample = { min_operands = 3 } },
+ { sampleGrad = { min_operands = 4 } },
+ { GroupMemoryBarrierWithGroupSync = {} },
+ { ControlBarrier = {} },
+ -- GPU_FOREACH loop of the form
+ { gpuForeach = { min_operands = 3 } },
+ -- Wrapper for OptiX intrinsics used to load and store ray payload data using
+ -- a pointer represented by two payload registers.
+ { getOptiXRayPayloadPtr = { hoistable = true } },
+ -- Wrapper for OptiX intrinsics used to load a single hit attribute
+ -- Takes two arguments: the type (either float or int), and the hit
+ -- attribute index
+ { getOptiXHitAttribute = { min_operands = 2 } },
+ -- Wrapper for OptiX intrinsics used to load shader binding table record data
+ -- using a pointer.
+ { getOptiXSbtDataPointer = { struct_name = "GetOptiXSbtDataPtr" } },
+ { GetVulkanRayTracingPayloadLocation = { min_operands = 1 } },
+ { GetLegalizedSPIRVGlobalParamAddr = { min_operands = 1 } },
+ {
+ GetPerVertexInputArray = {
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ { ResolveVaryingInputRef = { min_operands = 1, hoistable = true } },
+ {
+ ForceVarIntoStructTemporarilyBase = {
+ { ForceVarIntoStructTemporarily = { min_operands = 1 } },
+ {
+ ForceVarIntoRayPayloadStructTemporarily = {
+ min_operands = 1,
+ },
+ },
+ },
+ },
+ { MetalAtomicCast = { min_operands = 1 } },
+ { IsTextureAccess = { min_operands = 1 } },
+ { IsTextureScalarAccess = { min_operands = 1 } },
+ { IsTextureArrayAccess = { min_operands = 1 } },
+ { ExtractTextureFromTextureAccess = { min_operands = 1 } },
+ { ExtractCoordFromTextureAccess = { min_operands = 1 } },
+ { ExtractArrayCoordFromTextureAccess = { min_operands = 1 } },
+ { makeArrayList = {} },
+ { makeTensorView = {} },
+ { allocTorchTensor = { struct_name = "AllocateTorchTensor" } },
+ { TorchGetCudaStream = {} },
+ { TorchTensorGetView = {} },
+ { CoopMatMapElementIFunc = { min_operands = 2 } },
+ { allocateOpaqueHandle = {} },
+ {
+ BindingQuery = {
+ {
+ getRegisterIndex = {
+ -- Return the register index thtat a resource is bound to.
+ min_operands = 1,
+ },
+ },
+ {
+ getRegisterSpace = {
+ -- Return the registe space that a resource is bound to.
+ min_operands = 1,
+ },
+ },
+ },
+ },
+ {
+ Decoration = {
+ {
+ highLevelDecl = { struct_name = "HighLevelDeclDecoration", min_operands = 1 },
+ },
+ {
+ layout = {
+ struct_name = "LayoutDecoration",
+ min_operands = 1,
+ },
+ },
+ { branch = { struct_name = "BranchDecoration" } },
+ {
+ flatten = {
+ struct_name = "FlattenDecoration",
+ },
+ },
+ { loopControl = { struct_name = "LoopControlDecoration", min_operands = 1 } },
+ { loopMaxIters = { struct_name = "LoopMaxItersDecoration", min_operands = 1 } },
+ {
+ loopExitPrimalValue = { struct_name = "LoopExitPrimalValueDecoration", min_operands = 2 },
+ },
+ {
+ intrinsicOp = {
+ struct_name = "IntrinsicOpDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ TargetSpecificDecoration = {
+ {
+ TargetSpecificDefinitionDecoration = {
+ {
+ target = { struct_name = "TargetDecoration", min_operands = 1 },
+ },
+ {
+ targetIntrinsic = {
+ struct_name = "TargetIntrinsicDecoration",
+ min_operands = 2,
+ },
+ },
+ },
+ },
+ {
+ requirePrelude = {
+ struct_name = "RequirePreludeDecoration",
+ min_operands = 2,
+ },
+ },
+ },
+ },
+ {
+ glslOuterArray = {
+ struct_name = "GLSLOuterArrayDecoration",
+ min_operands = 1,
+ },
+ },
+ { TargetSystemValue = { struct_name = "TargetSystemValueDecoration", min_operands = 2 } },
+ { interpolationMode = { struct_name = "InterpolationModeDecoration", min_operands = 1 } },
+ {
+ nameHint = { struct_name = "NameHintDecoration", min_operands = 1 },
+ },
+ {
+ PhysicalType = {
+ struct_name = "PhysicalTypeDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ AlignedAddressDecoration = {
+ -- Mark an address instruction as aligned to a specific byte boundary.
+ min_operands = 1,
+ },
+ },
+ {
+ BinaryInterfaceType = {
+ -- Marks a type as being used as binary interface (e.g. shader parameters).
+ -- This prevents the legalizeEmptyType() pass from eliminating it on C++/CUDA targets.
+ struct_name = "BinaryInterfaceTypeDecoration",
+ },
+ },
+ {
+ transitory = {
+ -- * The decorated _instruction_ is transitory. Such a decoration should NEVER be found on an output instruction a module.
+ -- Typically used mark an instruction so can be specially handled - say when creating a IRConstant literal, and the payload of
+ -- needs to be special cased for lookup.
+ struct_name = "TransitoryDecoration",
+ },
+ },
+ {
+ ResultWitness = {
+ -- The result witness table that the functon's return type is a subtype of an interface.
+ -- This is used to keep track of the original witness table in a function that used to
+ -- return an existential value but now returns a concrete type after specialization.
+ struct_name = "ResultWitnessDecoration",
+ min_operands = 1,
+ },
+ },
+ -- A decoration that indicates that a variable represents
+ -- a vulkan ray payload, and should have a location assigned
+ -- to it.
+ { vulkanRayPayload = { struct_name = "VulkanRayPayloadDecoration" } },
+ { vulkanRayPayloadIn = { struct_name = "VulkanRayPayloadInDecoration" } },
+ -- A decoration that indicates that a variable represents
+ -- vulkan hit attributes, and should have a location assigned
+ -- to it.
+ { vulkanHitAttributes = { struct_name = "VulkanHitAttributesDecoration" } },
+ -- A decoration that indicates that a variable represents
+ -- vulkan hit object attributes, and should have a location assigned
+ -- to it.
+ { vulkanHitObjectAttributes = { struct_name = "VulkanHitObjectAttributesDecoration" } },
+ { GlobalVariableShadowingGlobalParameterDecoration = { min_operands = 2 } },
+ { requireSPIRVVersion = { struct_name = "RequireSPIRVVersionDecoration", min_operands = 1 } },
+ {
+ requireGLSLVersion = {
+ struct_name = "RequireGLSLVersionDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ requireGLSLExtension = { struct_name = "RequireGLSLExtensionDecoration", min_operands = 1 },
+ },
+ { requireWGSLExtension = { struct_name = "RequireWGSLExtensionDecoration", min_operands = 1 } },
+ { requireCUDASMVersion = { struct_name = "RequireCUDASMVersionDecoration", min_operands = 1 } },
+ {
+ requireCapabilityAtom = {
+ struct_name = "RequireCapabilityAtomDecoration",
+ min_operands = 1,
+ },
+ },
+ { HasExplicitHLSLBinding = { struct_name = "HasExplicitHLSLBindingDecoration" } },
+ { DefaultValue = { struct_name = "DefaultValueDecoration", min_operands = 1 } },
+ {
+ readNone = { struct_name = "ReadNoneDecoration" },
+ },
+ -- A decoration that indicates that a variable represents
+ -- a vulkan callable shader payload, and should have a location assigned
+ -- to it.
+ { vulkanCallablePayload = { struct_name = "VulkanCallablePayloadDecoration" } },
+ { vulkanCallablePayloadIn = { struct_name = "VulkanCallablePayloadInDecoration" } },
+ { earlyDepthStencil = { struct_name = "EarlyDepthStencilDecoration" } },
+ { precise = { struct_name = "PreciseDecoration" } },
+ { public = { struct_name = "PublicDecoration" } },
+ { hlslExport = { struct_name = "HLSLExportDecoration" } },
+ { downstreamModuleExport = { struct_name = "DownstreamModuleExportDecoration" } },
+ { downstreamModuleImport = { struct_name = "DownstreamModuleImportDecoration" } },
+ { patchConstantFunc = { struct_name = "PatchConstantFuncDecoration", min_operands = 1 } },
+ {
+ maxTessFactor = {
+ struct_name = "MaxTessFactorDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ outputControlPoints = { struct_name = "OutputControlPointsDecoration", min_operands = 1 },
+ },
+ { outputTopology = { struct_name = "OutputTopologyDecoration", min_operands = 2 } },
+ { partioning = { struct_name = "PartitioningDecoration", min_operands = 1 } },
+ {
+ domain = {
+ struct_name = "DomainDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ maxVertexCount = { struct_name = "MaxVertexCountDecoration", min_operands = 1 },
+ },
+ { instance = { struct_name = "InstanceDecoration", min_operands = 1 } },
+ { numThreads = { struct_name = "NumThreadsDecoration", min_operands = 3 } },
+ { fpDenormalPreserve = { struct_name = "FpDenormalPreserveDecoration", min_operands = 1 } },
+ { fpDenormalFlushToZero = { struct_name = "FpDenormalFlushToZeroDecoration", min_operands = 1 } },
+ {
+ waveSize = {
+ struct_name = "WaveSizeDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ availableInDownstreamIR = { struct_name = "AvailableInDownstreamIRDecoration", min_operands = 1 },
+ },
+ {
+ GeometryInputPrimitiveTypeDecoration = {
+ {
+ pointPrimitiveType = {
+ -- Added to IRParam parameters to an entry point
+ struct_name = "PointInputPrimitiveTypeDecoration",
+ },
+ },
+ { linePrimitiveType = { struct_name = "LineInputPrimitiveTypeDecoration" } },
+ {
+ trianglePrimitiveType = {
+ struct_name = "TriangleInputPrimitiveTypeDecoration",
+ },
+ },
+ { lineAdjPrimitiveType = { struct_name = "LineAdjInputPrimitiveTypeDecoration" } },
+ {
+ triangleAdjPrimitiveType = {
+ struct_name = "TriangleAdjInputPrimitiveTypeDecoration",
+ },
+ },
+ },
+ },
+ { streamOutputTypeDecoration = { min_operands = 1 } },
+ {
+ entryPoint = {
+ -- An `[entryPoint]` decoration marks a function that represents a shader entry point
+ struct_name = "EntryPointDecoration",
+ min_operands = 2,
+ },
+ },
+ { CudaKernel = { struct_name = "CudaKernelDecoration" } },
+ { CudaHost = { struct_name = "CudaHostDecoration" } },
+ { TorchEntryPoint = { struct_name = "TorchEntryPointDecoration" } },
+ { AutoPyBindCUDA = { struct_name = "AutoPyBindCudaDecoration" } },
+ { CudaKernelFwdDiffRef = { struct_name = "CudaKernelForwardDerivativeDecoration" } },
+ { CudaKernelBwdDiffRef = { struct_name = "CudaKernelBackwardDerivativeDecoration" } },
+ { PyBindExportFuncInfo = { struct_name = "AutoPyBindExportInfoDecoration" } },
+ { PyExportDecoration = {} },
+ {
+ entryPointParam = {
+ -- Used to mark parameters that are moved from entry point parameters to global params as coming from the entry
+ -- point.
+ struct_name = "EntryPointParamDecoration",
+ },
+ },
+ {
+ dependsOn = {
+ -- A `[dependsOn(x)]` decoration indicates that the parent instruction depends on `x`
+ -- even if it does not otherwise reference it.
+ struct_name = "DependsOnDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ keepAlive = {
+ -- A `[keepAlive]` decoration marks an instruction that should not be eliminated.
+ struct_name = "KeepAliveDecoration",
+ },
+ },
+ {
+ noSideEffect = {
+ -- A `[NoSideEffect]` decoration marks a callee to be side-effect free.
+ struct_name = "NoSideEffectDecoration",
+ },
+ },
+ { bindExistentialSlots = { struct_name = "BindExistentialSlotsDecoration" } },
+ {
+ format = {
+ -- A `[format(f)]` decoration specifies that the format of an image should be `f`
+ struct_name = "FormatDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ unsafeForceInlineEarly = {
+ -- An `[unsafeForceInlineEarly]` decoration specifies that calls to this function should be inline after initial
+ -- codegen
+ struct_name = "UnsafeForceInlineEarlyDecoration",
+ },
+ },
+ {
+ ForceInline = {
+ -- A `[ForceInline]` decoration indicates the callee should be inlined by the Slang compiler.
+ struct_name = "ForceInlineDecoration",
+ },
+ },
+ {
+ ForceUnroll = {
+ -- A `[ForceUnroll]` decoration indicates the loop should be unrolled by the Slang compiler.
+ struct_name = "ForceUnrollDecoration",
+ },
+ },
+ {
+ SizeAndAlignment = {
+ -- A `[SizeAndAlignment(l,s,a)]` decoration is attached to a type to indicate that is has size `s` and alignment
+ -- `a` under layout rules `l`.
+ struct_name = "SizeAndAlignmentDecoration",
+ min_operands = 3,
+ },
+ },
+ {
+ Offset = {
+ -- A `[Offset(l, o)]` decoration is attached to a field to indicate that it has offset `o` in the parent type
+ -- under layout rules `l`.
+ struct_name = "OffsetDecoration",
+ min_operands = 2,
+ },
+ },
+ {
+ LinkageDecoration = {
+ {
+ import = {
+ struct_name = "ImportDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ export = { struct_name = "ExportDecoration", min_operands = 1 },
+ },
+ },
+ },
+ {
+ TargetBuiltinVar = {
+ -- Mark a global variable as a target builtin variable.
+ struct_name = "TargetBuiltinVarDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ UserExtern = {
+ -- Marks an inst as coming from an `extern` symbol defined in the user code.
+ struct_name = "UserExternDecoration",
+ },
+ },
+ {
+ externCpp = {
+ -- An extern_cpp decoration marks the inst to emit its name without mangling for C++ interop.
+ struct_name = "ExternCppDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ externC = {
+ -- An externC decoration marks a function should be emitted inside an extern "C" block.
+ struct_name = "ExternCDecoration",
+ },
+ },
+ {
+ dllImport = {
+ -- An dllImport decoration marks a function as imported from a DLL. Slang will generate dynamic function loading
+ -- logic to use this function at runtime.
+ struct_name = "DllImportDecoration",
+ min_operands = 2,
+ },
+ },
+ {
+ dllExport = {
+ -- An dllExport decoration marks a function as an export symbol. Slang will generate a native wrapper function
+ -- that is exported to DLL.
+ struct_name = "DllExportDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ cudaDeviceExport = {
+ -- An cudaDeviceExport decoration marks a function to be exported as a cuda __device__ function.
+ struct_name = "CudaDeviceExportDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ COMInterface = {
+ -- Marks an interface as a COM interface declaration.
+ struct_name = "ComInterfaceDecoration",
+ },
+ },
+ {
+ KnownBuiltinDecoration = {
+ -- Attaches a name to this instruction so that it can be identified
+ -- later in the compiler reliably
+ min_operands = 1,
+ },
+ },
+ {
+ RTTI_typeSize = {
+ -- Decorations for RTTI objects
+ struct_name = "RTTITypeSizeDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ AnyValueSize = { struct_name = "AnyValueSizeDecoration", min_operands = 1 },
+ },
+ { SpecializeDecoration = {} },
+ { SequentialIDDecoration = { min_operands = 1 } },
+ { DynamicDispatchWitnessDecoration = {} },
+ { StaticRequirementDecoration = {} },
+ { DispatchFuncDecoration = { min_operands = 1 } },
+ { TypeConstraintDecoration = { min_operands = 1 } },
+ { BuiltinDecoration = {} },
+ {
+ requiresNVAPI = {
+ -- The decorated instruction requires NVAPI to be included via prelude when compiling for D3D.
+ struct_name = "RequiresNVAPIDecoration",
+ },
+ },
+ {
+ nvapiMagic = {
+ -- The decorated instruction is part of the NVAPI "magic" and should always use its original name
+ struct_name = "NVAPIMagicDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ nvapiSlot = {
+ -- A decoration that applies to an entire IR module, and indicates the register/space binding
+ -- that the NVAPI shader parameter intends to use.
+ struct_name = "NVAPISlotDecoration",
+ min_operands = 2,
+ },
+ },
+ {
+ noInline = {
+ -- Applie to an IR function and signals that inlining should not be performed unless unavoidable.
+ struct_name = "NoInlineDecoration",
+ },
+ },
+ { noRefInline = { struct_name = "NoRefInlineDecoration" } },
+ {
+ DerivativeGroupQuad = {
+ struct_name = "DerivativeGroupQuadDecoration",
+ },
+ },
+ { DerivativeGroupLinear = { struct_name = "DerivativeGroupLinearDecoration" } },
+ {
+ MaximallyReconverges = {
+ struct_name = "MaximallyReconvergesDecoration",
+ },
+ },
+ { QuadDerivatives = { struct_name = "QuadDerivativesDecoration" } },
+ {
+ RequireFullQuads = {
+ struct_name = "RequireFullQuadsDecoration",
+ },
+ },
+ { TempCallArgVar = { struct_name = "TempCallArgVarDecoration" } },
+ {
+ nonCopyable = {
+ -- Marks a type to be non copyable, causing SSA pass to skip turning variables of the the type into SSA values.
+ struct_name = "NonCopyableTypeDecoration",
+ },
+ },
+ {
+ DynamicUniform = {
+ -- Marks a value to be dynamically uniform.
+ struct_name = "DynamicUniformDecoration",
+ },
+ },
+ {
+ alwaysFold = {
+ -- A call to the decorated function should always be folded into its use site.
+ struct_name = "AlwaysFoldIntoUseSiteDecoration",
+ },
+ },
+ { output = { struct_name = "GlobalOutputDecoration" } },
+ {
+ input = {
+ struct_name = "GlobalInputDecoration",
+ },
+ },
+ { glslLocation = { struct_name = "GLSLLocationDecoration", min_operands = 1 } },
+ { glslOffset = { struct_name = "GLSLOffsetDecoration", min_operands = 1 } },
+ {
+ vkStructOffset = { struct_name = "VkStructOffsetDecoration", min_operands = 1 },
+ },
+ { raypayload = { struct_name = "RayPayloadDecoration" } },
+ {
+ MeshOutputDecoration = {
+ -- Mesh Shader outputs
+ { vertices = { struct_name = "VerticesDecoration", min_operands = 1 } },
+ {
+ indices = {
+ struct_name = "IndicesDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ primitives = { struct_name = "PrimitivesDecoration", min_operands = 1 },
+ },
+ },
+ },
+ { HLSLMeshPayloadDecoration = { struct_name = "HLSLMeshPayloadDecoration" } },
+ { perprimitive = { struct_name = "GLSLPrimitivesRateDecoration" } },
+ {
+ PositionOutput = {
+ -- Marks an inst that represents the gl_Position output.
+ struct_name = "GLPositionOutputDecoration",
+ },
+ },
+ {
+ PositionInput = {
+ -- Marks an inst that represents the gl_Position input.
+ struct_name = "GLPositionInputDecoration",
+ },
+ },
+ {
+ PerVertex = {
+ -- Marks a fragment shader input as per-vertex.
+ struct_name = "PerVertexDecoration",
+ },
+ },
+ {
+ StageAccessDecoration = {
+ { stageReadAccess = { struct_name = "StageReadAccessDecoration" } },
+ { stageWriteAccess = { struct_name = "StageWriteAccessDecoration" } },
+ },
+ },
+ {
+ semantic = { struct_name = "SemanticDecoration", min_operands = 2 },
+ },
+ {
+ constructor = {
+ struct_name = "ConstructorDecoration",
+ min_operands = 1,
+ },
+ },
+ { method = { struct_name = "MethodDecoration" } },
+ {
+ packoffset = {
+ struct_name = "PackOffsetDecoration",
+ min_operands = 2,
+ },
+ },
+ { SpecializationConstantDecoration = { min_operands = 1 } },
+ {
+ UserTypeName = {
+ -- Reflection metadata for a shader parameter that provides the original type name.
+ struct_name = "UserTypeNameDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ CounterBuffer = {
+ -- Reflection metadata for a shader parameter that refers to the associated counter buffer of a UAV.
+ struct_name = "CounterBufferDecoration",
+ min_operands = 1,
+ },
+ },
+ { RequireSPIRVDescriptorIndexingExtensionDecoration = {} },
+ {
+ spirvOpDecoration = {
+ struct_name = "SPIRVOpDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ forwardDifferentiable = {
+ -- Decorated function is marked for the forward-mode differentiation pass.
+ struct_name = "ForwardDifferentiableDecoration",
+ },
+ },
+ {
+ AutoDiffOriginalValueDecoration = {
+ -- Decorates a auto-diff transcribed value with the original value that the inst is transcribed from.
+ min_operands = 1,
+ },
+ },
+ {
+ AutoDiffBuiltinDecoration = {
+ -- Decorates a type as auto-diff builtin type.
+ },
+ },
+ {
+ fwdDerivative = {
+ -- Used by the auto-diff pass to hold a reference to the
+ -- generated derivative function.
+ struct_name = "ForwardDerivativeDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ backwardDifferentiable = {
+ -- Used by the auto-diff pass to hold a reference to the
+ -- generated derivative function.
+ struct_name = "BackwardDifferentiableDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ primalSubstFunc = {
+ -- Used by the auto-diff pass to hold a reference to the
+ -- primal substitute function.
+ struct_name = "PrimalSubstituteDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ backwardDiffPrimalReference = {
+ -- Decorations to associate an original function with compiler generated backward derivative functions.
+ struct_name = "BackwardDerivativePrimalDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ backwardDiffPropagateReference = {
+ struct_name = "BackwardDerivativePropagateDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ backwardDiffIntermediateTypeReference = {
+ struct_name = "BackwardDerivativeIntermediateTypeDecoration",
+ min_operands = 1,
+ },
+ },
+ { backwardDiffReference = { struct_name = "BackwardDerivativeDecoration", min_operands = 1 } },
+ {
+ userDefinedBackwardDiffReference = {
+ struct_name = "UserDefinedBackwardDerivativeDecoration",
+ min_operands = 1,
+ },
+ },
+ { BackwardDerivativePrimalContextDecoration = { min_operands = 1 } },
+ { BackwardDerivativePrimalReturnDecoration = { min_operands = 1 } },
+ {
+ PrimalContextDecoration = {
+ -- Mark a parameter as autodiff primal context.
+ },
+ },
+ { loopCounterDecoration = {} },
+ { loopCounterUpdateDecoration = {} },
+ {
+ AutodiffInstDecoration = {
+ -- Auto-diff inst decorations
+ {
+ primalInstDecoration = {
+ -- Used by the auto-diff pass to mark insts that compute
+ -- a primal value.
+ },
+ },
+ {
+ diffInstDecoration = {
+ -- Used by the auto-diff pass to mark insts that compute
+ -- a differential value.
+ struct_name = "DifferentialInstDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ mixedDiffInstDecoration = {
+ -- Used by the auto-diff pass to mark insts that compute
+ -- BOTH a differential and a primal value.
+ struct_name = "MixedDifferentialInstDecoration",
+ min_operands = 1,
+ },
+ },
+ { RecomputeBlockDecoration = {} },
+ },
+ },
+ {
+ primalValueKey = {
+ -- Used by the auto-diff pass to mark insts whose result is stored
+ -- in an intermediary struct for reuse in backward propagation phase.
+ struct_name = "PrimalValueStructKeyDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ primalElementType = {
+ -- Used by the auto-diff pass to mark the primal element type of an
+ -- forward-differentiated updateElement inst.
+ struct_name = "PrimalElementTypeDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ IntermediateContextFieldDifferentialTypeDecoration = {
+ -- Used by the auto-diff pass to mark the differential type of an intermediate context field.
+ min_operands = 1,
+ },
+ },
+ {
+ derivativeMemberDecoration = {
+ -- Used by the auto-diff pass to hold a reference to a
+ -- differential member of a type in its associated differential type.
+ min_operands = 1,
+ },
+ },
+ {
+ treatAsDifferentiableDecoration = {
+ -- Treat a function as differentiable function
+ },
+ },
+ {
+ treatCallAsDifferentiableDecoration = {
+ -- Treat a call to arbitrary function as a differentiable call.
+ },
+ },
+ {
+ differentiableCallDecoration = {
+ -- Mark a call as explicitly calling a differentiable function.
+ },
+ },
+ {
+ optimizableTypeDecoration = {
+ -- Mark a type as being eligible for trimming if necessary. If
+ -- any fields don't have any effective loads from them, they can be
+ -- removed.
+ },
+ },
+ {
+ ignoreSideEffectsDecoration = {
+ -- Informs the DCE pass to ignore side-effects on this call for
+ -- the purposes of dead code elimination, even if the call does have
+ -- side-effects.
+ },
+ },
+ {
+ CheckpointHintDecoration = {
+ {
+ PreferCheckpointDecoration = {
+ -- Hint that the result from a call to the decorated function should be stored in backward prop function.
+ },
+ },
+ {
+ PreferRecomputeDecoration = {
+ -- Hint that the result from a call to the decorated function should be recomputed in backward prop function.
+ },
+ },
+ {
+ CheckpointIntermediateDecoration = {
+ -- Hint that a struct is used for reverse mode checkpointing
+ min_operands = 1,
+ },
+ },
+ },
+ },
+ {
+ NonDynamicUniformReturnDecoration = {
+ -- Marks a function whose return value is never dynamic uniform.
+ },
+ },
+ {
+ COMWitnessDecoration = {
+ -- Marks a class type as a COM interface implementation, which enables
+ -- the witness table to be easily picked up by emit.
+ min_operands = 1,
+ },
+ },
+ {
+ DifferentiableTypeDictionaryDecoration = {
+ -- Differentiable Type Dictionary
+ parent = true,
+ },
+ },
+ {
+ FloatingPointModeOverride = {
+ struct_name = "FloatingPointModeOverrideDecoration",
+ -- Overrides the floating mode for the target function
+ min_operands = 1,
+ },
+ },
+ {
+ spvBufferBlock = {
+ -- Recognized by SPIRV-emit pass so we can emit a SPIRV `BufferBlock` decoration.
+ struct_name = "SPIRVBufferBlockDecoration",
+ },
+ },
+ {
+ DebugLocation = {
+ -- Decorates an inst with a debug source location (IRDebugSource, IRIntLit(line), IRIntLit(col)).
+ struct_name = "DebugLocationDecoration",
+ min_operands = 3,
+ },
+ },
+ {
+ DebugFunction = {
+ -- Decorates a function with a link to its debug function representation
+ struct_name = "DebugFuncDecoration",
+ min_operands = 1,
+ },
+ },
+ {
+ spvBlock = {
+ -- Recognized by SPIRV-emit pass so we can emit a SPIRV `Block` decoration.
+ struct_name = "SPIRVBlockDecoration",
+ },
+ },
+ {
+ NonUniformResource = {
+ -- Decorates a SPIRV-inst as `NonUniformResource` to guarantee non-uniform index lookup of
+ -- - a resource within an array of resources via IRGetElement.
+ -- - an IRLoad that takes a pointer within a memory buffer via IRGetElementPtr.
+ -- - an IRIntCast to a resource that is casted from signed to unsigned or viceversa.
+ -- - an IRGetElementPtr itself when using the pointer on an intrinsic operation.
+ struct_name = "SPIRVNonUniformResourceDecoration",
+ },
+ },
+ {
+ MemoryQualifierSetDecoration = {
+ -- Stores flag bits of which memory qualifiers an object has
+ min_operands = 1,
+ },
+ },
+ {
+ BitFieldAccessorDecoration = {
+ -- Marks a function as one which access a bitfield with the specified
+ -- backing value key, width and offset
+ min_operands = 3,
+ },
+ },
+ },
+ },
+ -- Decoration
+ -- A `makeExistential(v : C, w) : I` instruction takes a value `v` of type `C`
+ -- and produces a value of interface type `I` by using the witness `w` which
+ -- shows that `C` conforms to `I`.
+ { makeExistential = { min_operands = 2 } },
+ -- A `MakeExistentialWithRTTI(v, w, t)` is the same with `MakeExistential`,
+ -- but with the type of `v` being an explict operand.
+ { makeExistentialWithRTTI = { min_operands = 3 } },
+ -- A 'CreateExistentialObject<I>(typeID, T)` packs user-provided `typeID` and a
+ -- value of any type, and constructs an existential value of type `I`.
+ { createExistentialObject = { min_operands = 2 } },
+ -- A `wrapExistential(v, T0,w0, T1,w0) : T` instruction is similar to `makeExistential`.
+ -- but applies to a value `v` that is of type `BindExistentials(T, T0,w0, ...)`. The
+ -- result of the `wrapExistentials` operation is a value of type `T`, allowing us to
+ -- "smuggle" a value of specialized type into computations that expect an unspecialized type.
+ { wrapExistential = { min_operands = 1 } },
+ -- A `GetValueFromBoundInterface` takes a `BindInterface<I, T, w0>` value and returns the
+ -- value of concrete type `T` value that is being stored.
+ { getValueFromBoundInterface = { min_operands = 1 } },
+ { extractExistentialValue = { min_operands = 1 } },
+ { extractExistentialType = { min_operands = 1, hoistable = true } },
+ {
+ extractExistentialWitnessTable = {
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ { isNullExistential = { min_operands = 1 } },
+ { extractTaggedUnionTag = { min_operands = 1 } },
+ { extractTaggedUnionPayload = { min_operands = 1 } },
+ { BuiltinCast = { min_operands = 1 } },
+ { bitCast = { min_operands = 1 } },
+ { reinterpret = { min_operands = 1 } },
+ { unmodified = { min_operands = 1 } },
+ { outImplicitCast = { min_operands = 1 } },
+ { inOutImplicitCast = { min_operands = 1 } },
+ { intCast = { min_operands = 1 } },
+ { floatCast = { min_operands = 1 } },
+ { castIntToFloat = { min_operands = 1 } },
+ { castFloatToInt = { min_operands = 1 } },
+ { CastPtrToBool = { min_operands = 1 } },
+ { CastPtrToInt = { min_operands = 1 } },
+ { CastIntToPtr = { min_operands = 1 } },
+ { castToVoid = { min_operands = 1 } },
+ { PtrCast = { min_operands = 1 } },
+ { CastEnumToInt = { min_operands = 1 } },
+ { CastIntToEnum = { min_operands = 1 } },
+ { EnumCast = { min_operands = 1 } },
+ { CastUInt2ToDescriptorHandle = { min_operands = 1 } },
+ { CastDescriptorHandleToUInt2 = { min_operands = 1 } },
+ -- Represents a no-op cast to convert a resource pointer to a resource on targets where the resource handles are
+ -- already concrete types.
+ { CastDescriptorHandleToResource = { min_operands = 1 } },
+ { TreatAsDynamicUniform = { min_operands = 1 } },
+ { sizeOf = { min_operands = 1 } },
+ { alignOf = { min_operands = 1 } },
+ { countOf = { min_operands = 1 } },
+ { GetArrayLength = { min_operands = 1 } },
+ { IsType = { min_operands = 3 } },
+ { TypeEquals = { min_operands = 2 } },
+ { IsInt = { min_operands = 1 } },
+ { IsBool = { min_operands = 1 } },
+ { IsFloat = { min_operands = 1 } },
+ { IsHalf = { min_operands = 1 } },
+ { IsUnsignedInt = { min_operands = 1 } },
+ { IsSignedInt = { min_operands = 1 } },
+ { IsVector = { min_operands = 1 } },
+ { GetDynamicResourceHeap = { hoistable = true } },
+ { ForwardDifferentiate = { min_operands = 1 } },
+ -- Produces the primal computation of backward derivatives, will return an intermediate context for
+ -- backward derivative func.
+ { BackwardDifferentiatePrimal = { min_operands = 1 } },
+ -- Produces the actual backward derivative propagate function, using the intermediate context returned by the
+ -- primal func produced from `BackwardDifferentiatePrimal`.
+ { BackwardDifferentiatePropagate = { min_operands = 1 } },
+ -- Represents the conceptual backward derivative function. Only produced by lower-to-ir and will be
+ -- replaced with `BackwardDifferentiatePrimal` and `BackwardDifferentiatePropagate`.
+ { BackwardDifferentiate = { min_operands = 1 } },
+ { PrimalSubstitute = { min_operands = 1 } },
+ { DispatchKernel = { min_operands = 3 } },
+ { CudaKernelLaunch = { min_operands = 6 } },
+ -- Converts other resources (such as ByteAddressBuffer) to the equivalent StructuredBuffer
+ { getEquivalentStructuredBuffer = { min_operands = 1 } },
+ -- Gets a T[] pointer to the underlying data of a StructuredBuffer etc...
+ { getStructuredBufferPtr = { min_operands = 1 } },
+ -- Gets a uint[] pointer to the underlying data of a ByteAddressBuffer etc...
+ { getUntypedBufferPtr = { min_operands = 1 } },
+ {
+ Layout = {
+ hoistable = true,
+ { varLayout = { min_operands = 1 } },
+ {
+ TypeLayout = {
+ {
+ typeLayout = { struct_name = "TypeLayoutBase" },
+ },
+ { parameterGroupTypeLayout = { min_operands = 2 } },
+ {
+ arrayTypeLayout = { min_operands = 1 },
+ },
+ { streamOutputTypeLayout = { min_operands = 1 } },
+ {
+ matrixTypeLayout = { min_operands = 1 },
+ },
+ { existentialTypeLayout = {} },
+ { structTypeLayout = {} },
+ { tupleTypeLayout = {} },
+ { structuredBufferTypeLayout = { min_operands = 1 } },
+ {
+ ptrTypeLayout = {
+ -- "TODO(JS): Ideally we'd have the layout to the pointed to value type (ie 1 instead of 0 here). But to
+ -- avoid infinite recursion we don't."
+ struct_name = "PointerTypeLayout",
+ },
+ },
+ },
+ },
+ { EntryPointLayout = { min_operands = 1 } },
+ },
+ },
+ {
+ Attr = {
+ hoistable = true,
+ {
+ pendingLayout = {
+ struct_name = "PendingLayoutAttr",
+ min_operands = 1,
+ },
+ },
+ { stage = { struct_name = "StageAttr", min_operands = 1 } },
+ { structFieldLayout = { struct_name = "StructFieldLayoutAttr", min_operands = 2 } },
+ {
+ tupleFieldLayout = { struct_name = "TupleFieldLayoutAttr", min_operands = 1 },
+ },
+ {
+ caseLayout = {
+ struct_name = "CaseTypeLayoutAttr",
+ min_operands = 1,
+ },
+ },
+ { unorm = { struct_name = "UNormAttr" } },
+ {
+ snorm = {
+ struct_name = "SNormAttr",
+ },
+ },
+ { no_diff = { struct_name = "NoDiffAttr" } },
+ {
+ nonuniform = {
+ struct_name = "NonUniformAttr",
+ },
+ },
+ { Aligned = { struct_name = "AlignedAttr", min_operands = 1 } },
+ {
+ SemanticAttr = {
+ { userSemantic = { struct_name = "UserSemanticAttr", min_operands = 2 } },
+ { systemValueSemantic = { struct_name = "SystemValueSemanticAttr", min_operands = 2 } },
+ },
+ },
+ {
+ LayoutResourceInfoAttr = {
+ { size = { struct_name = "TypeSizeAttr", min_operands = 2 } },
+ { offset = { struct_name = "VarOffsetAttr", min_operands = 2 } },
+ },
+ },
+ { FuncThrowType = { struct_name = "FuncThrowTypeAttr", min_operands = 1 } },
+ },
+ },
+ -- Liveness
+ {
+ LiveRangeMarker = { { liveRangeStart = { min_operands = 2 } }, { liveRangeEnd = {} } },
+ },
+ -- IRSpecialization
+ { SpecializationDictionaryItem = {} },
+ { GenericSpecializationDictionary = { parent = true } },
+ { ExistentialFuncSpecializationDictionary = { parent = true } },
+ { ExistentialTypeSpecializationDictionary = { parent = true } },
+ -- Differentiable Type Dictionary
+ { DifferentiableTypeDictionaryItem = {} },
+ -- Differentiable Type Annotation (for run-time types)
+ { DifferentiableTypeAnnotation = { min_operands = 2, hoistable = true } },
+ { BeginFragmentShaderInterlock = {} },
+ {
+ EndFragmentShaderInterlock = { struct_name = "EndFragmentShaderInterlock" },
+ },
+ -- DebugInfo
+ { DebugSource = { min_operands = 2, hoistable = true } },
+ {
+ DebugLine = {
+ min_operands = 5,
+ },
+ },
+ { DebugVar = { min_operands = 4 } },
+ {
+ DebugValue = {
+ min_operands = 2,
+ },
+ },
+ { DebugInlinedAt = { min_operands = 5 } },
+ {
+ DebugFunction = {
+ min_operands = 5,
+ },
+ },
+ { DebugInlinedVariable = { min_operands = 2 } },
+ {
+ DebugScope = {
+ min_operands = 2,
+ },
+ },
+ { DebugNoScope = { min_operands = 1 } },
+ {
+ DebugBuildIdentifier = {
+ min_operands = 2,
+ },
+ },
+ -- Embedded Precompiled Libraries
+ { EmbeddedDownstreamIR = { min_operands = 2 } },
+ -- Inline assembly
+ { SPIRVAsm = { parent = true } },
+ { SPIRVAsmInst = { min_operands = 1 } },
+ {
+ SPIRVAsmOperand = {
+ {
+ SPIRVAsmOperandLiteral = {
+ -- These instruction serve to inform the backend precisely how to emit each
+ -- instruction, consider the difference between emitting a literal integer
+ -- and a reference to a literal integer instruction
+ -- A literal string or 32-bit integer to be passed as operands
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ {
+ SPIRVAsmOperandInst = {
+ -- A reference to a slang IRInst, either a value or a type
+ -- This isn't hoistable, as we sometimes need to change the used value and
+ -- instructions around the specific asm block
+ min_operands = 1,
+ },
+ },
+ { SPIRVAsmOperandConvertTexel = { min_operands = 1 } },
+ {
+ SPIRVAsmOperandRayPayloadFromLocation = {
+ -- a late resolving type to handle the case of ray objects (resolving late due to constexpr data requirment)
+ min_operands = 1,
+ },
+ },
+ { SPIRVAsmOperandRayAttributeFromLocation = { min_operands = 1 } },
+ { SPIRVAsmOperandRayCallableFromLocation = { min_operands = 1 } },
+ {
+ SPIRVAsmOperandEnum = {
+ -- A named enumerator, the value is stored as a constant operand
+ -- It may have a second operand, which if present is a type with which to
+ -- construct a constant id to pass, instead of a literal constant
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ {
+ SPIRVAsmOperandBuiltinVar = {
+ -- A reference to a builtin variable.
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ {
+ SPIRVAsmOperandGLSL450Set = {
+ -- A reference to the glsl450 instruction set.
+ hoistable = true,
+ },
+ },
+ { SPIRVAsmOperandDebugPrintfSet = { hoistable = true } },
+ {
+ SPIRVAsmOperandId = {
+ -- A string which is given a unique ID in the backend, used to refer to
+ -- results of other instrucions in the same asm block
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ {
+ SPIRVAsmOperandResult = {
+ -- A special instruction which marks the place to insert the generated
+ -- result operand
+ hoistable = true,
+ },
+ },
+ {
+ ["__truncate"] = {
+ -- A special instruction which represents a type directed truncation
+ -- operation where extra components are dropped
+ struct_name = "SPIRVAsmOperandTruncate",
+ hoistable = true,
+ },
+ },
+ {
+ ["__entryPoint"] = {
+ -- A special instruction which represents an ID of an entry point that references the current function.
+ struct_name = "SPIRVAsmOperandEntryPoint",
+ hoistable = true,
+ },
+ },
+ {
+ ["__sampledType"] = {
+ -- A type function which returns the result type of sampling an image of
+ -- this component type
+ struct_name = "SPIRVAsmOperandSampledType",
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ {
+ ["__imageType"] = {
+ -- A type function which returns the equivalent OpTypeImage type of sampled image value
+ struct_name = "SPIRVAsmOperandImageType",
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ {
+ ["__sampledImageType"] = {
+ -- A type function which returns the equivalent OpTypeImage type of sampled image value
+ struct_name = "SPIRVAsmOperandSampledImageType",
+ min_operands = 1,
+ hoistable = true,
+ },
+ },
+ },
+ },
+}
+
+-- A function to calculate some useful properties and put it in the table,
+--
+-- Returns the tree as well as the flattened tree in preorder
+-- Annotates instructions with whether they are a leaf or not
+-- Calculates flags from the parent flags
+local function process(insts)
+ local function to_pascal_case(str)
+ local result = str:gsub("_(.)", function(c)
+ return c:upper()
+ end)
+ return result:sub(1, 1):upper() .. result:sub(2)
+ end
+
+ -- Check if an instruction is a leaf
+ local function is_leaf(inst)
+ for k, v in ipairs(inst) do
+ return false
+ end
+ return true
+ end
+
+ -- Recursively process instructions
+ local function process_inst(tbl, inherited_flags)
+ inherited_flags = inherited_flags or {}
+
+ -- Collect flags from current level
+ local current_flags = {}
+ for k, v in pairs(inherited_flags) do
+ current_flags[k] = v
+ end
+
+ -- Add flags from this table if it has any
+ if tbl.hoistable then
+ current_flags.hoistable = true
+ end
+ if tbl.parent then
+ current_flags.parent = true
+ end
+ if tbl.useOther then
+ current_flags.useOther = true
+ end
+ if tbl.global then
+ current_flags.global = true
+ end
+
+ -- If we have any children, this will be set to false
+ tbl.is_leaf = true
+
+ for _, i in ipairs(tbl) do
+ local key, value = next(i)
+ tbl.is_leaf = false
+
+ if not value.mnemonic then
+ value.mnemonic = key
+ end
+
+ -- Add struct_name if missing
+ if not value.struct_name then
+ value.struct_name = to_pascal_case(key)
+ end
+
+ value.parent_inst = tbl
+
+ -- Apply inherited flags
+ for flag, flag_value in pairs(current_flags) do
+ if value[flag] == nil then
+ value[flag] = flag_value
+ end
+ end
+
+ -- If it's a leaf and doesn't have min_operands, add it
+ if is_leaf(value) and value.min_operands == nil then
+ value.min_operands = 0
+ end
+
+ -- Recursively process children
+ process_inst(value, current_flags)
+ end
+ end
+
+ -- Process the entire tree
+ process_inst(insts)
+
+ return {
+ insts = insts,
+ }
+end
+
+return process(insts)
diff --git a/source/slang/slang-ir-legalize-empty-array.cpp b/source/slang/slang-ir-legalize-empty-array.cpp
index 1f7d59783..1e6798a2e 100644
--- a/source/slang/slang-ir-legalize-empty-array.cpp
+++ b/source/slang/slang-ir-legalize-empty-array.cpp
@@ -72,56 +72,56 @@ struct EmptyArrayLoweringContext
{
const auto base = gep->getBase();
return hasEmptyArrayPtrType(gep) || hasEmptyArrayPtrType(base) ||
- base->getOp() == kIROp_undefined
+ base->getOp() == kIROp_Undefined
? builder.emitUndefined(gep->getDataType())
: nullptr;
},
[&](IRFieldAddress* gep)
{
const auto base = gep->getBase();
- return hasEmptyArrayPtrType(gep) || base->getOp() == kIROp_undefined
+ return hasEmptyArrayPtrType(gep) || base->getOp() == kIROp_Undefined
? builder.emitUndefined(gep->getDataType())
: nullptr;
},
[&](IRLoad* load)
{
- return load->getOperand(0)->getOp() == kIROp_undefined
+ return load->getOperand(0)->getOp() == kIROp_Undefined
? builder.emitUndefined(load->getDataType())
: nullptr;
},
[&](IRImageLoad* load)
{
- return load->getOperand(0)->getOp() == kIROp_undefined
+ return load->getOperand(0)->getOp() == kIROp_Undefined
? builder.emitUndefined(load->getDataType())
: nullptr;
},
[&](IRStore* store)
{
- if (store->getPtr()->getOp() == kIROp_undefined)
+ if (store->getPtr()->getOp() == kIROp_Undefined)
store->removeAndDeallocate();
return nullptr;
},
[&](IRAtomicStore* store)
{
- if (store->getPtr()->getOp() == kIROp_undefined)
+ if (store->getPtr()->getOp() == kIROp_Undefined)
store->removeAndDeallocate();
return nullptr;
},
[&](IRImageStore* store)
{
- if (store->getImage()->getOp() == kIROp_undefined)
+ if (store->getImage()->getOp() == kIROp_Undefined)
store->removeAndDeallocate();
return nullptr;
},
[&](IRImageSubscript* subscript)
{
- return subscript->getImage()->getOp() == kIROp_undefined
+ return subscript->getImage()->getOp() == kIROp_Undefined
? builder.emitUndefined(subscript->getDataType())
: nullptr;
},
[&](IRAtomicOperation* atomic)
{
- return atomic->getOperand(0)->getOp() == kIROp_undefined
+ return atomic->getOperand(0)->getOp() == kIROp_Undefined
? builder.emitUndefined(atomic->getDataType())
: nullptr;
},
diff --git a/source/slang/slang-ir-legalize-global-values.cpp b/source/slang/slang-ir-legalize-global-values.cpp
index 63dbed3bd..55676f2d1 100644
--- a/source/slang/slang-ir-legalize-global-values.cpp
+++ b/source/slang/slang-ir-legalize-global-values.cpp
@@ -101,8 +101,8 @@ bool GlobalInstInliningContextGeneric::isInlinableGlobalInst(IRInst* inst)
case kIROp_MakeMatrix:
case kIROp_MakeMatrixFromScalar:
case kIROp_MakeVectorFromScalar:
- case kIROp_swizzle:
- case kIROp_swizzleSet:
+ case kIROp_Swizzle:
+ case kIROp_SwizzleSet:
case kIROp_MatrixReshape:
case kIROp_MakeString:
case kIROp_MakeResultError:
@@ -218,7 +218,7 @@ IRInst* GlobalInstInliningContextGeneric::maybeInlineGlobalValue(
case kIROp_Func:
case kIROp_Specialize:
case kIROp_Generic:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
return inst;
}
if (as<IRType>(inst))
diff --git a/source/slang/slang-ir-legalize-types.cpp b/source/slang/slang-ir-legalize-types.cpp
index 529770acc..9cf8d7b5f 100644
--- a/source/slang/slang-ir-legalize-types.cpp
+++ b/source/slang/slang-ir-legalize-types.cpp
@@ -2134,14 +2134,14 @@ static LegalVal legalizeInst(
case kIROp_DefaultConstruct:
result = legalizeDefaultConstruct(context, type);
break;
- case kIROp_unconditionalBranch:
- case kIROp_loop:
+ case kIROp_UnconditionalBranch:
+ case kIROp_Loop:
result = legalizeUnconditionalBranch(context, args, (IRUnconditionalBranch*)inst);
break;
case kIROp_Printf:
result = legalizePrintf(context, args);
break;
- case kIROp_undefined:
+ case kIROp_Undefined:
return legalizeUndefined(context, inst);
case kIROp_GpuForeach:
// This case should only happen when compiling for a target that does not support
@@ -3965,7 +3965,7 @@ struct IRTypeLegalizationPass
// would not be a valid location at which to
// store their replacements.
//
- if (!inst->getParent() && inst->getOp() != kIROp_Module)
+ if (!inst->getParent() && inst->getOp() != kIROp_ModuleInst)
return;
// The main logic for legalizing an instruction is defined
diff --git a/source/slang/slang-ir-link.cpp b/source/slang/slang-ir-link.cpp
index a7b4c4560..8f48e83dc 100644
--- a/source/slang/slang-ir-link.cpp
+++ b/source/slang/slang-ir-link.cpp
@@ -141,7 +141,7 @@ void registerClonedValue(IRSpecContextBase* context, IRInst* clonedValue, IRInst
switch (clonedValue->getOp())
{
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
// If `originalVal` represents a witness table entry key, add the key
// to witnessTableEntryWorkList.
diff --git a/source/slang/slang-ir-liveness.cpp b/source/slang/slang-ir-liveness.cpp
index 91721e5ea..880c99c80 100644
--- a/source/slang/slang-ir-liveness.cpp
+++ b/source/slang/slang-ir-liveness.cpp
@@ -670,7 +670,7 @@ LivenessContext::BlockResult LivenessContext::_completeBlock(
static IRLoop* _getLoopTerminator(IRBlock* block)
{
auto terminator = block->getTerminator();
- if (terminator->getOp() == kIROp_loop)
+ if (terminator->getOp() == kIROp_Loop)
{
return static_cast<IRLoop*>(terminator);
}
@@ -888,7 +888,7 @@ void LivenessContext::_findAliasesAndAccesses(IRInst* root)
accessType = AccessType::Alias;
break;
}
- case kIROp_GetAddr:
+ case kIROp_GetAddress:
{
IRGetAddress* getAddr = static_cast<IRGetAddress*>(cur);
base = getAddr->getOperand(0);
diff --git a/source/slang/slang-ir-lower-com-methods.cpp b/source/slang/slang-ir-lower-com-methods.cpp
index 551cccd3b..d51807aa1 100644
--- a/source/slang/slang-ir-lower-com-methods.cpp
+++ b/source/slang/slang-ir-lower-com-methods.cpp
@@ -32,7 +32,7 @@ struct ComMethodLoweringContext : public InstPassBase
SLANG_ASSERT(callee);
IRLookupWitnessMethod* innerMostCallee = callee;
- while (innerMostCallee->getOperand(0)->getOp() == kIROp_LookupWitness)
+ while (innerMostCallee->getOperand(0)->getOp() == kIROp_LookupWitnessMethod)
{
innerMostCallee = as<IRLookupWitnessMethod>(innerMostCallee->getOperand(0));
}
@@ -84,7 +84,7 @@ struct ComMethodLoweringContext : public InstPassBase
auto funcValue = inst->getOperand(0);
// Detect if this is a call into a COM interface method.
- if (funcValue->getOp() == kIROp_LookupWitness)
+ if (funcValue->getOp() == kIROp_LookupWitnessMethod)
{
const auto operand0TypeOp = funcValue->getOperand(0)->getDataType();
if (auto tableType = as<IRWitnessTableTypeBase>(operand0TypeOp))
diff --git a/source/slang/slang-ir-lower-defer.cpp b/source/slang/slang-ir-lower-defer.cpp
index 4e1ec9a8b..d650f53ec 100644
--- a/source/slang/slang-ir-lower-defer.cpp
+++ b/source/slang/slang-ir-lower-defer.cpp
@@ -187,11 +187,11 @@ struct DeferLoweringContext : InstPassBase
switch (terminator->getOp())
{
case kIROp_Return:
- case kIROp_discard:
+ case kIROp_Discard:
case kIROp_Throw:
exits = true;
break;
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
{
auto targetBlock = as<IRBlock>(terminator->getOperand(0));
if (!scopeBlocksSet.contains(targetBlock))
@@ -200,7 +200,7 @@ struct DeferLoweringContext : InstPassBase
}
}
break;
- case kIROp_conditionalBranch:
+ case kIROp_ConditionalBranch:
{
auto trueBlock = as<IRBlock>(terminator->getOperand(1));
auto falseBlock = as<IRBlock>(terminator->getOperand(2));
diff --git a/source/slang/slang-ir-lower-expand-type.cpp b/source/slang/slang-ir-lower-expand-type.cpp
index 6bd79737b..dc7512fad 100644
--- a/source/slang/slang-ir-lower-expand-type.cpp
+++ b/source/slang/slang-ir-lower-expand-type.cpp
@@ -32,7 +32,7 @@ IRInst* clonePatternValImpl(
return result;
}
case kIROp_Specialize:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
case kIROp_ExtractExistentialType:
case kIROp_ExtractExistentialWitnessTable:
break;
@@ -83,7 +83,7 @@ IRInst* clonePatternVal(IRCloneEnv& cloneEnv, IRBuilder* builder, IRInst* val, I
// Translate a `IRExpandType` into an `IRExpand` where the `PatternType` is defined
// inside the `IRExpand` body.
//
-IRInst* lowerExpandTypeImpl(IRExpandType* expandType)
+IRInst* lowerExpandTypeImpl(IRExpandTypeOrVal* expandType)
{
// Turn `IRExpandType` into an `IRExpand` instruction.
IRBuilder builder(expandType);
@@ -159,7 +159,7 @@ void lowerExpandType(IRModule* module)
auto inst = workList.getLast();
workList.removeLast();
- if (auto expandType = as<IRExpandType>(inst))
+ if (auto expandType = as<IRExpandTypeOrVal>(inst))
{
inst = lowerExpandTypeImpl(expandType);
if (inst != expandType)
diff --git a/source/slang/slang-ir-lower-generic-call.cpp b/source/slang/slang-ir-lower-generic-call.cpp
index 41a78d00c..e4fb5ac98 100644
--- a/source/slang/slang-ir-lower-generic-call.cpp
+++ b/source/slang/slang-ir-lower-generic-call.cpp
@@ -269,7 +269,7 @@ struct GenericCallLoweringContext
// modified in this pass.
SLANG_UNEXPECTED("Nested generics specialization.");
}
- else if (loweredFunc->getOp() == kIROp_LookupWitness)
+ else if (loweredFunc->getOp() == kIROp_LookupWitnessMethod)
{
lowerCallToInterfaceMethod(
callInst,
diff --git a/source/slang/slang-ir-lower-generic-function.cpp b/source/slang/slang-ir-lower-generic-function.cpp
index c003d6125..6c2eb6193 100644
--- a/source/slang/slang-ir-lower-generic-function.cpp
+++ b/source/slang/slang-ir-lower-generic-function.cpp
@@ -97,7 +97,7 @@ struct GenericFunctionLoweringContext
}
break;
case kIROp_Specialize:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
childrenToDemote.add(clonedChild);
break;
default:
diff --git a/source/slang/slang-ir-lower-generics.cpp b/source/slang/slang-ir-lower-generics.cpp
index b01abcbc5..be21a66ba 100644
--- a/source/slang/slang-ir-lower-generics.cpp
+++ b/source/slang/slang-ir-lower-generics.cpp
@@ -43,7 +43,7 @@ void specializeRTTIObjectReferences(SharedGenericsLoweringContext* sharedContext
for (auto use = rtti.value->firstUse; use; use = nextUse)
{
nextUse = use->nextUse;
- if (use->getUser()->getOp() == kIROp_GetAddr)
+ if (use->getUser()->getOp() == kIROp_GetAddress)
{
use->getUser()->replaceUsesWith(idOperand);
}
diff --git a/source/slang/slang-ir-lower-tuple-types.cpp b/source/slang/slang-ir-lower-tuple-types.cpp
index 066895b78..da8568a01 100644
--- a/source/slang/slang-ir-lower-tuple-types.cpp
+++ b/source/slang/slang-ir-lower-tuple-types.cpp
@@ -358,10 +358,10 @@ struct TupleLoweringContext
case kIROp_GetElementPtr:
processGetElementPtr((IRGetElementPtr*)inst);
break;
- case kIROp_swizzle:
+ case kIROp_Swizzle:
processSwizzle((IRSwizzle*)inst);
break;
- case kIROp_swizzleSet:
+ case kIROp_SwizzleSet:
processSwizzleSet((IRSwizzleSet*)inst);
break;
case kIROp_SwizzledStore:
diff --git a/source/slang/slang-ir-peephole.cpp b/source/slang/slang-ir-peephole.cpp
index cafe978f9..8d6685212 100644
--- a/source/slang/slang-ir-peephole.cpp
+++ b/source/slang/slang-ir-peephole.cpp
@@ -256,7 +256,7 @@ struct PeepholeContext : InstPassBase
{
if (as<IRGlobalValueWithCode>(inst))
{
- if (auto fpModeDecor = inst->findDecoration<IRFloatingModeOverrideDecoration>())
+ if (auto fpModeDecor = inst->findDecoration<IRFloatingPointModeOverrideDecoration>())
floatingPointMode = fpModeDecor->getFloatingPointMode();
}
@@ -863,7 +863,7 @@ struct PeepholeContext : InstPassBase
}
}
break;
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
{
if (inst->getOperand(0)->getOp() == kIROp_WitnessTable)
{
@@ -1041,7 +1041,7 @@ struct PeepholeContext : InstPassBase
continue;
SLANG_ASSERT(terminator->getArgCount() > paramIndex);
auto arg = terminator->getArg(paramIndex);
- if (arg->getOp() == kIROp_undefined)
+ if (arg->getOp() == kIROp_Undefined)
continue;
if (argValue == nullptr)
argValue = arg;
@@ -1090,7 +1090,7 @@ struct PeepholeContext : InstPassBase
}
}
break;
- case kIROp_swizzle:
+ case kIROp_Swizzle:
{
// If we see a swizzle(scalar), we replace it with makeVectorFromScalar.
if (as<IRBasicType>(inst->getOperand(0)->getDataType()))
@@ -1269,7 +1269,7 @@ struct PeepholeContext : InstPassBase
case kIROp_Load:
{
// Load from undef is undef.
- if (as<IRLoad>(inst)->getPtr()->getOp() == kIROp_undefined)
+ if (as<IRLoad>(inst)->getPtr()->getOp() == kIROp_Undefined)
{
IRBuilder builder(module);
IRBuilderSourceLocRAII srcLocRAII(&builder, inst->sourceLoc);
@@ -1285,7 +1285,7 @@ struct PeepholeContext : InstPassBase
case kIROp_Store:
{
// Store undef is no-op.
- if (as<IRStore>(inst)->getVal()->getOp() == kIROp_undefined)
+ if (as<IRStore>(inst)->getVal()->getOp() == kIROp_Undefined)
{
maybeRemoveOldInst(inst);
changed = true;
@@ -1295,7 +1295,7 @@ struct PeepholeContext : InstPassBase
case kIROp_DebugValue:
{
// Update debug value with undef is no-op.
- if (as<IRDebugValue>(inst)->getValue()->getOp() == kIROp_undefined)
+ if (as<IRDebugValue>(inst)->getValue()->getOp() == kIROp_Undefined)
{
maybeRemoveOldInst(inst);
changed = true;
@@ -1309,7 +1309,7 @@ struct PeepholeContext : InstPassBase
bool isConcreteType(IRType* type)
{
- return type->parent->getOp() == kIROp_Module && !as<IRGlobalGenericParam>(type);
+ return type->parent->getOp() == kIROp_ModuleInst && !as<IRGlobalGenericParam>(type);
}
bool processFunc(IRInst* func)
diff --git a/source/slang/slang-ir-propagate-func-properties.cpp b/source/slang/slang-ir-propagate-func-properties.cpp
index 8c13a6455..0e5ee731a 100644
--- a/source/slang/slang-ir-propagate-func-properties.cpp
+++ b/source/slang/slang-ir-propagate-func-properties.cpp
@@ -35,11 +35,11 @@ static bool isKnownOpCodeWithSideEffect(IROp op)
{
switch (op)
{
- case kIROp_ifElse:
- case kIROp_unconditionalBranch:
+ case kIROp_IfElse:
+ case kIROp_UnconditionalBranch:
case kIROp_Switch:
case kIROp_Return:
- case kIROp_loop:
+ case kIROp_Loop:
case kIROp_Call:
case kIROp_Param:
case kIROp_Unreachable:
diff --git a/source/slang/slang-ir-restructure.cpp b/source/slang/slang-ir-restructure.cpp
index db3bb61f5..33d5aebea 100644
--- a/source/slang/slang-ir-restructure.cpp
+++ b/source/slang/slang-ir-restructure.cpp
@@ -246,7 +246,7 @@ static RefPtr<Region> generateRegionsForIRBlocks(
switch (terminator->getOp())
{
default:
- case kIROp_conditionalBranch:
+ case kIROp_ConditionalBranch:
// Note: we don't currently generate ordinary `conditionalBranch` instructions,
// and instead only generate `ifElse` instructions, which include additional
// information that can inform our control-flow restructuring pass.
@@ -265,7 +265,7 @@ static RefPtr<Region> generateRegionsForIRBlocks(
*resultLink = nullptr;
return resultRegion;
- case kIROp_ifElse:
+ case kIROp_IfElse:
{
// Here we have a two-way branch, so that we will construct a
// region representing an `if` statement.
@@ -305,7 +305,7 @@ static RefPtr<Region> generateRegionsForIRBlocks(
}
break;
- case kIROp_loop:
+ case kIROp_Loop:
{
// The terminator in this case is the header for a structured loop.
//
@@ -424,7 +424,7 @@ static RefPtr<Region> generateRegionsForIRBlocks(
}
break;
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
{
// Here we have an unconditional branch that was
// not covered by one of our labels for non-local
diff --git a/source/slang/slang-ir-simplify-cfg.cpp b/source/slang/slang-ir-simplify-cfg.cpp
index 2310a5cce..425cb3b35 100644
--- a/source/slang/slang-ir-simplify-cfg.cpp
+++ b/source/slang/slang-ir-simplify-cfg.cpp
@@ -56,7 +56,7 @@ static IRInst* findBreakableRegionHeaderInst(IRDominatorTree* domTree, IRBlock*
switch (terminator->getOp())
{
case kIROp_Switch:
- case kIROp_loop:
+ case kIROp_Loop:
return terminator;
}
}
@@ -138,7 +138,7 @@ bool isTrivialSingleIterationLoop(
//
switch (terminator->getOp())
{
- case kIROp_loop:
+ case kIROp_Loop:
if (isBlockInRegion(domTree, as<IRLoop>(terminator), breakOriginBlock))
return false;
break;
@@ -351,7 +351,7 @@ static bool isTrivialIfElseBranch(IRIfElse* condBranch, IRBlock* branchBlock)
if (auto br = as<IRUnconditionalBranch>(branchBlock->getFirstOrdinaryInst()))
{
if (br->getTargetBlock() == condBranch->getAfterBlock() &&
- br->getOp() == kIROp_unconditionalBranch)
+ br->getOp() == kIROp_UnconditionalBranch)
{
return true;
}
@@ -436,7 +436,7 @@ static bool isTrivialSwitchBranch(IRSwitch* switchInst, IRBlock* branchBlock)
if (auto br = as<IRUnconditionalBranch>(branchBlock->getFirstOrdinaryInst()))
{
if (br->getTargetBlock() == switchInst->getBreakLabel() &&
- br->getOp() == kIROp_unconditionalBranch)
+ br->getOp() == kIROp_UnconditionalBranch)
{
return true;
}
@@ -564,7 +564,7 @@ static bool trySimplifySwitch(IRBuilder& builder, IRSwitch* switchInst)
for (;;)
{
auto block = as<IRBlock>(targetUse->get());
- if (block->getFirstInst()->getOp() != kIROp_unconditionalBranch)
+ if (block->getFirstInst()->getOp() != kIROp_UnconditionalBranch)
return;
auto branch = as<IRUnconditionalBranch>(block->getFirstInst());
// We can't fuse the block if there are phi arguments.
@@ -580,8 +580,8 @@ static bool trySimplifySwitch(IRBuilder& builder, IRSwitch* switchInst)
continue;
switch (use->getUser()->getOp())
{
- case kIROp_loop:
- case kIROp_ifElse:
+ case kIROp_Loop:
+ case kIROp_IfElse:
case kIROp_Switch:
// If the target block is used by a special control flow inst,
// it is likely a merge block and we can't fuse it.
@@ -690,7 +690,7 @@ static bool simplifyBoolPhiParams(IRBlock* block)
Array<IRBlock*, 2> preds;
for (auto pred : block->getPredecessors())
{
- if (pred->getTerminator()->getOp() != kIROp_unconditionalBranch)
+ if (pred->getTerminator()->getOp() != kIROp_UnconditionalBranch)
return false;
preds.add(pred);
}
@@ -914,7 +914,7 @@ static bool processFunc(IRGlobalValueWithCode* func, CFGSimplificationOptions op
}
// If `block` does not end with an unconditional branch, bail.
- if (block->getTerminator()->getOp() != kIROp_unconditionalBranch)
+ if (block->getTerminator()->getOp() != kIROp_UnconditionalBranch)
break;
auto branch = as<IRUnconditionalBranch>(block->getTerminator());
auto successor = branch->getTargetBlock();
diff --git a/source/slang/slang-ir-specialize-dispatch.cpp b/source/slang/slang-ir-specialize-dispatch.cpp
index 0c8b248b0..b862b3dd0 100644
--- a/source/slang/slang-ir-specialize-dispatch.cpp
+++ b/source/slang/slang-ir-specialize-dispatch.cpp
@@ -34,7 +34,7 @@ IRFunc* specializeDispatchFunction(
case kIROp_Call:
callInst = cast<IRCall>(inst);
break;
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
lookupInst = cast<IRLookupWitnessMethod>(inst);
break;
case kIROp_Return:
diff --git a/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp b/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp
index 906bb8882..5bbc62bed 100644
--- a/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp
+++ b/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp
@@ -184,7 +184,7 @@ struct AssociatedTypeLookupSpecializationContext
sharedContext,
[this](IRInst* inst)
{
- if (inst->getOp() == kIROp_LookupWitness)
+ if (inst->getOp() == kIROp_LookupWitnessMethod)
{
processLookupInterfaceMethodInst(cast<IRLookupWitnessMethod>(inst));
}
diff --git a/source/slang/slang-ir-specialize.cpp b/source/slang/slang-ir-specialize.cpp
index 266c1aa99..ed96b23c1 100644
--- a/source/slang/slang-ir-specialize.cpp
+++ b/source/slang/slang-ir-specialize.cpp
@@ -130,7 +130,7 @@ struct SpecializationContext
switch (inst->getOp())
{
case kIROp_GlobalGenericParam:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
case kIROp_GetTupleElement:
return false;
case kIROp_Specialize:
@@ -597,7 +597,7 @@ struct SpecializationContext
//
return maybeSpecializeGeneric(cast<IRSpecialize>(inst));
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
// The remaining case we need to consider here for generics
// is when we have a `lookup_witness_method` instruction
// that is being applied to a concrete witness table,
@@ -941,7 +941,7 @@ struct SpecializationContext
shouldSkip = true;
break;
}
- if (item->getOperand(i)->getOp() == kIROp_undefined)
+ if (item->getOperand(i)->getOp() == kIROp_Undefined)
{
shouldSkip = true;
break;
@@ -1095,7 +1095,7 @@ struct SpecializationContext
workList.removeLast();
workListSet.remove(inst);
- if (!inst->getParent() && inst->getOp() != kIROp_Module)
+ if (!inst->getParent() && inst->getOp() != kIROp_ModuleInst)
continue;
// For each instruction we process, we want to perform
diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp
index 31742cbde..2a5701e33 100644
--- a/source/slang/slang-ir-spirv-legalize.cpp
+++ b/source/slang/slang-ir-spirv-legalize.cpp
@@ -983,13 +983,13 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
builder.setInsertBefore(inst);
if (!m_mapArrayValueToVar.tryGetValue(x, y))
{
- if (x->getParent()->getOp() == kIROp_Module)
+ if (x->getParent()->getOp() == kIROp_ModuleInst)
builder.setInsertBefore(inst);
else
setInsertAfterOrdinaryInst(&builder, x);
y = builder.emitVar(x->getDataType(), AddressSpace::Function);
builder.emitStore(y, x);
- if (x->getParent()->getOp() != kIROp_Module)
+ if (x->getParent()->getOp() != kIROp_ModuleInst)
m_mapArrayValueToVar.set(x, y);
}
builder.setInsertBefore(inst);
@@ -1397,7 +1397,7 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
{
maybeHoistConstructInstToGlobalScope(inst);
- if (inst->getOp() == kIROp_MakeVector && inst->getParent()->getOp() == kIROp_Module &&
+ if (inst->getOp() == kIROp_MakeVector && inst->getParent()->getOp() == kIROp_ModuleInst &&
inst->getOperandCount() !=
(UInt)getIntVal(as<IRVectorType>(inst->getDataType())->getElementCount()))
{
@@ -1772,10 +1772,10 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
case kIROp_NonUniformResourceIndex:
processNonUniformResourceIndex(inst, NonUniformResourceIndexFloatMode::SPIRV);
break;
- case kIROp_loop:
+ case kIROp_Loop:
processLoop(as<IRLoop>(inst));
break;
- case kIROp_ifElse:
+ case kIROp_IfElse:
processIfElse(as<IRIfElse>(inst));
break;
case kIROp_Switch:
@@ -1809,7 +1809,7 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
case kIROp_PtrLit:
processPtrLit(inst);
break;
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
processBranch(inst);
break;
case kIROp_SPIRVAsm:
@@ -2407,7 +2407,7 @@ void insertFragmentShaderInterlock(SPIRVEmitSharedContext* context, IRModule* mo
if (auto inst = block->getTerminator())
{
if (inst->getOp() == kIROp_Return ||
- !context->isSpirv16OrLater() && inst->getOp() == kIROp_discard)
+ !context->isSpirv16OrLater() && inst->getOp() == kIROp_Discard)
{
builder.setInsertBefore(inst);
builder.emitEndFragmentShaderInterlock();
diff --git a/source/slang/slang-ir-ssa-register-allocate.cpp b/source/slang/slang-ir-ssa-register-allocate.cpp
index e3bda0c1b..dae834e7a 100644
--- a/source/slang/slang-ir-ssa-register-allocate.cpp
+++ b/source/slang/slang-ir-ssa-register-allocate.cpp
@@ -123,7 +123,7 @@ struct RegisterAllocateContext
IRUse* branchUse = nullptr;
for (auto use = phiArg->firstUse; use; use = use->nextUse)
{
- if (use->getUser()->getOp() == kIROp_unconditionalBranch)
+ if (use->getUser()->getOp() == kIROp_UnconditionalBranch)
{
if (!branchUse)
branchUse = use;
diff --git a/source/slang/slang-ir-synthesize-active-mask.cpp b/source/slang/slang-ir-synthesize-active-mask.cpp
index f899fee1a..555cd4a5a 100644
--- a/source/slang/slang-ir-synthesize-active-mask.cpp
+++ b/source/slang/slang-ir-synthesize-active-mask.cpp
@@ -1049,7 +1049,7 @@ struct SynthesizeActiveMaskForFunctionContext
// that unstructured branches can split the active mask,
// without any option to reconverge it.
//
- case kIROp_conditionalBranch:
+ case kIROp_ConditionalBranch:
//
// Finally, we also don't handle any control-flow op we might not
// have introduced at the time this pass was created.
@@ -1067,7 +1067,7 @@ struct SynthesizeActiveMaskForFunctionContext
case kIROp_Unreachable:
break;
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
{
auto branch = cast<IRUnconditionalBranch>(terminator);
@@ -1131,7 +1131,7 @@ struct SynthesizeActiveMaskForFunctionContext
}
break;
- case kIROp_ifElse:
+ case kIROp_IfElse:
{
// A structured `ifElse` instruction is a two-way branch on a
// Boolean coniditon, along with a specific block representing
@@ -1252,7 +1252,7 @@ struct SynthesizeActiveMaskForFunctionContext
}
break;
- case kIROp_loop:
+ case kIROp_Loop:
{
// At the most basic level, a `loop` instruction is just an uncondtional
// branch. What is stores above and beyond an `unconditionalBranch`
diff --git a/source/slang/slang-ir-uniformity.cpp b/source/slang/slang-ir-uniformity.cpp
index 312b64af3..64c916a4f 100644
--- a/source/slang/slang-ir-uniformity.cpp
+++ b/source/slang/slang-ir-uniformity.cpp
@@ -318,7 +318,7 @@ struct ValidateUniformityContext
}
break;
}
- case kIROp_ifElse:
+ case kIROp_IfElse:
{
auto ifElse = as<IRIfElse>(user);
visitControlDependentBlock(ifElse->getTrueBlock());
diff --git a/source/slang/slang-ir-use-uninitialized-values.cpp b/source/slang/slang-ir-use-uninitialized-values.cpp
index 71aae5923..daa667a0a 100644
--- a/source/slang/slang-ir-use-uninitialized-values.cpp
+++ b/source/slang/slang-ir-use-uninitialized-values.cpp
@@ -35,7 +35,7 @@ static bool isUninitializedValue(IRInst* inst)
// Also consider var since it does not
// automatically mean it will be initialized
// (at least not as the user may have intended)
- return (inst->m_op == kIROp_undefined) || (inst->m_op == kIROp_Var);
+ return (inst->m_op == kIROp_Undefined) || (inst->m_op == kIROp_Var);
}
static bool isUnmodifying(IRFunc* func)
@@ -278,8 +278,8 @@ static InstructionUsageType getInstructionUsageType(IRInst* user, IRInst* inst)
switch (user->getOp())
{
- case kIROp_loop:
- case kIROp_unconditionalBranch:
+ case kIROp_Loop:
+ case kIROp_UnconditionalBranch:
// TODO: Ignore branches for now
return None;
@@ -520,7 +520,7 @@ static List<IRStructField*> checkFieldsFromExit(
static void checkConstructor(IRFunc* func, ReachabilityContext& reachability, DiagnosticSink* sink)
{
- auto constructor = func->findDecoration<IRConstructorDecorartion>();
+ auto constructor = func->findDecoration<IRConstructorDecoration>();
if (!constructor)
return;
@@ -598,7 +598,7 @@ static void checkUninitializedValues(IRFunc* func, DiagnosticSink* sink)
ReachabilityContext reachability(func);
// Used for a further analysis and to skip usual return checks
- auto constructor = func->findDecoration<IRConstructorDecorartion>();
+ auto constructor = func->findDecoration<IRConstructorDecoration>();
// Special checks for stages e.g. raytracing shader
Stage stage = Stage::Unknown;
diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp
index 497281114..687841d5e 100644
--- a/source/slang/slang-ir-util.cpp
+++ b/source/slang/slang-ir-util.cpp
@@ -871,8 +871,8 @@ bool canInstHaveSideEffectAtAddress(IRGlobalValueWithCode* func, IRInst* inst, I
}
}
break;
- case kIROp_unconditionalBranch:
- case kIROp_loop:
+ case kIROp_UnconditionalBranch:
+ case kIROp_Loop:
{
auto branch = as<IRUnconditionalBranch>(inst);
// If any pointer typed argument of the branch inst may overlap addr, return true.
@@ -922,7 +922,7 @@ IRInst* getUndefInst(IRBuilder builder, IRModule* module)
for (auto inst : module->getModuleInst()->getChildren())
{
- if (inst->getOp() == kIROp_undefined && inst->getDataType() &&
+ if (inst->getOp() == kIROp_Undefined && inst->getDataType() &&
inst->getDataType()->getOp() == kIROp_VoidType)
{
undefInst = inst;
diff --git a/source/slang/slang-ir-validate.cpp b/source/slang/slang-ir-validate.cpp
index b3d6504ab..bf5d8ed5d 100644
--- a/source/slang/slang-ir-validate.cpp
+++ b/source/slang/slang-ir-validate.cpp
@@ -220,7 +220,7 @@ void validateIRInstOperand(IRValidateContext* context, IRInst* inst, IRUse* oper
}
// We allow out-of-order def-use in global scope.
- bool allInGlobalScope = inst->getParent() && inst->getParent()->getOp() == kIROp_Module;
+ bool allInGlobalScope = inst->getParent() && inst->getParent()->getOp() == kIROp_ModuleInst;
if (allInGlobalScope)
{
for (UInt i = 0; i < inst->getOperandCount(); i++)
@@ -230,7 +230,7 @@ void validateIRInstOperand(IRValidateContext* context, IRInst* inst, IRUse* oper
continue;
if (!op->getParent())
continue;
- if (op->getParent()->getOp() != kIROp_Module)
+ if (op->getParent()->getOp() != kIROp_ModuleInst)
{
allInGlobalScope = false;
break;
@@ -292,10 +292,10 @@ void validateIRInstOperands(IRInst* inst)
return;
switch (inst->getOp())
{
- case kIROp_loop:
- case kIROp_ifElse:
- case kIROp_unconditionalBranch:
- case kIROp_conditionalBranch:
+ case kIROp_Loop:
+ case kIROp_IfElse:
+ case kIROp_UnconditionalBranch:
+ case kIROp_ConditionalBranch:
case kIROp_Switch:
return;
default:
@@ -325,12 +325,12 @@ void validateCodeBody(IRValidateContext* context, IRGlobalValueWithCode* code)
validate(context, terminator, block, "block must have valid terminator inst.");
switch (terminator->getOp())
{
- case kIROp_conditionalBranch:
+ case kIROp_ConditionalBranch:
validateBranchTarget(terminator, as<IRConditionalBranch>(terminator)->getTrueBlock());
validateBranchTarget(terminator, as<IRConditionalBranch>(terminator)->getFalseBlock());
break;
- case kIROp_loop:
- case kIROp_unconditionalBranch:
+ case kIROp_Loop:
+ case kIROp_UnconditionalBranch:
validateBranchTarget(
terminator,
as<IRUnconditionalBranch>(terminator)->getTargetBlock());
diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp
index 6e7e573b8..dc25b1489 100644
--- a/source/slang/slang-ir.cpp
+++ b/source/slang/slang-ir.cpp
@@ -94,63 +94,6 @@ IRInst* cloneGlobalValueWithLinkage(
IRInst* originalVal,
IRLinkageDecoration* originalLinkage);
-struct IROpMapEntry
-{
- IROp op;
- IROpInfo info;
-};
-
-// TODO: We should ideally be speeding up the name->inst
-// mapping by using a dictionary, or even by pre-computing
-// a hash table to be stored as a `static const` array.
-//
-// NOTE! That this array is now constructed in such a way that looking up
-// an entry from an op is fast, by keeping blocks of main, and pseudo ops in same order
-// as the ops themselves. Care must be taken to keep this constraint.
-static const IROpMapEntry kIROps[] = {
-
-// Main ops in order
-#define INST(ID, MNEMONIC, ARG_COUNT, FLAGS) \
- {kIROp_##ID, \
- { \
- #MNEMONIC, \
- ARG_COUNT, \
- FLAGS, \
- }},
-#include "slang-ir-inst-defs.h"
-
- // Invalid op sentinel value comes after all the valid ones
- {kIROp_Invalid, {"invalid", 0, 0}},
-};
-
-IROpInfo getIROpInfo(IROp opIn)
-{
- const int op = opIn & kIROpMask_OpMask;
- if (op < kIROpCount)
- {
- // It's a main op
- const auto& entry = kIROps[op];
- SLANG_ASSERT(entry.op == op);
- return entry.info;
- }
-
- // Don't know what this is
- SLANG_ASSERT(!"Invalid op");
- SLANG_ASSERT(kIROps[kIROpCount].op == kIROp_Invalid);
- return kIROps[kIROpCount].info;
-}
-
-IROp findIROp(const UnownedStringSlice& name)
-{
- for (auto ee : kIROps)
- {
- if (name == ee.info.name)
- return ee.op;
- }
-
- return IROp(kIROp_Invalid);
-}
-
//
@@ -584,15 +527,15 @@ static IRBlock::SuccessorList getSuccessors(IRInst* terminator)
case kIROp_GenericAsm:
break;
- case kIROp_unconditionalBranch:
- case kIROp_loop:
+ case kIROp_UnconditionalBranch:
+ case kIROp_Loop:
// unconditonalBranch <block>
begin = operands + 0;
end = begin + 1;
break;
- case kIROp_conditionalBranch:
- case kIROp_ifElse:
+ case kIROp_ConditionalBranch:
+ case kIROp_IfElse:
// conditionalBranch <condition> <trueBlock> <falseBlock>
begin = operands + 1;
end = begin + 2;
@@ -759,10 +702,10 @@ UInt IRUnconditionalBranch::getArgCount()
{
switch (getOp())
{
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
return getOperandCount() - 1;
- case kIROp_loop:
+ case kIROp_Loop:
return getOperandCount() - 3;
default:
@@ -775,10 +718,10 @@ IRUse* IRUnconditionalBranch::getArgs()
{
switch (getOp())
{
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
return getOperands() + 1;
- case kIROp_loop:
+ case kIROp_Loop:
return getOperands() + 3;
default:
@@ -791,10 +734,10 @@ void IRUnconditionalBranch::removeArgument(UInt index)
{
switch (getOp())
{
- case kIROp_unconditionalBranch:
+ case kIROp_UnconditionalBranch:
removeOperand(1 + index);
break;
- case kIROp_loop:
+ case kIROp_Loop:
removeOperand(3 + index);
break;
default:
@@ -892,10 +835,10 @@ bool isTerminatorInst(IROp op)
return false;
case kIROp_Return:
- case kIROp_unconditionalBranch:
- case kIROp_conditionalBranch:
- case kIROp_loop:
- case kIROp_ifElse:
+ case kIROp_UnconditionalBranch:
+ case kIROp_ConditionalBranch:
+ case kIROp_Loop:
+ case kIROp_IfElse:
case kIROp_Switch:
case kIROp_Unreachable:
case kIROp_MissingReturn:
@@ -2899,7 +2842,7 @@ IRTypePack* IRBuilder::getTypePack(UInt count, IRType* const* types)
return (IRTypePack*)getType(kIROp_TypePack, count, (IRInst* const*)types);
}
-IRExpandType* IRBuilder::getExpandTypeOrVal(
+IRExpandTypeOrVal* IRBuilder::getExpandTypeOrVal(
IRType* type,
IRInst* pattern,
ArrayView<IRInst*> capture)
@@ -2907,7 +2850,7 @@ IRExpandType* IRBuilder::getExpandTypeOrVal(
ShortList<IRInst*> args;
args.add(pattern);
args.addRange(capture);
- return (IRExpandType*)emitIntrinsicInst(
+ return (IRExpandTypeOrVal*)emitIntrinsicInst(
type,
kIROp_ExpandTypeOrVal,
args.getCount(),
@@ -3350,7 +3293,7 @@ IRInst* IRBuilder::emitGetValueFromBoundInterface(IRType* type, IRInst* boundInt
IRUndefined* IRBuilder::emitUndefined(IRType* type)
{
- auto inst = createInst<IRUndefined>(this, kIROp_undefined, type);
+ auto inst = createInst<IRUndefined>(this, kIROp_Undefined, type);
addInst(inst);
@@ -3836,7 +3779,7 @@ IRInst* IRBuilder::emitLookupInterfaceMethodInst(
IRInst* args[] = {witnessTableVal, interfaceMethodVal};
- return createIntrinsicInst(type, kIROp_LookupWitness, 2, args);
+ return createIntrinsicInst(type, kIROp_LookupWitnessMethod, 2, args);
}
IRInst* IRBuilder::emitGetSequentialIDInst(IRInst* rttiObj)
@@ -4443,7 +4386,7 @@ IRInst* IRBuilder::emitMakeString(IRInst* nativeStr)
IRInst* IRBuilder::emitGetNativeString(IRInst* str)
{
- return emitIntrinsicInst(getNativeStringType(), kIROp_getNativeStr, 1, &str);
+ return emitIntrinsicInst(getNativeStringType(), kIROp_GetNativeStr, 1, &str);
}
IRInst* IRBuilder::emitGetElement(IRType* type, IRInst* arrayLikeType, IRIntegerValue element)
@@ -4754,7 +4697,7 @@ RefPtr<IRModule> IRModule::create(Session* session)
{
RefPtr<IRModule> module = new IRModule(session);
- auto moduleInst = module->_allocateInst<IRModuleInst>(kIROp_Module, 0);
+ auto moduleInst = module->_allocateInst<IRModuleInst>(kIROp_ModuleInst, 0);
module->m_moduleInst = moduleInst;
moduleInst->module = module;
@@ -5594,7 +5537,7 @@ IRInst* IRBuilder::emitGetOffsetPtr(IRInst* base, IRInst* offset)
IRInst* IRBuilder::emitGetAddress(IRType* type, IRInst* value)
{
- auto inst = createInst<IRGetAddress>(this, kIROp_GetAddr, type, value);
+ auto inst = createInst<IRGetAddress>(this, kIROp_GetAddress, type, value);
addInst(inst);
return inst;
@@ -5608,7 +5551,7 @@ IRInst* IRBuilder::emitSwizzle(
{
auto inst = createInstWithTrailingArgs<IRSwizzle>(
this,
- kIROp_swizzle,
+ kIROp_Swizzle,
type,
base,
elementCount,
@@ -5728,7 +5671,7 @@ IRInst* IRBuilder::emitSwizzleSet(
auto inst = createInstWithTrailingArgs<IRSwizzleSet>(
this,
- kIROp_swizzleSet,
+ kIROp_SwizzleSet,
type,
fixedArgCount,
fixedArgs,
@@ -5884,7 +5827,7 @@ IRInst* IRBuilder::emitMissingReturn()
IRInst* IRBuilder::emitDiscard()
{
- auto inst = createInst<IRDiscard>(this, kIROp_discard, nullptr);
+ auto inst = createInst<IRDiscard>(this, kIROp_Discard, nullptr);
addInst(inst);
return inst;
}
@@ -5906,7 +5849,7 @@ IRInst* IRBuilder::emitLoopExitValue(IRInst* value)
IRInst* IRBuilder::emitBranch(IRBlock* pBlock)
{
- auto inst = createInst<IRUnconditionalBranch>(this, kIROp_unconditionalBranch, nullptr, pBlock);
+ auto inst = createInst<IRUnconditionalBranch>(this, kIROp_UnconditionalBranch, nullptr, pBlock);
addInst(inst);
return inst;
}
@@ -5919,7 +5862,7 @@ IRInst* IRBuilder::emitBranch(IRBlock* block, Int argCount, IRInst* const* args)
argList.add(args[i]);
auto inst = createInst<IRUnconditionalBranch>(
this,
- kIROp_unconditionalBranch,
+ kIROp_UnconditionalBranch,
nullptr,
argList.getCount(),
argList.getBuffer());
@@ -5942,7 +5885,7 @@ IRInst* IRBuilder::emitLoop(IRBlock* target, IRBlock* breakBlock, IRBlock* conti
IRInst* args[] = {target, breakBlock, continueBlock};
UInt argCount = sizeof(args) / sizeof(args[0]);
- auto inst = createInst<IRLoop>(this, kIROp_loop, nullptr, argCount, args);
+ auto inst = createInst<IRLoop>(this, kIROp_Loop, nullptr, argCount, args);
addInst(inst);
return inst;
}
@@ -5964,7 +5907,7 @@ IRInst* IRBuilder::emitLoop(
argList.add(args[ii]);
auto inst =
- createInst<IRLoop>(this, kIROp_loop, nullptr, argList.getCount(), argList.getBuffer());
+ createInst<IRLoop>(this, kIROp_Loop, nullptr, argList.getCount(), argList.getBuffer());
addInst(inst);
return inst;
}
@@ -5975,7 +5918,7 @@ IRInst* IRBuilder::emitBranch(IRInst* val, IRBlock* trueBlock, IRBlock* falseBlo
UInt argCount = sizeof(args) / sizeof(args[0]);
auto inst =
- createInst<IRConditionalBranch>(this, kIROp_conditionalBranch, nullptr, argCount, args);
+ createInst<IRConditionalBranch>(this, kIROp_ConditionalBranch, nullptr, argCount, args);
addInst(inst);
return inst;
}
@@ -5989,7 +5932,7 @@ IRIfElse* IRBuilder::emitIfElse(
IRInst* args[] = {val, trueBlock, falseBlock, afterBlock};
UInt argCount = sizeof(args) / sizeof(args[0]);
- auto inst = createInst<IRIfElse>(this, kIROp_ifElse, nullptr, argCount, args);
+ auto inst = createInst<IRIfElse>(this, kIROp_IfElse, nullptr, argCount, args);
addInst(inst);
return inst;
}
@@ -7654,7 +7597,7 @@ void dumpIR(
context.options = options;
context.sourceManager = sourceManager;
- if (globalVal->getOp() == kIROp_Module)
+ if (globalVal->getOp() == kIROp_ModuleInst)
dumpIRModule(&context, globalVal->getModule());
else
dumpInst(&context, globalVal);
@@ -7815,7 +7758,7 @@ static bool _isTypeOperandEqual(IRInst* a, IRInst* b)
return static_cast<IRConstant*>(a)->isValueEqual(static_cast<IRConstant*>(b)) &&
isTypeEqual(a->getFullType(), b->getFullType());
}
- if (IRSpecialize::isaImpl(opA) || opA == kIROp_LookupWitness)
+ if (IRSpecialize::isaImpl(opA) || opA == kIROp_LookupWitnessMethod)
{
return _areTypeOperandsEqual(a, b);
}
@@ -8131,7 +8074,7 @@ static void _maybeHoistOperand(IRUse* use)
continue;
// We allow out-of-order uses in global scope.
- if (operand->getParent() && operand->getParent()->getOp() == kIROp_Module)
+ if (operand->getParent() && operand->getParent()->getOp() == kIROp_ModuleInst)
continue;
// If the operand is defined after user, move it to before user.
@@ -8516,7 +8459,7 @@ void IRInst::transferDecorationsTo(IRInst* target)
bool IRInst::mightHaveSideEffects(SideEffectAnalysisOptions options)
{
// TODO: We should drive this based on flags specified
- // in `ir-inst-defs.h` isntead of hard-coding things here,
+ // in `ir-inst-defs.yaml` isntead of hard-coding things here,
// but this is good enough for now if we are conservative:
if (as<IRType>(this))
@@ -8596,12 +8539,12 @@ bool IRInst::mightHaveSideEffects(SideEffectAnalysisOptions options)
case kIROp_LiveRangeEnd:
case kIROp_Nop:
- case kIROp_undefined:
+ case kIROp_Undefined:
case kIROp_DefaultConstruct:
case kIROp_Specialize:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
case kIROp_GetSequentialID:
- case kIROp_GetAddr:
+ case kIROp_GetAddress:
case kIROp_GetValueFromBoundInterface:
case kIROp_MakeUInt64:
case kIROp_MakeCoopVector:
@@ -8615,7 +8558,7 @@ bool IRInst::mightHaveSideEffects(SideEffectAnalysisOptions options)
case kIROp_MakeArrayFromElement:
case kIROp_MakeStruct:
case kIROp_MakeString:
- case kIROp_getNativeStr:
+ case kIROp_GetNativeStr:
case kIROp_MakeResultError:
case kIROp_MakeResultValue:
case kIROp_GetResultError:
@@ -8650,8 +8593,8 @@ bool IRInst::mightHaveSideEffects(SideEffectAnalysisOptions options)
case kIROp_UpdateElement:
case kIROp_MeshOutputRef:
case kIROp_MakeVectorFromScalar:
- case kIROp_swizzle:
- case kIROp_swizzleSet: // Doesn't actually "set" anything - just returns the resulting
+ case kIROp_Swizzle:
+ case kIROp_SwizzleSet: // Doesn't actually "set" anything - just returns the resulting
// vector
case kIROp_Add:
case kIROp_Sub:
@@ -9115,7 +9058,7 @@ bool isMovableInst(IRInst* inst)
case kIROp_GetOffsetPtr:
case kIROp_UpdateElement:
case kIROp_Specialize:
- case kIROp_LookupWitness:
+ case kIROp_LookupWitnessMethod:
case kIROp_OptionalHasValue:
case kIROp_GetOptionalValue:
case kIROp_MakeOptionalValue:
@@ -9128,8 +9071,8 @@ bool isMovableInst(IRInst* inst)
case kIROp_MakeMatrix:
case kIROp_MakeMatrixFromScalar:
case kIROp_MakeVectorFromScalar:
- case kIROp_swizzle:
- case kIROp_swizzleSet:
+ case kIROp_Swizzle:
+ case kIROp_SwizzleSet:
case kIROp_MatrixReshape:
case kIROp_MakeString:
case kIROp_MakeResultError:
diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h
index 0ee4bf94b..bd16eb1b9 100644
--- a/source/slang/slang-ir.h
+++ b/source/slang/slang-ir.h
@@ -1,6 +1,5 @@
// slang-ir.h
-#ifndef SLANG_IR_H_INCLUDED
-#define SLANG_IR_H_INCLUDED
+#pragma once
// This file defines the intermediate representation (IR) used for Slang
// shader code. This is a typed static single assignment (SSA) IR,
@@ -11,12 +10,17 @@
#include "../compiler-core/slang-source-map.h"
#include "../core/slang-basic.h"
#include "../core/slang-memory-arena.h"
+#include "slang-ast-type.h"
#include "slang-container-pool.h"
+#include "slang-ir-insts-enum.h"
#include "slang-type-system-shared.h"
-#include <bit>
#include <functional>
+//
+#include "slang-ir.h.fiddle"
+
+FIDDLE()
namespace Slang
{
@@ -36,6 +40,8 @@ struct IRModule;
struct IRStructField;
struct IRStructKey;
+FIDDLE(instStructForwardDecls())
+
typedef unsigned int IROpFlags;
enum : IROpFlags
{
@@ -48,37 +54,6 @@ enum : IROpFlags
1 << 3, ///< If set this op should always be hoisted but should never be deduplicated.
};
-/* Bit usage of IROp is a follows
-
- MainOp | Other
-Bit range: 0-10 | Remaining bits
-
-For doing range checks (for example for doing isa tests), the value is masked by kIROpMask_OpMask,
-such that the Other bits don't interfere. The other bits can be used for storage for anything that
-needs to identify as a different 'op' or 'type'. It is currently used currently for storing the
-TextureFlavor of a IRResourceTypeBase derived types for example.
-
-TODO: We should eliminate the use of the "other" bits so that the entire value/state
-of an instruction is manifest in its opcode, operands, and children.
-*/
-enum IROp : int32_t
-{
-#define INST(ID, MNEMONIC, ARG_COUNT, FLAGS) kIROp_##ID,
-#include "slang-ir-inst-defs.h"
-
- /// The total number of valid opcodes
- kIROpCount,
-
- /// An invalid opcode used to represent a missing or unknown opcode value.
- kIROp_Invalid = kIROpCount,
-
-#define INST(ID, MNEMONIC, ARG_COUNT, FLAGS) /* empty */
-#define INST_RANGE(BASE, FIRST, LAST) \
- kIROp_First##BASE = kIROp_##FIRST, kIROp_Last##BASE = kIROp_##LAST,
-
-#include "slang-ir-inst-defs.h"
-};
-
/* IROpMeta describes values for the layout of IROps */
enum IROpMeta
{
@@ -557,8 +532,10 @@ struct IRBlock;
// Every value in the IR is an instruction (even things
// like literal values).
//
+FIDDLE()
struct IRInst
{
+ FIDDLE(...)
// The operation that this value represents
IROp m_op;
@@ -963,39 +940,18 @@ typename IRFilteredInstList<T>::Iterator IRFilteredInstList<T>::end()
// Types
-#define IR_LEAF_ISA(NAME) \
- static bool isaImpl(IROp op) \
- { \
- return (kIROpMask_OpMask & op) == kIROp_##NAME; \
- }
-#define IR_PARENT_ISA(NAME) \
- static bool isaImpl(IROp opIn) \
- { \
- const int op = (kIROpMask_OpMask & opIn); \
- return op >= kIROp_First##NAME && op <= kIROp_Last##NAME; \
- }
-
-#define SIMPLE_IR_TYPE(NAME, BASE) \
- struct IR##NAME : IR##BASE \
- { \
- IR_LEAF_ISA(NAME) \
- };
-#define SIMPLE_IR_PARENT_TYPE(NAME, BASE) \
- struct IR##NAME : IR##BASE \
- { \
- IR_PARENT_ISA(NAME) \
- };
-
// All types in the IR are represented as instructions which conceptually
// execute before run time.
+FIDDLE()
struct IRType : IRInst
{
+ FIDDLE(baseInst{noIsaImpl = true})
IRType* getCanonicalType() { return this; }
// Hack: specialize can also be a type. We should consider using a
// separate `specializeType` op code for types so we can use the normal
- // `IR_PARENT_ISA` macro here.
+ // isaImpl definition macro here.
static bool isaImpl(IROp opIn)
{
const int op = (kIROpMask_OpMask & opIn);
@@ -1005,32 +961,31 @@ struct IRType : IRInst
IRType* unwrapArray(IRType* type);
+FIDDLE()
struct IRBasicType : IRType
{
+ FIDDLE(baseInst())
BaseType getBaseType() { return BaseType(getOp() - kIROp_FirstBasicType); }
-
- IR_PARENT_ISA(BasicType)
};
+FIDDLE()
struct IRVoidType : IRBasicType
{
- IR_LEAF_ISA(VoidType)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRBoolType : IRBasicType
{
- IR_LEAF_ISA(BoolType)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRStringTypeBase : IRType
{
- IR_PARENT_ISA(StringTypeBase)
+ FIDDLE(baseInst())
};
-SIMPLE_IR_TYPE(StringType, StringTypeBase)
-SIMPLE_IR_TYPE(NativeStringType, StringTypeBase)
-
-SIMPLE_IR_TYPE(DynamicType, Type)
// True if types are equal
// Note compares nominal types by name alone
@@ -1075,8 +1030,10 @@ typedef int64_t IRIntegerValue;
typedef uint64_t IRUnsignedIntegerValue;
typedef double IRFloatingPointValue;
+FIDDLE()
struct IRConstant : IRInst
{
+ FIDDLE(baseInst())
enum class FloatKind
{
Finite,
@@ -1129,7 +1086,6 @@ struct IRConstant : IRInst
/// Get the hash
HashCode getHashCode();
- IR_PARENT_ISA(Constant)
// Must be last member, because data may be held behind
// NOTE! The total size of IRConstant may not be allocated - only enough space is allocated for
@@ -1137,25 +1093,25 @@ struct IRConstant : IRInst
ValueUnion value;
};
+FIDDLE()
struct IRIntLit : IRConstant
{
+ FIDDLE(leafInst())
IRIntegerValue getValue() { return value.intVal; }
-
- IR_LEAF_ISA(IntLit);
};
+FIDDLE()
struct IRFloatLit : IRConstant
{
+ FIDDLE(leafInst())
IRFloatingPointValue getValue() { return value.floatVal; }
-
- IR_LEAF_ISA(FloatLit);
};
+FIDDLE()
struct IRBoolLit : IRConstant
{
+ FIDDLE(leafInst())
bool getValue() { return value.intVal != 0; }
-
- IR_LEAF_ISA(BoolLit);
};
// Get the compile-time constant integer value of an instruction,
@@ -1167,33 +1123,37 @@ IRIntegerValue getIntVal(IRInst* inst);
// the actual size.
IRIntegerValue getArraySizeVal(IRInst* inst);
+FIDDLE()
struct IRStringLit : IRConstant
{
-
- IR_LEAF_ISA(StringLit);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRBlobLit : IRConstant
{
- IR_LEAF_ISA(BlobLit);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRPtrLit : IRConstant
{
- IR_LEAF_ISA(PtrLit);
+ FIDDLE(leafInst())
void* getValue() { return value.ptrVal; }
};
+FIDDLE()
struct IRVoidLit : IRConstant
{
- IR_LEAF_ISA(VoidLit);
+ FIDDLE(leafInst())
};
// A instruction that ends a basic block (usually because of control flow)
+FIDDLE()
struct IRTerminatorInst : IRInst
{
- IR_PARENT_ISA(TerminatorInst)
+ FIDDLE(baseInst())
};
// A function parameter is owned by a basic block, and represents
@@ -1204,12 +1164,12 @@ struct IRTerminatorInst : IRInst
// In each case, the basic idea is that a block is a "label with
// arguments."
//
+FIDDLE()
struct IRParam : IRInst
{
+ FIDDLE(leafInst())
IRParam* getNextParam();
IRParam* getPrevParam();
-
- IR_LEAF_ISA(Param)
};
/// A control-flow edge from one basic block to another
@@ -1239,8 +1199,10 @@ private:
// no function declarations, or nested blocks). We also expect
// that the previous/next instruction are always a basic block.
//
+FIDDLE()
struct IRBlock : IRInst
{
+ FIDDLE(leafInst())
// Linked list of the instructions contained in this block
//
IRInst* getFirstInst() { return getChildren().first; }
@@ -1386,14 +1348,13 @@ struct IRBlock : IRInst
SuccessorList getSuccessors();
//
-
- IR_LEAF_ISA(Block)
};
-SIMPLE_IR_TYPE(BasicBlockType, Type)
+FIDDLE()
struct IRResourceTypeBase : IRType
{
+ FIDDLE(baseInst())
IRInst* getShapeInst() { return getOperand(kCoreModule_TextureShapeParameterIndex); }
IRInst* getIsArrayInst() { return getOperand(kCoreModule_TextureIsArrayParameterIndex); }
IRInst* getIsMultisampleInst()
@@ -1461,115 +1422,93 @@ struct IRResourceTypeBase : IRType
}
return SLANG_RESOURCE_ACCESS_UNKNOWN;
}
-
- IR_PARENT_ISA(ResourceTypeBase);
};
+FIDDLE()
struct IRResourceType : IRResourceTypeBase
{
+ FIDDLE(baseInst())
IRType* getElementType() { return (IRType*)getOperand(0); }
IRInst* getSampleCount() { return getSampleCountInst(); }
bool hasFormat() { return getOperandCount() >= 9; }
IRIntegerValue getFormat() { return getIntVal(getFormatInst()); }
-
- IR_PARENT_ISA(ResourceType)
};
+FIDDLE()
struct IRTextureTypeBase : IRResourceType
{
- IR_PARENT_ISA(TextureTypeBase)
+ FIDDLE(baseInst())
};
+FIDDLE()
struct IRTextureType : IRTextureTypeBase
{
- IR_LEAF_ISA(TextureType)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRGLSLImageType : IRTextureTypeBase
{
- IR_LEAF_ISA(GLSLImageType)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRSubpassInputType : IRType
{
+ FIDDLE(leafInst())
IRType* getElementType() { return (IRType*)getOperand(0); }
IRInst* getIsMultisampleInst() { return getOperand(1); }
bool isMultisample() { return getIntVal(getIsMultisampleInst()) == 1; }
-
- IR_LEAF_ISA(SubpassInputType)
};
+FIDDLE()
struct IRSamplerStateTypeBase : IRType
{
- IR_PARENT_ISA(SamplerStateTypeBase)
+ FIDDLE(baseInst())
};
-SIMPLE_IR_TYPE(SamplerStateType, SamplerStateTypeBase)
-SIMPLE_IR_TYPE(SamplerComparisonStateType, SamplerStateTypeBase)
+FIDDLE()
struct IRBuiltinGenericType : IRType
{
+ FIDDLE(baseInst())
IRType* getElementType() { return (IRType*)getOperand(0); }
-
- IR_PARENT_ISA(BuiltinGenericType)
};
-SIMPLE_IR_PARENT_TYPE(PointerLikeType, BuiltinGenericType);
+FIDDLE()
struct IRHLSLStructuredBufferTypeBase : IRBuiltinGenericType
{
+ FIDDLE(baseInst())
IRType* getDataLayout() { return (IRType*)getOperand(1); }
-
- IR_PARENT_ISA(HLSLStructuredBufferTypeBase)
};
-SIMPLE_IR_TYPE(HLSLStructuredBufferType, HLSLStructuredBufferTypeBase)
-SIMPLE_IR_TYPE(HLSLRWStructuredBufferType, HLSLStructuredBufferTypeBase)
-SIMPLE_IR_TYPE(HLSLRasterizerOrderedStructuredBufferType, HLSLStructuredBufferTypeBase)
-
-SIMPLE_IR_PARENT_TYPE(UntypedBufferResourceType, Type)
-SIMPLE_IR_PARENT_TYPE(ByteAddressBufferTypeBase, UntypedBufferResourceType)
-SIMPLE_IR_TYPE(HLSLByteAddressBufferType, ByteAddressBufferTypeBase)
-SIMPLE_IR_TYPE(HLSLRWByteAddressBufferType, ByteAddressBufferTypeBase)
-SIMPLE_IR_TYPE(HLSLRasterizerOrderedByteAddressBufferType, ByteAddressBufferTypeBase)
-
-SIMPLE_IR_TYPE(HLSLAppendStructuredBufferType, HLSLStructuredBufferTypeBase)
-SIMPLE_IR_TYPE(HLSLConsumeStructuredBufferType, HLSLStructuredBufferTypeBase)
+FIDDLE()
struct IRHLSLPatchType : IRType
{
+ FIDDLE(baseInst())
IRType* getElementType() { return (IRType*)getOperand(0); }
IRInst* getElementCount() { return getOperand(1); }
-
- IR_PARENT_ISA(HLSLPatchType)
};
-SIMPLE_IR_TYPE(HLSLInputPatchType, HLSLPatchType)
-SIMPLE_IR_TYPE(HLSLOutputPatchType, HLSLPatchType)
-
-SIMPLE_IR_PARENT_TYPE(HLSLStreamOutputType, BuiltinGenericType)
-SIMPLE_IR_TYPE(HLSLPointStreamType, HLSLStreamOutputType)
-SIMPLE_IR_TYPE(HLSLLineStreamType, HLSLStreamOutputType)
-SIMPLE_IR_TYPE(HLSLTriangleStreamType, HLSLStreamOutputType)
// Mesh shaders
// TODO: Ellie, should this parent struct be shared with Patch?
// IRArrayLikeType? IROpaqueArrayLikeType?
+FIDDLE()
struct IRMeshOutputType : IRType
{
+ FIDDLE(baseInst())
IRType* getElementType() { return (IRType*)getOperand(0); }
IRInst* getMaxElementCount() { return getOperand(1); }
-
- IR_PARENT_ISA(MeshOutputType)
};
-SIMPLE_IR_TYPE(VerticesType, MeshOutputType)
-SIMPLE_IR_TYPE(IndicesType, MeshOutputType)
-SIMPLE_IR_TYPE(PrimitivesType, MeshOutputType)
+FIDDLE()
struct IRMetalMeshType : IRType
{
- IR_LEAF_ISA(MetalMeshType);
+ FIDDLE(leafInst())
IRType* getVerticesType() { return (IRType*)getOperand(0); }
IRType* getPrimitivesType() { return (IRType*)getOperand(1); }
@@ -1578,35 +1517,38 @@ struct IRMetalMeshType : IRType
IRIntLit* getTopology() { return (IRIntLit*)getOperand(4); }
};
-SIMPLE_IR_TYPE(MetalMeshGridPropertiesType, Type)
+FIDDLE()
+struct IRPointerLikeType : IRBuiltinGenericType
+{
+ FIDDLE(baseInst())
+};
-SIMPLE_IR_TYPE(GLSLInputAttachmentType, Type)
-SIMPLE_IR_PARENT_TYPE(ParameterGroupType, PointerLikeType)
+FIDDLE()
+struct IRParameterGroupType : IRPointerLikeType
+{
+ FIDDLE(baseInst())
+};
+FIDDLE()
struct IRUniformParameterGroupType : IRParameterGroupType
{
- IR_PARENT_ISA(UniformParameterGroupType)
+ FIDDLE(baseInst())
IRType* getDataLayout() { return getOperandCount() > 1 ? (IRType*)getOperand(1) : nullptr; }
};
-SIMPLE_IR_PARENT_TYPE(VaryingParameterGroupType, ParameterGroupType)
-SIMPLE_IR_TYPE(ConstantBufferType, UniformParameterGroupType)
-SIMPLE_IR_TYPE(TextureBufferType, UniformParameterGroupType)
-SIMPLE_IR_TYPE(GLSLInputParameterGroupType, VaryingParameterGroupType)
-SIMPLE_IR_TYPE(GLSLOutputParameterGroupType, VaryingParameterGroupType)
-SIMPLE_IR_TYPE(ParameterBlockType, UniformParameterGroupType)
-SIMPLE_IR_TYPE(DynamicResourceType, Type)
+FIDDLE()
struct IRGLSLShaderStorageBufferType : IRBuiltinGenericType
{
+ FIDDLE(leafInst())
IRType* getDataLayout() { return (IRType*)getOperand(1); }
-
- IR_LEAF_ISA(GLSLShaderStorageBufferType)
};
+FIDDLE()
struct IRArrayTypeBase : IRType
{
+ FIDDLE(baseInst())
IRType* getElementType() { return (IRType*)getOperand(0); }
// Returns the element count for an `IRArrayType`, and null
@@ -1629,51 +1571,43 @@ struct IRArrayTypeBase : IRType
}
return nullptr;
}
-
- IR_PARENT_ISA(ArrayTypeBase)
};
+FIDDLE()
struct IRArrayType : IRArrayTypeBase
{
- IR_LEAF_ISA(ArrayType)
+ FIDDLE(leafInst())
};
-SIMPLE_IR_TYPE(UnsizedArrayType, ArrayTypeBase)
+FIDDLE()
struct IRAtomicType : IRType
{
- IR_LEAF_ISA(AtomicType)
+ FIDDLE(leafInst())
IRType* getElementType() { return (IRType*)getOperand(0); }
};
-SIMPLE_IR_PARENT_TYPE(Rate, Type)
-SIMPLE_IR_TYPE(ConstExprRate, Rate)
-SIMPLE_IR_TYPE(SpecConstRate, Rate)
-SIMPLE_IR_TYPE(GroupSharedRate, Rate)
-SIMPLE_IR_TYPE(ActualGlobalRate, Rate)
+FIDDLE()
struct IRRateQualifiedType : IRType
{
+ FIDDLE(leafInst())
IRRate* getRate() { return (IRRate*)getOperand(0); }
IRType* getValueType() { return (IRType*)getOperand(1); }
-
- IR_LEAF_ISA(RateQualifiedType)
};
+FIDDLE()
struct IRDescriptorHandleType : IRType
{
+ FIDDLE(leafInst())
IRType* getResourceType() { return (IRType*)getOperand(0); }
- IR_LEAF_ISA(DescriptorHandleType)
};
// Unlike the AST-level type system where `TypeType` tracks the
// underlying type, the "type of types" in the IR is a simple
// value with no operands, so that all type nodes have the
// same type.
-SIMPLE_IR_PARENT_TYPE(Kind, Type);
-SIMPLE_IR_TYPE(TypeKind, Kind);
-SIMPLE_IR_TYPE(TypeParameterPackKind, Kind);
// The kind of any and all generics.
//
@@ -1684,83 +1618,90 @@ SIMPLE_IR_TYPE(TypeParameterPackKind, Kind);
// "higher-kinded" generics (e.g., a generic that takes another
// generic as a parameter).
//
-SIMPLE_IR_TYPE(GenericKind, Kind)
+FIDDLE()
struct IRDifferentialPairTypeBase : IRType
{
+ FIDDLE(baseInst())
IRType* getValueType() { return (IRType*)getOperand(0); }
IRInst* getWitness() { return (IRInst*)getOperand(1); }
-
- IR_PARENT_ISA(DifferentialPairTypeBase)
};
+FIDDLE()
struct IRDifferentialPairType : IRDifferentialPairTypeBase
{
- IR_LEAF_ISA(DifferentialPairType)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRDifferentialPtrPairType : IRDifferentialPairTypeBase
{
- IR_LEAF_ISA(DifferentialPtrPairType)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRDifferentialPairUserCodeType : IRDifferentialPairTypeBase
{
- IR_LEAF_ISA(DifferentialPairUserCodeType)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRBackwardDiffIntermediateContextType : IRType
{
+ FIDDLE(leafInst())
IRInst* getFunc() { return getOperand(0); }
- IR_LEAF_ISA(BackwardDiffIntermediateContextType)
};
+FIDDLE()
struct IRVectorType : IRType
{
+ FIDDLE(leafInst())
IRType* getElementType() { return (IRType*)getOperand(0); }
IRInst* getElementCount() { return getOperand(1); }
-
- IR_LEAF_ISA(VectorType)
};
+FIDDLE()
struct IRMatrixType : IRType
{
+ FIDDLE(leafInst())
IRType* getElementType() { return (IRType*)getOperand(0); }
IRInst* getRowCount() { return getOperand(1); }
IRInst* getColumnCount() { return getOperand(2); }
IRInst* getLayout() { return getOperand(3); }
-
- IR_LEAF_ISA(MatrixType)
};
+FIDDLE()
struct IRArrayListType : IRType
{
+ FIDDLE(leafInst())
IRType* getElementType() { return (IRType*)getOperand(0); }
-
- IR_LEAF_ISA(ArrayListType)
};
+FIDDLE()
struct IRTensorViewType : IRType
{
+ FIDDLE(leafInst())
IRType* getElementType() { return (IRType*)getOperand(0); }
-
- IR_LEAF_ISA(TensorViewType)
};
+FIDDLE()
struct IRTorchTensorType : IRType
{
- IR_LEAF_ISA(TorchTensorType)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRSPIRVLiteralType : IRType
{
- IR_LEAF_ISA(SPIRVLiteralType)
+ FIDDLE(leafInst())
IRType* getValueType() { return static_cast<IRType*>(getOperand(0)); }
};
+FIDDLE()
struct IRPtrTypeBase : IRType
{
+ FIDDLE(baseInst())
IRType* getValueType() { return (IRType*)getOperand(0); }
bool hasAddressSpace()
@@ -1774,63 +1715,62 @@ struct IRPtrTypeBase : IRType
? (AddressSpace) static_cast<IRIntLit*>(getOperand(1))->getValue()
: AddressSpace::Generic;
}
-
- IR_PARENT_ISA(PtrTypeBase)
};
-SIMPLE_IR_TYPE(PtrType, PtrTypeBase)
-SIMPLE_IR_TYPE(RefType, PtrTypeBase)
-SIMPLE_IR_TYPE(ConstRefType, PtrTypeBase)
-SIMPLE_IR_PARENT_TYPE(OutTypeBase, PtrTypeBase)
-SIMPLE_IR_TYPE(OutType, OutTypeBase)
-SIMPLE_IR_TYPE(InOutType, OutTypeBase)
-
+FIDDLE()
struct IRComPtrType : public IRType
{
- IR_LEAF_ISA(ComPtrType);
+ FIDDLE(leafInst())
IRType* getValueType() { return (IRType*)getOperand(0); }
};
+FIDDLE()
struct IRNativePtrType : public IRType
{
- IR_LEAF_ISA(NativePtrType);
+ FIDDLE(leafInst())
IRType* getValueType() { return (IRType*)getOperand(0); }
};
+FIDDLE()
struct IRPseudoPtrType : public IRPtrTypeBase
{
- IR_LEAF_ISA(PseudoPtrType);
+ FIDDLE(leafInst())
};
/// The base class of RawPointerType and RTTIPointerType.
+FIDDLE()
struct IRRawPointerTypeBase : IRType
{
- IR_PARENT_ISA(RawPointerTypeBase);
+ FIDDLE(baseInst())
};
/// Represents a pointer to an object of unknown type.
+FIDDLE()
struct IRRawPointerType : IRRawPointerTypeBase
{
- IR_LEAF_ISA(RawPointerType)
+ FIDDLE(leafInst())
};
/// Represents a pointer to an object whose type is determined at runtime,
/// with type information available through `rttiOperand`.
///
+FIDDLE()
struct IRRTTIPointerType : IRRawPointerTypeBase
{
+ FIDDLE(leafInst())
IRInst* getRTTIOperand() { return getOperand(0); }
- IR_LEAF_ISA(RTTIPointerType)
};
+FIDDLE()
struct IRGlobalHashedStringLiterals : IRInst
{
- IR_LEAF_ISA(GlobalHashedStringLiterals)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRGetStringHash : IRInst
{
- IR_LEAF_ISA(GetStringHash)
+ FIDDLE(leafInst())
IRStringLit* getStringLit() { return as<IRStringLit>(getOperand(0)); }
};
@@ -1840,8 +1780,10 @@ struct IRGetStringHash : IRInst
/// The given IR `builder` will be used if new instructions need to be created.
IRType* tryGetPointedToType(IRBuilder* builder, IRType* type);
+FIDDLE()
struct IRFuncType : IRType
{
+ FIDDLE(leafInst())
IRType* getResultType() { return (IRType*)getOperand(0); }
UInt getParamCount() { return getOperandCount() - 1; }
IRType* getParamType(UInt index) { return (IRType*)getOperand(1 + index); }
@@ -1849,54 +1791,54 @@ struct IRFuncType : IRType
{
return IROperandList<IRType>(getOperands() + 1, getOperands() + getOperandCount());
}
-
- IR_LEAF_ISA(FuncType)
};
+FIDDLE()
struct IRRayQueryType : IRType
{
- IR_LEAF_ISA(RayQueryType)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRHitObjectType : IRType
{
- IR_LEAF_ISA(HitObjectType)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRCoopVectorType : IRType
{
+ FIDDLE(leafInst())
IRType* getElementType() { return (IRType*)getOperand(0); }
IRInst* getElementCount() { return getOperand(1); }
-
- IR_LEAF_ISA(CoopVectorType)
};
+FIDDLE()
struct IRCoopMatrixType : IRType
{
+ FIDDLE(leafInst())
IRType* getElementType() { return (IRType*)getOperand(0); }
IRInst* getScope() { return getOperand(1); }
IRInst* getRowCount() { return getOperand(2); }
IRInst* getColumnCount() { return getOperand(3); }
IRInst* getMatrixUse() { return getOperand(4); }
-
- IR_LEAF_ISA(CoopMatrixType)
};
+FIDDLE()
struct IRTensorAddressingTensorLayoutType : IRType
{
+ FIDDLE(leafInst())
IRInst* getDimension() { return getOperand(0); }
IRInst* getClampMode() { return getOperand(1); }
-
- IR_LEAF_ISA(TensorAddressingTensorLayoutType)
};
+FIDDLE()
struct IRTensorAddressingTensorViewType : IRType
{
+ FIDDLE(leafInst())
IRInst* getDimension() { return getOperand(0); }
IRInst* getHasDimension() { return getOperand(1); }
IRInst* getPermutation(int index) { return getOperand(2 + index); }
-
- IR_LEAF_ISA(TensorAddressingTensorViewType)
};
bool isDefinition(IRInst* inVal);
@@ -1910,9 +1852,10 @@ bool isDefinition(IRInst* inVal);
// (that is, they have mangled names that can be used
// for linkage).
//
+FIDDLE()
struct IRStructKey : IRInst
{
- IR_LEAF_ISA(StructKey)
+ FIDDLE(leafInst())
};
//
// The fields of the struct are then defined as mappings
@@ -1922,8 +1865,10 @@ struct IRStructKey : IRInst
// A struct field thus has two operands: the key, and the
// type of the field.
//
+FIDDLE()
struct IRStructField : IRInst
{
+ FIDDLE(leafInst())
IRStructKey* getKey() { return cast<IRStructKey>(getOperand(0)); }
IRType* getFieldType()
{
@@ -1935,8 +1880,6 @@ struct IRStructField : IRInst
return (IRType*)getOperand(1);
}
void setFieldType(IRType* type) { setOperand(1, type); }
-
- IR_LEAF_ISA(StructField)
};
//
// The struct type is then represented as a parent instruction
@@ -1944,191 +1887,214 @@ struct IRStructField : IRInst
// *not* contain the keys, because code needs to be able to
// reference the keys from scopes outside of the struct.
//
+FIDDLE()
struct IRStructType : IRType
{
+ FIDDLE(leafInst())
IRFilteredInstList<IRStructField> getFields()
{
return IRFilteredInstList<IRStructField>(getChildren());
}
-
- IR_LEAF_ISA(StructType)
};
+FIDDLE()
struct IRClassType : IRType
{
+ FIDDLE(leafInst())
IRFilteredInstList<IRStructField> getFields()
{
return IRFilteredInstList<IRStructField>(getChildren());
}
-
- IR_LEAF_ISA(ClassType)
};
+FIDDLE()
struct IRAssociatedType : IRType
{
- IR_LEAF_ISA(AssociatedType)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRThisType : IRType
{
- IR_LEAF_ISA(ThisType)
+ FIDDLE(leafInst())
IRInst* getConstraintType() { return getOperand(0); }
};
+FIDDLE()
struct IRThisTypeWitness : IRInst
{
- IR_LEAF_ISA(ThisTypeWitness)
+ FIDDLE(leafInst())
IRInst* getConstraintType() { return getOperand(0); }
};
+FIDDLE()
struct IRInterfaceRequirementEntry : IRInst
{
+ FIDDLE(leafInst())
IRInst* getRequirementKey() { return getOperand(0); }
IRInst* getRequirementVal() { return getOperand(1); }
void setRequirementKey(IRInst* val) { setOperand(0, val); }
void setRequirementVal(IRInst* val) { setOperand(1, val); }
-
- IR_LEAF_ISA(InterfaceRequirementEntry);
};
+FIDDLE()
struct IRInterfaceType : IRType
{
- IR_LEAF_ISA(InterfaceType)
+ FIDDLE(leafInst())
UInt getRequirementCount() { return getOperandCount(); }
};
+FIDDLE()
struct IRConjunctionType : IRType
{
- IR_LEAF_ISA(ConjunctionType)
+ FIDDLE(leafInst())
Int getCaseCount() { return getOperandCount(); }
IRType* getCaseType(Int index) { return (IRType*)getOperand(index); }
};
+FIDDLE()
struct IRAttributedType : IRType
{
- IR_LEAF_ISA(AttributedType)
+ FIDDLE(leafInst())
IRType* getBaseType() { return (IRType*)getOperand(0); }
IRInst* getAttr() { return getOperand(1); }
};
+FIDDLE()
struct IRTupleTypeBase : IRType
{
- IR_PARENT_ISA(TupleTypeBase)
+ FIDDLE(baseInst())
};
/// Represents a tuple. Tuples are created by `IRMakeTuple` and its elements
/// are accessed via `GetTupleElement(tupleValue, IRIntLit)`.
+FIDDLE()
struct IRTupleType : IRTupleTypeBase
{
- IR_LEAF_ISA(TupleType)
+ FIDDLE(leafInst())
};
/// Represents a type pack. Type packs behave like tuples, but they have a
/// "flattening" semantics, so that MakeTypePack(MakeTypePack(T1,T2), T3) is
/// MakeTypePack(T1,T2,T3).
+FIDDLE()
struct IRTypePack : IRTupleTypeBase
{
- IR_LEAF_ISA(TypePack)
+ FIDDLE(leafInst())
};
// A placeholder struct key for tuple type layouts that will be replaced with
// the actual struct key when the tuple type is materialized into a struct type.
+FIDDLE()
struct IRIndexedFieldKey : IRInst
{
- IR_LEAF_ISA(IndexedFieldKey)
+ FIDDLE(leafInst())
IRInst* getBaseType() { return getOperand(0); }
IRInst* getIndex() { return getOperand(1); }
};
/// Represents a tuple in target language. TargetTupleType will not be lowered to structs.
+FIDDLE()
struct IRTargetTupleType : IRType
{
- IR_LEAF_ISA(TargetTupleType)
+ FIDDLE(leafInst())
};
/// Represents a `expand T` type used in variadic generic decls in Slang. Expected to be substituted
/// by actual types during specialization.
-struct IRExpandType : IRType
+FIDDLE()
+struct IRExpandTypeOrVal : IRType
{
- IR_LEAF_ISA(ExpandTypeOrVal)
+ FIDDLE(leafInst())
IRType* getPatternType() { return (IRType*)(getOperand(0)); }
UInt getCaptureCount() { return getOperandCount() - 1; }
IRType* getCaptureType(UInt index) { return (IRType*)(getOperand(index + 1)); }
};
/// Represents an `Result<T,E>`, used by functions that throws error codes.
+FIDDLE()
struct IRResultType : IRType
{
- IR_LEAF_ISA(ResultType)
+ FIDDLE(leafInst())
IRType* getValueType() { return (IRType*)getOperand(0); }
IRType* getErrorType() { return (IRType*)getOperand(1); }
};
/// Represents an `Optional<T>`.
+FIDDLE()
struct IROptionalType : IRType
{
- IR_LEAF_ISA(OptionalType)
+ FIDDLE(leafInst())
IRType* getValueType() { return (IRType*)getOperand(0); }
};
/// Represents an enum type
+FIDDLE()
struct IREnumType : IRType
{
- IR_LEAF_ISA(EnumType)
+ FIDDLE(leafInst())
IRType* getTagType() { return (IRType*)getOperand(0); }
};
+FIDDLE()
struct IRTypeType : IRType
{
- IR_LEAF_ISA(TypeType);
+ FIDDLE(leafInst())
};
/// Represents the IR type for an `IRRTTIObject`.
+FIDDLE()
struct IRRTTIType : IRType
{
- IR_LEAF_ISA(RTTIType);
+ FIDDLE(leafInst())
};
/// Represents a handle to an RTTI object.
/// This is lowered as an integer number identifying a type.
+FIDDLE()
struct IRRTTIHandleType : IRType
{
- IR_LEAF_ISA(RTTIHandleType);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRAnyValueType : IRType
{
- IR_LEAF_ISA(AnyValueType);
+ FIDDLE(leafInst())
IRInst* getSize() { return getOperand(0); }
};
+FIDDLE()
struct IRWitnessTableTypeBase : IRType
{
+ FIDDLE(baseInst())
IRInst* getConformanceType() { return getOperand(0); }
- IR_PARENT_ISA(WitnessTableTypeBase);
};
+FIDDLE()
struct IRWitnessTableType : IRWitnessTableTypeBase
{
- IR_LEAF_ISA(WitnessTableType);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRWitnessTableIDType : IRWitnessTableTypeBase
{
- IR_LEAF_ISA(WitnessTableIDType);
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRBindExistentialsTypeBase : IRType
{
- IR_PARENT_ISA(BindExistentialsTypeBase)
+ FIDDLE(baseInst())
IRType* getBaseType() { return (IRType*)getOperand(0); }
UInt getExistentialArgCount() { return getOperandCount() - 1; }
@@ -2136,14 +2102,16 @@ struct IRBindExistentialsTypeBase : IRType
IRInst* getExistentialArg(UInt index) { return getExistentialArgs()[index].get(); }
};
+FIDDLE()
struct IRBindExistentialsType : IRBindExistentialsTypeBase
{
- IR_LEAF_ISA(BindExistentialsType)
+ FIDDLE(leafInst())
};
+FIDDLE()
struct IRBoundInterfaceType : IRBindExistentialsTypeBase
{
- IR_LEAF_ISA(BoundInterfaceType)
+ FIDDLE(leafInst())
IRType* getInterfaceType() { return getBaseType(); }
IRType* getConcreteType() { return (IRType*)getExistentialArg(0); }
@@ -2153,20 +2121,22 @@ struct IRBoundInterfaceType : IRBindExistentialsTypeBase
/// @brief A global value that potentially holds executable code.
///
+FIDDLE()
struct IRGlobalValueWithCode : IRInst
{
+ FIDDLE(baseInst())
// The children of a value with code will be the basic
// blocks of its definition.
IRBlock* getFirstBlock() { return cast<IRBlock>(getFirstChild()); }
IRBlock* getLastBlock() { return cast<IRBlock>(getLastChild()); }
IRInstList<IRBlock> getBlocks() { return IRInstList<IRBlock>(getChildren()); }
-
- IR_PARENT_ISA(GlobalValueWithCode)
};
// A value that has parameters so that it can conceptually be called.
+FIDDLE()
struct IRGlobalValueWithParams : IRGlobalValueWithCode
{
+ FIDDLE(baseInst())
// Convenience accessor for the IR parameters,
// which are actually the parameters of the first
// block.
@@ -2174,16 +2144,16 @@ struct IRGlobalValueWithParams : IRGlobalValueWithCode
IRParam* getLastParam();
IRInstList<IRParam> getParams();
IRInst* getFirstOrdinaryInst();
-
- IR_PARENT_ISA(GlobalValueWithParams)
};
// A function is a parent to zero or more blocks of instructions.
//
// A function is itself a value, so that it can be a direct operand of
// an instruction (e.g., a call).
+FIDDLE()
struct IRFunc : IRGlobalValueWithParams
{
+ FIDDLE(leafInst())
// The type of the IR-level function
IRFuncType* getDataType() { return (IRFuncType*)IRInst::getDataType(); }
@@ -2194,8 +2164,6 @@ struct IRFunc : IRGlobalValueWithParams
IRType* getParamType(UInt index);
bool isDefinition() { return getFirstBlock() != nullptr; }
-
- IR_LEAF_ISA(Func)
};
/// Adjust the type of an IR function based on its parameter list.
@@ -2218,9 +2186,10 @@ void fixUpFuncType(IRFunc* func);
//
// In practice, a generic always holds only a single block, and ends
// with a `return` instruction for the value that the generic yields.
+FIDDLE()
struct IRGeneric : IRGlobalValueWithParams
{
- IR_LEAF_ISA(Generic)
+ FIDDLE(leafInst())
};
// Find the value that is returned from a generic, so that
@@ -2255,16 +2224,16 @@ IRInst* getResolvedInstForDecorations(IRInst* inst, bool resolveThroughDifferent
// The IR module itself is represented as an instruction, which
// serves at the root of the tree of all instructions in the module.
+FIDDLE()
struct IRModuleInst : IRInst
{
+ FIDDLE(leafInst())
// Pointer back to the non-instruction object that represents
// the module, so that we can get back to it in algorithms
// that need it.
IRModule* module;
IRInstListBase getGlobalInsts() { return getChildren(); }
-
- IR_LEAF_ISA(Module)
};
struct IRModule;
@@ -2603,9 +2572,10 @@ struct InstHashSet
};
+FIDDLE()
struct IRSpecializationDictionaryItem : public IRInst
{
- IR_LEAF_ISA(SpecializationDictionaryItem)
+ FIDDLE(leafInst())
};
struct IRDumpOptions
@@ -2832,5 +2802,3 @@ R* composeGetters(T* t)
}
} // namespace Slang
-
-#endif
diff --git a/source/slang/slang-ir.h.lua b/source/slang/slang-ir.h.lua
new file mode 100644
index 000000000..8455ce652
--- /dev/null
+++ b/source/slang/slang-ir.h.lua
@@ -0,0 +1,202 @@
+--
+-- This file contains most of the code generation logic for the ir instructions
+--
+
+-- Helper function
+-- Walk the instruction tree and call a callback for each instruction
+local function walk_instructions(insts, callback, parent_struct)
+ local function walk_insts(tbl, parent)
+ for _, i in ipairs(tbl) do
+ local key, value = next(i)
+ -- Determine struct name
+ local struct_name = value.struct_name and value.struct_name or key
+
+ -- Call the callback
+ callback(key, value, struct_name, parent)
+
+ -- Recursively process nested instructions
+ walk_insts(value, struct_name)
+ end
+ end
+
+ -- Start walking from the top-level insts
+ if insts then
+ walk_insts(insts, "Inst")
+ end
+end
+
+-- The definitions for leaf instructions
+local leafInst = function(name, args)
+ args = args or {}
+ return args.noIsaImpl and ""
+ or [[static bool isaImpl(IROp op)
+ {
+ return (kIROpMask_OpMask & op) == kIROp_]]
+ .. name
+ .. [[;
+ }
+ enum { kOp = kIROp_]]
+ .. name
+ .. [[ }; ]]
+end
+
+-- The definitions for abstract instruction classes
+local baseInst = function(name, args)
+ args = args or {}
+ return args.noIsaImpl and ""
+ or [[static bool isaImpl(IROp opIn)
+ {
+ const int op = (kIROpMask_OpMask & opIn);
+ return op >= kIROp_First]]
+ .. name
+ .. [[ && op <= kIROp_Last]]
+ .. name
+ .. [[;
+ }]]
+end
+
+-- Generate struct definitions for instructions not defined by the user
+local function allOtherInstStructs()
+ local insts = require("source/slang/slang-ir-insts.lua").insts
+ local output = {}
+
+ walk_instructions(insts, function(key, value, struct_name, parent_struct)
+ -- If this type already has a definition, skip it
+ if not Slang["IR" .. struct_name] then
+ -- Generate struct definition
+ table.insert(output, string.format("struct IR%s : IR%s", struct_name, parent_struct))
+ table.insert(output, "{")
+ table.insert(
+ output,
+ string.format(" %s", value.is_leaf and leafInst(struct_name) or baseInst(struct_name))
+ )
+ table.insert(output, "};")
+ table.insert(output, "")
+ end
+ end)
+
+ return table.concat(output, "\n")
+end
+
+-- Forward declarations for everything
+local function instStructForwardDecls()
+ local insts = require("source/slang/slang-ir-insts.lua").insts
+ local output = {}
+
+ walk_instructions(insts, function(key, value, struct_name, parent_struct)
+ -- Generate struct definition
+ table.insert(output, string.format("struct IR%s;", struct_name))
+ end)
+
+ return table.concat(output, "\n")
+end
+
+-- The info table
+local function instInfoEntries()
+ local insts = require("source/slang/slang-ir-insts.lua").insts
+ local output = {}
+
+ local function constructFlags(value)
+ local flags = {}
+
+ -- Map of field names to their IROpFlags names
+ local flagMap = {
+ hoistable = "kIROpFlag_Hoistable",
+ parent = "kIROpFlag_Parent",
+ global = "kIROpFlag_Global",
+ use_other = "kIROpFlag_UseOther",
+ }
+
+ -- Check each flag and add to the list if true
+ for field, flagName in pairs(flagMap) do
+ if value[field] then
+ table.insert(flags, flagName)
+ end
+ end
+
+ -- Join all flags with " | "
+ if #flags > 0 then
+ return table.concat(flags, " | ")
+ else
+ return "kIROpFlags_None" -- or return "" if you prefer empty string
+ end
+ end
+
+ walk_instructions(insts, function(key, value, struct_name, parent_struct)
+ if value.is_leaf then
+ RAW(
+ "{kIROp_"
+ .. struct_name
+ .. ', {"'
+ .. value.mnemonic
+ .. '", '
+ .. tostring(value.min_operands)
+ .. ", "
+ .. constructFlags(value)
+ .. "}},"
+ )
+ end
+ end)
+end
+
+-- The enum table
+local function instEnums()
+ local insts = require("source/slang/slang-ir-insts.lua").insts
+ local output = {}
+
+ -- Walk manually so we can output in postorder
+ local function traverse(tbl)
+ local first_child = nil
+ local last_child = nil
+
+ -- First, process all children
+ for _, i in ipairs(tbl) do
+ local key, value = next(i)
+ if value.is_leaf then
+ -- Leaf instruction
+ RAW(" kIROp_" .. value.struct_name .. ",")
+
+ -- Track first and last child
+ if first_child == nil then
+ first_child = "kIROp_" .. value.struct_name
+ end
+ last_child = "kIROp_" .. value.struct_name
+ else
+ -- Parent instruction - recurse first
+ local child_first, child_last = traverse(value)
+
+ -- Track first and last child across all children
+ if first_child == nil then
+ first_child = child_first
+ end
+ if child_last then
+ last_child = child_last
+ end
+
+ -- Then add parent entries
+ if child_first and child_last then
+ RAW(" kIROp_First" .. value.struct_name .. " = " .. child_first .. ",")
+ RAW(" kIROp_Last" .. value.struct_name .. " = " .. child_last .. ",")
+ end
+ end
+ end
+
+ return first_child, last_child
+ end
+
+ traverse(insts)
+ return table.concat(output, "\n")
+end
+
+return {
+ leafInst = function(args)
+ return leafInst(tostring(fiddle.current_decl):gsub("^IR", ""), args)
+ end,
+ baseInst = function(args)
+ return baseInst(tostring(fiddle.current_decl):gsub("^IR", ""), args)
+ end,
+ allOtherInstStructs = allOtherInstStructs,
+ instStructForwardDecls = instStructForwardDecls,
+ instInfoEntries = instInfoEntries,
+ instEnums = instEnums,
+}
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index 42a71764c..ed4336ff9 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -1779,7 +1779,7 @@ struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower
auto supType = lowerType(context, witness->getSup());
auto witnessTableType = irBuilder->getWitnessTableType(supType);
ShortList<IRInst*> captures;
- if (auto expandType = as<IRExpandType>(subType))
+ if (auto expandType = as<IRExpandTypeOrVal>(subType))
{
for (UInt i = 0; i < expandType->getCaptureCount(); i++)
{
@@ -4753,7 +4753,7 @@ struct ExprLoweringVisitorBase : public ExprVisitor<Derived, LoweredValInfo>
auto irBuilder = getBuilder();
auto irType = lowerType(context, expr->type);
List<IRInst*> irCapturedPacks;
- if (auto expandType = as<IRExpandType>(irType))
+ if (auto expandType = as<IRExpandTypeOrVal>(irType))
{
for (UInt i = 0; i < expandType->getCaptureCount(); i++)
{
@@ -8270,10 +8270,10 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
void ensureInsertAtGlobalScope(IRBuilder* builder)
{
auto inst = builder->getInsertLoc().getInst();
- if (inst->getOp() == kIROp_Module)
+ if (inst->getOp() == kIROp_ModuleInst)
return;
- while (inst && inst->getParent() && inst->getParent()->getOp() != kIROp_Module)
+ while (inst && inst->getParent() && inst->getParent()->getOp() != kIROp_ModuleInst)
{
inst = inst->getParent();
}
@@ -11312,7 +11312,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
debugType);
// Add a decoration to link the function to its debug function
- getBuilder()->addDecoration(irFunc, kIROp_DebugFunctionDecoration, debugFuncCallee);
+ getBuilder()->addDecoration(irFunc, kIROp_DebugFuncDecoration, debugFuncCallee);
}
}
diff --git a/source/slang/slang-serialize-ir.cpp b/source/slang/slang-serialize-ir.cpp
index 662f8acf1..093643d09 100644
--- a/source/slang/slang-serialize-ir.cpp
+++ b/source/slang/slang-serialize-ir.cpp
@@ -530,7 +530,7 @@ Result IRSerialReader::read(
{
// Check that insts[1] is the module inst
const Ser::Inst& srcInst = data.m_insts[1];
- SLANG_RELEASE_ASSERT(srcInst.m_op == kIROp_Module);
+ SLANG_RELEASE_ASSERT(srcInst.m_op == kIROp_ModuleInst);
SLANG_ASSERT(srcInst.m_payloadType == PayloadType::Empty);
// The root IR instruction for the module will already have