summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2023-12-15 17:05:32 -0800
committerGitHub <noreply@github.com>2023-12-15 17:05:32 -0800
commitb507d881ca47135bfa46237767e7183f61e7d8e3 (patch)
tree3bbe4652a6972d940fd4df92a113b760c3a9e115 /source/slang
parentf8b3027d0be0b890152a6a649822741cd3a3b6b6 (diff)
Add ConstBufferPointer::subscript. (#3415)
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/core.meta.slang12
-rw-r--r--source/slang/hlsl.meta.slang40
-rw-r--r--source/slang/slang-ast-dump.cpp3
-rw-r--r--source/slang/slang-ast-expr.h1
-rw-r--r--source/slang/slang-check-expr.cpp1
-rw-r--r--source/slang/slang-emit.cpp20
-rw-r--r--source/slang/slang-ir-autodiff-fwd.cpp2
-rw-r--r--source/slang/slang-ir-autodiff.cpp11
-rw-r--r--source/slang/slang-ir-autodiff.h7
-rw-r--r--source/slang/slang-ir-check-differentiability.cpp2
-rw-r--r--source/slang/slang-ir-inline.cpp2
-rw-r--r--source/slang/slang-ir-inst-defs.h2
-rw-r--r--source/slang/slang-ir-loop-unroll.cpp15
-rw-r--r--source/slang/slang-ir-loop-unroll.h5
-rw-r--r--source/slang/slang-ir-lower-generics.cpp2
-rw-r--r--source/slang/slang-ir-peephole.cpp42
-rw-r--r--source/slang/slang-ir-peephole.h9
-rw-r--r--source/slang/slang-ir-specialize-function-call.cpp2
-rw-r--r--source/slang/slang-ir-specialize-resources.cpp4
-rw-r--r--source/slang/slang-ir-specialize.cpp11
-rw-r--r--source/slang/slang-ir-specialize.h2
-rw-r--r--source/slang/slang-ir-spirv-legalize.cpp8
-rw-r--r--source/slang/slang-ir-ssa-simplification.cpp14
-rw-r--r--source/slang/slang-ir-ssa-simplification.h7
-rw-r--r--source/slang/slang-lower-to-ir.cpp14
-rw-r--r--source/slang/slang-parser.cpp7
26 files changed, 183 insertions, 62 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index bc214ceff..3df11fffe 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -2294,6 +2294,18 @@ bool __isVector()
return __isVector_impl(__declVal<T>());
}
+__generic<T>
+__intrinsic_op($(kIROp_GetNaturalStride))
+int __naturalStrideOf_impl(T v);
+
+__generic<T>
+[__unsafeForceInlineEarly]
+int __naturalStrideOf()
+{
+ return __naturalStrideOf_impl(__declVal<T>());
+}
+
+
// Binding Attributes
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 39ed13488..945dfa862 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -12555,7 +12555,45 @@ struct ConstBufferPointer
__intrinsic_asm "$0._data";
case spirv:
return spirv_asm {
- result:$$T = OpLoad $this Aligned $Alignment;
+ result:$$T = OpLoad $this Aligned !Alignment;
+ };
+ }
+ }
+
+ __subscript(int index) -> T
+ {
+ [ForceInline]
+ get {return ConstBufferPointer<T>.fromUInt(toUInt() + __naturalStrideOf<T>() * index).get(); }
+ }
+
+ __glsl_version(450)
+ __glsl_extension(GL_EXT_shader_explicit_arithmetic_types_int64)
+ __glsl_extension(GL_EXT_buffer_reference)
+ static ConstBufferPointer<T> fromUInt(uint64_t val)
+ {
+ __target_switch
+ {
+ case glsl:
+ __intrinsic_asm "$TR($0)";
+ case spirv:
+ return spirv_asm {
+ result:$$ConstBufferPointer<T> = OpConvertUToPtr $val;
+ };
+ }
+ }
+
+ __glsl_version(450)
+ __glsl_extension(GL_EXT_shader_explicit_arithmetic_types_int64)
+ __glsl_extension(GL_EXT_buffer_reference)
+ uint64_t toUInt()
+ {
+ __target_switch
+ {
+ case glsl:
+ __intrinsic_asm "uint64_t($0)";
+ case spirv:
+ return spirv_asm {
+ result:$$uint64_t = OpConvertPtrToU $this;
};
}
}
diff --git a/source/slang/slang-ast-dump.cpp b/source/slang/slang-ast-dump.cpp
index e05f0a455..cde7c6201 100644
--- a/source/slang/slang-ast-dump.cpp
+++ b/source/slang/slang-ast-dump.cpp
@@ -659,6 +659,9 @@ struct ASTDumpContext
case SPIRVAsmOperand::SlangType:
m_writer->emit("$$");
break;
+ case SPIRVAsmOperand::SlangImmediateValue:
+ m_writer->emit("!");
+ break;
default:
SLANG_UNREACHABLE("Unhandled case in ast dump for SPIRVAsmOperand");
}
diff --git a/source/slang/slang-ast-expr.h b/source/slang/slang-ast-expr.h
index 23c721038..9f2cd22a9 100644
--- a/source/slang/slang-ast-expr.h
+++ b/source/slang/slang-ast-expr.h
@@ -658,6 +658,7 @@ public:
NamedValue, // Any other identifier
SlangValue,
SlangValueAddr,
+ SlangImmediateValue,
SlangType,
SampledType, // __sampledType(T), this becomes a 4 vector of the component type of T
ImageType, // __imageType(texture), returns the equivalaent OpTypeImage of a given texture typed value.
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp
index 3aaeade74..e5e990fe5 100644
--- a/source/slang/slang-check-expr.cpp
+++ b/source/slang/slang-check-expr.cpp
@@ -4262,6 +4262,7 @@ namespace Slang
operand.expr = typeExpr.exp;
}
else if(operand.flavor == SPIRVAsmOperand::SlangValue
+ || operand.flavor == SPIRVAsmOperand::SlangImmediateValue
|| operand.flavor == SPIRVAsmOperand::SlangValueAddr
|| operand.flavor == SPIRVAsmOperand::ImageType
|| operand.flavor == SPIRVAsmOperand::SampledImageType)
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index 306ad9abd..4edf45759 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -367,7 +367,7 @@ Result linkAndOptimizeIR(
// Lower all the LValue implict casts (used for out/inout/ref scenarios)
lowerLValueCast(targetRequest, irModule);
- simplifyIR(irModule, IRSimplificationOptions::getDefault(), sink);
+ simplifyIR(targetRequest, irModule, IRSimplificationOptions::getDefault(), sink);
// Fill in default matrix layout into matrix types that left layout unspecified.
specializeMatrixLayout(codeGenContext->getTargetReq(), irModule);
@@ -407,7 +407,7 @@ Result linkAndOptimizeIR(
//auto b1 = dumpIRToString(irModule->getModuleInst());
dumpIRIfEnabled(codeGenContext, irModule, "BEFORE-SPECIALIZE");
if (!codeGenContext->isSpecializationDisabled())
- changed |= specializeModule(irModule, codeGenContext->getSink());
+ changed |= specializeModule(codeGenContext->getTargetReq(), irModule, codeGenContext->getSink());
if (codeGenContext->getSink()->getErrorCount() != 0)
return SLANG_FAIL;
dumpIRIfEnabled(codeGenContext, irModule, "AFTER-SPECIALIZE");
@@ -425,7 +425,7 @@ Result linkAndOptimizeIR(
// Unroll loops.
if (codeGenContext->getSink()->getErrorCount() == 0)
{
- if (!unrollLoopsInModule(irModule, codeGenContext->getSink()))
+ if (!unrollLoopsInModule(targetRequest, irModule, codeGenContext->getSink()))
return SLANG_FAIL;
}
@@ -438,7 +438,7 @@ Result linkAndOptimizeIR(
dumpIRIfEnabled(codeGenContext, irModule, "BEFORE-AUTODIFF");
enableIRValidationAtInsert();
- changed |= processAutodiffCalls(irModule, sink);
+ changed |= processAutodiffCalls(targetRequest, irModule, sink);
disableIRValidationAtInsert();
dumpIRIfEnabled(codeGenContext, irModule, "AFTER-AUTODIFF");
@@ -446,7 +446,7 @@ Result linkAndOptimizeIR(
break;
}
- finalizeAutoDiffPass(irModule);
+ finalizeAutoDiffPass(targetRequest, irModule);
finalizeSpecialization(irModule);
@@ -481,7 +481,7 @@ Result linkAndOptimizeIR(
validateIRModuleIfEnabled(codeGenContext, irModule);
- simplifyIR(irModule, IRSimplificationOptions::getFast(), sink);
+ simplifyIR(targetRequest, irModule, IRSimplificationOptions::getFast(), sink);
if (!ArtifactDescUtil::isCpuLikeTarget(artifactDesc))
{
@@ -510,7 +510,7 @@ Result linkAndOptimizeIR(
// up downstream passes like type legalization, so we
// will run a DCE pass to clean up after the specialization.
//
- simplifyIR(irModule, IRSimplificationOptions::getDefault(), sink);
+ simplifyIR(targetRequest, irModule, IRSimplificationOptions::getDefault(), sink);
validateIRModuleIfEnabled(codeGenContext, irModule);
@@ -596,7 +596,7 @@ Result linkAndOptimizeIR(
// to see if we can clean up any temporaries created by legalization.
// (e.g., things that used to be aggregated might now be split up,
// so that we can work with the individual fields).
- simplifyIR(irModule, IRSimplificationOptions::getFast(), sink);
+ simplifyIR(targetRequest, irModule, IRSimplificationOptions::getFast(), sink);
#if 0
dumpIRIfEnabled(codeGenContext, irModule, "AFTER SSA");
@@ -940,7 +940,7 @@ Result linkAndOptimizeIR(
{
IRSimplificationOptions simplificationOptions = IRSimplificationOptions::getFast();
simplificationOptions.cfgOptions.removeTrivialSingleIterationLoops = true;
- simplifyIR(irModule, simplificationOptions, sink);
+ simplifyIR(targetRequest, irModule, simplificationOptions, sink);
}
// As a late step, we need to take the SSA-form IR and move things *out*
@@ -1018,7 +1018,7 @@ Result linkAndOptimizeIR(
}
// Run a final round of simplifications to clean up unused things after phi-elimination.
- simplifyNonSSAIR(irModule, IRSimplificationOptions::getFast());
+ simplifyNonSSAIR(targetRequest, irModule, IRSimplificationOptions::getFast());
// We include one final step to (optionally) dump the IR and validate
// it after all of the optimization passes are complete. This should
diff --git a/source/slang/slang-ir-autodiff-fwd.cpp b/source/slang/slang-ir-autodiff-fwd.cpp
index 213b53df0..9d13dafae 100644
--- a/source/slang/slang-ir-autodiff-fwd.cpp
+++ b/source/slang/slang-ir-autodiff-fwd.cpp
@@ -1642,7 +1642,7 @@ SlangResult ForwardDiffTranscriber::prepareFuncForForwardDiff(IRFunc* func)
if (SLANG_SUCCEEDED(result))
{
disableIRValidationAtInsert();
- simplifyFunc(func, IRSimplificationOptions::getDefault());
+ simplifyFunc(autoDiffSharedContext->targetRequest, func, IRSimplificationOptions::getDefault());
enableIRValidationAtInsert();
}
return result;
diff --git a/source/slang/slang-ir-autodiff.cpp b/source/slang/slang-ir-autodiff.cpp
index 9166c560a..9acb6756e 100644
--- a/source/slang/slang-ir-autodiff.cpp
+++ b/source/slang/slang-ir-autodiff.cpp
@@ -339,8 +339,8 @@ IRInst* DifferentialPairTypeBuilder::lowerDiffPairType(
return result;
}
-AutoDiffSharedContext::AutoDiffSharedContext(IRModuleInst* inModuleInst)
- : moduleInst(inModuleInst)
+AutoDiffSharedContext::AutoDiffSharedContext(TargetRequest* target, IRModuleInst* inModuleInst)
+ : moduleInst(inModuleInst), targetRequest(target)
{
differentiableInterfaceType = as<IRInterfaceType>(findDifferentiableInterface());
if (differentiableInterfaceType)
@@ -1979,6 +1979,7 @@ protected:
};
bool processAutodiffCalls(
+ TargetRequest* target,
IRModule* module,
DiagnosticSink* sink,
IRAutodiffPassOptions const&)
@@ -1987,7 +1988,7 @@ bool processAutodiffCalls(
bool modified = false;
// Create shared context for all auto-diff related passes
- AutoDiffSharedContext autodiffContext(module->getModuleInst());
+ AutoDiffSharedContext autodiffContext(target, module->getModuleInst());
AutoDiffPass pass(&autodiffContext, sink);
@@ -2077,12 +2078,12 @@ void releaseNullDifferentialType(AutoDiffSharedContext* context)
}
}
-bool finalizeAutoDiffPass(IRModule* module)
+bool finalizeAutoDiffPass(TargetRequest* target, IRModule* module)
{
bool modified = false;
// Create shared context for all auto-diff related passes
- AutoDiffSharedContext autodiffContext(module->getModuleInst());
+ AutoDiffSharedContext autodiffContext(target, module->getModuleInst());
// Replaces IRDifferentialPairType with an auto-generated struct,
// IRDifferentialPairGetDifferential with 'differential' field access,
diff --git a/source/slang/slang-ir-autodiff.h b/source/slang/slang-ir-autodiff.h
index be51fba6f..0f688c84f 100644
--- a/source/slang/slang-ir-autodiff.h
+++ b/source/slang/slang-ir-autodiff.h
@@ -59,6 +59,8 @@ struct DiffTranscriberSet
struct AutoDiffSharedContext
{
+ TargetRequest* targetRequest = nullptr;
+
IRModuleInst* moduleInst = nullptr;
// A reference to the builtin IDifferentiable interface type.
@@ -113,7 +115,7 @@ struct AutoDiffSharedContext
DiffTranscriberSet transcriberSet;
- AutoDiffSharedContext(IRModuleInst* inModuleInst);
+ AutoDiffSharedContext(TargetRequest* target, IRModuleInst* inModuleInst);
private:
@@ -357,11 +359,12 @@ struct IRAutodiffPassOptions
};
bool processAutodiffCalls(
+ TargetRequest* target,
IRModule* module,
DiagnosticSink* sink,
IRAutodiffPassOptions const& options = IRAutodiffPassOptions());
-bool finalizeAutoDiffPass(IRModule* module);
+bool finalizeAutoDiffPass(TargetRequest* target, IRModule* module);
// Utility methods
diff --git a/source/slang/slang-ir-check-differentiability.cpp b/source/slang/slang-ir-check-differentiability.cpp
index ddb70d779..c5c03f7da 100644
--- a/source/slang/slang-ir-check-differentiability.cpp
+++ b/source/slang/slang-ir-check-differentiability.cpp
@@ -19,7 +19,7 @@ public:
Dictionary<IRInst*, DifferentiableLevel> differentiableFunctions;
CheckDifferentiabilityPassContext(IRModule* inModule, DiagnosticSink* inSink)
- : InstPassBase(inModule), sink(inSink), sharedContext(inModule->getModuleInst())
+ : InstPassBase(inModule), sink(inSink), sharedContext(nullptr, inModule->getModuleInst())
{}
bool _isFuncMarkedForAutoDiff(IRInst* func)
diff --git a/source/slang/slang-ir-inline.cpp b/source/slang/slang-ir-inline.cpp
index 01dfdc42d..eea47533d 100644
--- a/source/slang/slang-ir-inline.cpp
+++ b/source/slang/slang-ir-inline.cpp
@@ -944,7 +944,7 @@ void performGLSLResourceReturnFunctionInlining(IRModule* module)
while (changed)
{
changed = pass.considerAllCallSites();
- simplifyIR(module, IRSimplificationOptions::getFast());
+ simplifyIR(nullptr, module, IRSimplificationOptions::getFast());
}
}
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index 0abfdc694..99f73b025 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -464,6 +464,8 @@ INST(StructuredBufferGetDimensions, StructuredBufferGetDimensions, 1, 0)
INST(AtomicCounterIncrement, AtomicCounterIncrement, 1, 0)
INST(AtomicCounterDecrement, AtomicCounterDecrement, 1, 0)
+INST(GetNaturalStride, getNaturalStride, 1, 0)
+
INST(MeshOutputRef, meshOutputRef, 2, 0)
// Construct a vector from a scalar
diff --git a/source/slang/slang-ir-loop-unroll.cpp b/source/slang/slang-ir-loop-unroll.cpp
index 31715e7b1..d998f5e61 100644
--- a/source/slang/slang-ir-loop-unroll.cpp
+++ b/source/slang/slang-ir-loop-unroll.cpp
@@ -67,6 +67,7 @@ static int _getLoopMaxIterationsToUnroll(IRLoop* loopInst)
}
static void _foldAndSimplifyLoopIteration(
+ TargetRequest* targetRequest,
IRBuilder& builder,
List<IRBlock*>& clonedBlocks,
IRBlock* firstIterationBreakBlock,
@@ -80,7 +81,7 @@ static void _foldAndSimplifyLoopIteration(
{
for (auto inst : b->getChildren())
{
- tryReplaceInstUsesWithSimplifiedValue(builder.getModule(), inst);
+ tryReplaceInstUsesWithSimplifiedValue(targetRequest, builder.getModule(), inst);
}
}
@@ -88,7 +89,7 @@ static void _foldAndSimplifyLoopIteration(
// the phi arguments for next iteration evaluated (args in the new loop inst).
for (auto inst : firstIterationBreakBlock->getChildren())
{
- tryReplaceInstUsesWithSimplifiedValue(builder.getModule(), inst);
+ tryReplaceInstUsesWithSimplifiedValue(targetRequest, builder.getModule(), inst);
}
// Fold conditional branches into unconditional branches if the condition is known.
@@ -147,6 +148,7 @@ static void _foldAndSimplifyLoopIteration(
// Returns true if we can statically determine that the loop terminated within the iteration limit.
// This operation assumes the loop does not have `continue` jumps, i.e. continueBlock == targetBlock.
static bool _unrollLoop(
+ TargetRequest* targetRequest,
IRModule* module,
IRLoop* loopInst,
List<IRBlock*>& blocks)
@@ -339,7 +341,7 @@ static bool _unrollLoop(
// conditional jumps can be folded into unconditional jumps.
_foldAndSimplifyLoopIteration(
- builder, clonedBlocks, firstIterationBreakBlock, unreachableBlock);
+ targetRequest, builder, clonedBlocks, firstIterationBreakBlock, unreachableBlock);
// Now we have peeled off one iteration from the loop, we check if there are any
// branches into next iteration, if not, the loop terminates and we are done.
@@ -433,6 +435,7 @@ List<IRLoop*> collectLoopsInFunc(IRGlobalValueWithCode* func, const TFunc& filte
}
bool unrollLoopsInFunc(
+ TargetRequest* targetRequest,
IRModule* module,
IRGlobalValueWithCode* func,
DiagnosticSink* sink)
@@ -450,7 +453,7 @@ bool unrollLoopsInFunc(
auto blocks = collectBlocksInRegion(func, loop);
auto loopLoc = loop->sourceLoc;
- if (!_unrollLoop(module, loop, blocks))
+ if (!_unrollLoop(targetRequest, module, loop, blocks))
{
if (sink)
sink->diagnose(loopLoc, Diagnostics::cannotUnrollLoop);
@@ -465,7 +468,7 @@ bool unrollLoopsInFunc(
return true;
}
-bool unrollLoopsInModule(IRModule* module, DiagnosticSink* sink)
+bool unrollLoopsInModule(TargetRequest* targetRequest, IRModule* module, DiagnosticSink* sink)
{
SLANG_PROFILE;
@@ -476,7 +479,7 @@ bool unrollLoopsInModule(IRModule* module, DiagnosticSink* sink)
if (auto func = as<IRGlobalValueWithCode>(inst))
{
- bool result = unrollLoopsInFunc(module, func, sink);
+ bool result = unrollLoopsInFunc(targetRequest, module, func, sink);
if (!result)
return false;
}
diff --git a/source/slang/slang-ir-loop-unroll.h b/source/slang/slang-ir-loop-unroll.h
index 90d530556..3b42afe80 100644
--- a/source/slang/slang-ir-loop-unroll.h
+++ b/source/slang/slang-ir-loop-unroll.h
@@ -10,11 +10,12 @@ namespace Slang
class DiagnosticSink;
struct IRModule;
struct IRBlock;
+ class TargetRequest;
// Return true if successfull, false if errors occurred.
- bool unrollLoopsInFunc(IRModule* module, IRGlobalValueWithCode* func, DiagnosticSink* sink);
+ bool unrollLoopsInFunc(TargetRequest*target, IRModule* module, IRGlobalValueWithCode* func, DiagnosticSink* sink);
- bool unrollLoopsInModule(IRModule* module, DiagnosticSink* sink);
+ bool unrollLoopsInModule(TargetRequest* target, IRModule* module, DiagnosticSink* sink);
// Turn a loop with continue block into a loop with only back jumps and breaks.
// Each iteration will be wrapped in a breakable region, where everything before `continue`
diff --git a/source/slang/slang-ir-lower-generics.cpp b/source/slang/slang-ir-lower-generics.cpp
index 2002b42cc..f3aa2145e 100644
--- a/source/slang/slang-ir-lower-generics.cpp
+++ b/source/slang/slang-ir-lower-generics.cpp
@@ -255,7 +255,7 @@ namespace Slang
// real RTTI objects and witness tables.
specializeRTTIObjects(&sharedContext, sink);
- simplifyIR(module, IRSimplificationOptions::getFast());
+ simplifyIR(sharedContext.targetReq, module, IRSimplificationOptions::getFast());
lowerTuples(module, sink);
if (sink->getErrorCount() != 0)
diff --git a/source/slang/slang-ir-peephole.cpp b/source/slang/slang-ir-peephole.cpp
index 6cabbe8d4..22bcafdf4 100644
--- a/source/slang/slang-ir-peephole.cpp
+++ b/source/slang/slang-ir-peephole.cpp
@@ -3,6 +3,7 @@
#include "slang-ir-sccp.h"
#include "slang-ir-dominators.h"
#include "slang-ir-util.h"
+#include "slang-ir-layout.h"
namespace Slang
{
@@ -15,6 +16,9 @@ struct PeepholeContext : InstPassBase
bool changed = false;
FloatingPointMode floatingPointMode = FloatingPointMode::Precise;
bool removeOldInst = true;
+ bool isInGeneric = false;
+
+ TargetRequest* targetRequest;
void maybeRemoveOldInst(IRInst* inst)
{
@@ -959,6 +963,24 @@ struct PeepholeContext : InstPassBase
}
break;
}
+ case kIROp_GetNaturalStride:
+ {
+ if (targetRequest)
+ {
+ if (isInGeneric)
+ break;
+ auto type = inst->getOperand(0)->getDataType();
+ IRSizeAndAlignment sizeAlignment;
+ getNaturalSizeAndAlignment(targetRequest, type, &sizeAlignment);
+ IRBuilder builder(module);
+ builder.setInsertBefore(inst);
+ auto stride = builder.getIntValue(inst->getDataType(), sizeAlignment.getStride());
+ inst->replaceUsesWith(stride);
+ maybeRemoveOldInst(inst);
+ changed = true;
+ }
+ break;
+ }
case kIROp_IsInt:
case kIROp_IsFloat:
case kIROp_IsUnsignedInt:
@@ -1017,6 +1039,10 @@ struct PeepholeContext : InstPassBase
{
func->getModule()->invalidateAllAnalysis();
+ bool lastIsInGeneric = isInGeneric;
+ if (!isInGeneric)
+ isInGeneric = as<IRGeneric>(func) != nullptr;
+
bool result = false;
for (;;)
{
@@ -1027,6 +1053,9 @@ struct PeepholeContext : InstPassBase
else
break;
}
+
+ isInGeneric = lastIsInGeneric;
+
return result;
}
@@ -1036,21 +1065,25 @@ struct PeepholeContext : InstPassBase
}
};
-bool peepholeOptimize(IRModule* module)
+bool peepholeOptimize(TargetRequest* target, IRModule* module)
{
PeepholeContext context = PeepholeContext(module);
+ context.targetRequest = target;
return context.processModule();
}
-bool peepholeOptimize(IRInst* func)
+bool peepholeOptimize(TargetRequest* target, IRInst* func)
{
PeepholeContext context = PeepholeContext(func->getModule());
+ context.targetRequest = target;
return context.processFunc(func);
}
-bool peepholeOptimizeGlobalScope(IRModule* module)
+bool peepholeOptimizeGlobalScope(TargetRequest* target, IRModule* module)
{
PeepholeContext context = PeepholeContext(module);
+ context.targetRequest = target;
+
bool result = false;
for (;;)
{
@@ -1064,12 +1097,13 @@ bool peepholeOptimizeGlobalScope(IRModule* module)
return result;
}
-bool tryReplaceInstUsesWithSimplifiedValue(IRModule* module, IRInst* inst)
+bool tryReplaceInstUsesWithSimplifiedValue(TargetRequest* target, IRModule* module, IRInst* inst)
{
if (inst != tryConstantFoldInst(module, inst))
return true;
PeepholeContext context = PeepholeContext(inst->getModule());
+ context.targetRequest = target;
context.removeOldInst = false;
context.processInst(inst);
return context.changed;
diff --git a/source/slang/slang-ir-peephole.h b/source/slang/slang-ir-peephole.h
index b2ea1bc04..28edfbe78 100644
--- a/source/slang/slang-ir-peephole.h
+++ b/source/slang/slang-ir-peephole.h
@@ -6,10 +6,11 @@ namespace Slang
struct IRModule;
struct IRCall;
struct IRInst;
+ class TargetRequest;
/// Apply peephole optimizations.
- bool peepholeOptimize(IRModule* module);
- bool peepholeOptimize(IRInst* func);
- bool peepholeOptimizeGlobalScope(IRModule* module);
- bool tryReplaceInstUsesWithSimplifiedValue(IRModule* module, IRInst* inst);
+ bool peepholeOptimize(TargetRequest* target, IRModule* module);
+ bool peepholeOptimize(TargetRequest* target, IRInst* func);
+ bool peepholeOptimizeGlobalScope(TargetRequest* target, IRModule* module);
+ bool tryReplaceInstUsesWithSimplifiedValue(TargetRequest* target, IRModule* module, IRInst* inst);
}
diff --git a/source/slang/slang-ir-specialize-function-call.cpp b/source/slang/slang-ir-specialize-function-call.cpp
index 6aa2e4998..01cdf4cd9 100644
--- a/source/slang/slang-ir-specialize-function-call.cpp
+++ b/source/slang/slang-ir-specialize-function-call.cpp
@@ -891,7 +891,7 @@ struct FunctionParameterSpecializationContext
//
addCallsToWorkListRec(newFunc);
- simplifyFunc(newFunc, IRSimplificationOptions::getFast());
+ simplifyFunc(targetRequest, newFunc, IRSimplificationOptions::getFast());
return newFunc;
}
diff --git a/source/slang/slang-ir-specialize-resources.cpp b/source/slang/slang-ir-specialize-resources.cpp
index bb3d59bf2..cfab3fb13 100644
--- a/source/slang/slang-ir-specialize-resources.cpp
+++ b/source/slang/slang-ir-specialize-resources.cpp
@@ -1185,7 +1185,7 @@ bool specializeResourceUsage(
// and turned into SSA temporaries. Such optimization may enable
// the following passes to "see" and specialize more cases.
//
- simplifyIR(irModule, IRSimplificationOptions::getFast());
+ simplifyIR(codeGenContext->getTargetReq(), irModule, IRSimplificationOptions::getFast());
result |= changed;
}
if (unspecializableFuncs.getCount() == 0)
@@ -1205,7 +1205,7 @@ bool specializeResourceUsage(
inlineCall(call);
});
}
- simplifyIR(irModule, IRSimplificationOptions::getFast());
+ simplifyIR(codeGenContext->getTargetReq(), irModule, IRSimplificationOptions::getFast());
}
return result;
}
diff --git a/source/slang/slang-ir-specialize.cpp b/source/slang/slang-ir-specialize.cpp
index e1a563b04..3f75a8b32 100644
--- a/source/slang/slang-ir-specialize.cpp
+++ b/source/slang/slang-ir-specialize.cpp
@@ -47,15 +47,17 @@ struct SpecializationContext
// we are specializing.
IRModule* module;
DiagnosticSink* sink;
+ TargetRequest* targetRequest;
bool changed = false;
- SpecializationContext(IRModule* inModule)
+ SpecializationContext(IRModule* inModule, TargetRequest* target)
: workList(*inModule->getContainerPool().getList<IRInst>())
, workListSet(*inModule->getContainerPool().getHashSet<IRInst>())
, cleanInsts(*module->getContainerPool().getHashSet<IRInst>())
, module(inModule)
+ , targetRequest(target)
{
}
@@ -1511,7 +1513,7 @@ struct SpecializationContext
//
addToWorkList(newFunc);
- simplifyFunc(newFunc, IRSimplificationOptions::getFast());
+ simplifyFunc(targetRequest, newFunc, IRSimplificationOptions::getFast());
return newFunc;
}
@@ -2230,11 +2232,12 @@ struct SpecializationContext
};
bool specializeModule(
+ TargetRequest* target,
IRModule* module,
DiagnosticSink* sink)
{
SLANG_PROFILE;
- SpecializationContext context(module);
+ SpecializationContext context(module, target);
context.sink = sink;
context.processModule();
return context.changed;
@@ -2369,7 +2372,7 @@ IRInst* specializeGenericImpl(
// the same thing.
if (auto func = as<IRFunc>(specializedVal))
{
- simplifyFunc(func, IRSimplificationOptions::getFast());
+ simplifyFunc(context->targetRequest, func, IRSimplificationOptions::getFast());
}
return specializedVal;
diff --git a/source/slang/slang-ir-specialize.h b/source/slang/slang-ir-specialize.h
index 1feff3e4b..23d523a43 100644
--- a/source/slang/slang-ir-specialize.h
+++ b/source/slang/slang-ir-specialize.h
@@ -5,9 +5,11 @@ namespace Slang
{
struct IRModule;
class DiagnosticSink;
+class TargetRequest;
/// Specialize generic and interface-based code to use concrete types.
bool specializeModule(
+ TargetRequest* target,
IRModule* module,
DiagnosticSink* sink);
diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp
index 03e823d25..d5b24dd31 100644
--- a/source/slang/slang-ir-spirv-legalize.cpp
+++ b/source/slang/slang-ir-spirv-legalize.cpp
@@ -1781,7 +1781,7 @@ void buildEntryPointReferenceGraph(SPIRVEmitSharedContext* context, IRModule* mo
visit(workList[i].entryPoint, workList[i].inst);
}
-void simplifyIRForSpirvLegalization(DiagnosticSink* sink, IRModule* module)
+void simplifyIRForSpirvLegalization(TargetRequest* target, DiagnosticSink* sink, IRModule* module)
{
bool changed = true;
const int kMaxIterations = 8;
@@ -1796,7 +1796,7 @@ void simplifyIRForSpirvLegalization(DiagnosticSink* sink, IRModule* module)
changed = false;
changed |= applySparseConditionalConstantPropagationForGlobalScope(module, sink);
- changed |= peepholeOptimizeGlobalScope(module);
+ changed |= peepholeOptimizeGlobalScope(target, module);
for (auto inst : module->getGlobalInsts())
{
@@ -1809,7 +1809,7 @@ void simplifyIRForSpirvLegalization(DiagnosticSink* sink, IRModule* module)
{
funcChanged = false;
funcChanged |= applySparseConditionalConstantPropagation(func, sink);
- funcChanged |= peepholeOptimize(func);
+ funcChanged |= peepholeOptimize(target, func);
funcChanged |= removeRedundancyInFunc(func);
funcChanged |= simplifyCFG(func, CFGSimplificationOptions::getFast());
eliminateDeadCode(func);
@@ -1826,7 +1826,7 @@ void legalizeIRForSPIRV(
{
SLANG_UNUSED(entryPoints);
legalizeSPIRV(context, module);
- simplifyIRForSpirvLegalization(codeGenContext->getSink(), module);
+ simplifyIRForSpirvLegalization(context->m_targetRequest, codeGenContext->getSink(), module);
buildEntryPointReferenceGraph(context, module);
}
diff --git a/source/slang/slang-ir-ssa-simplification.cpp b/source/slang/slang-ir-ssa-simplification.cpp
index 104ce05e4..f20d1295c 100644
--- a/source/slang/slang-ir-ssa-simplification.cpp
+++ b/source/slang/slang-ir-ssa-simplification.cpp
@@ -17,7 +17,7 @@ namespace Slang
{
// Run a combination of SSA, SCCP, SimplifyCFG, and DeadCodeElimination pass
// until no more changes are possible.
- void simplifyIR(IRModule* module, IRSimplificationOptions options, DiagnosticSink* sink)
+ void simplifyIR(TargetRequest* target, IRModule* module, IRSimplificationOptions options, DiagnosticSink* sink)
{
SLANG_PROFILE;
bool changed = true;
@@ -36,7 +36,7 @@ namespace Slang
changed |= propagateFuncProperties(module);
changed |= removeUnusedGenericParam(module);
changed |= applySparseConditionalConstantPropagationForGlobalScope(module, sink);
- changed |= peepholeOptimizeGlobalScope(module);
+ changed |= peepholeOptimizeGlobalScope(target, module);
for (auto inst : module->getGlobalInsts())
{
@@ -49,7 +49,7 @@ namespace Slang
{
funcChanged = false;
funcChanged |= applySparseConditionalConstantPropagation(func, sink);
- funcChanged |= peepholeOptimize(func);
+ funcChanged |= peepholeOptimize(target, func);
funcChanged |= removeRedundancyInFunc(func);
funcChanged |= simplifyCFG(func, options.cfgOptions);
eliminateDeadCode(func);
@@ -68,7 +68,7 @@ namespace Slang
}
}
- void simplifyNonSSAIR(IRModule* module, IRSimplificationOptions options)
+ void simplifyNonSSAIR(TargetRequest* target, IRModule* module, IRSimplificationOptions options)
{
bool changed = true;
const int kMaxIterations = 8;
@@ -76,7 +76,7 @@ namespace Slang
while (changed && iterationCounter < kMaxIterations)
{
changed = false;
- changed |= peepholeOptimize(module);
+ changed |= peepholeOptimize(target, module);
changed |= removeRedundancy(module);
changed |= simplifyCFG(module, options.cfgOptions);
@@ -90,7 +90,7 @@ namespace Slang
}
- void simplifyFunc(IRGlobalValueWithCode* func, IRSimplificationOptions options, DiagnosticSink* sink)
+ void simplifyFunc(TargetRequest* target, IRGlobalValueWithCode* func, IRSimplificationOptions options, DiagnosticSink* sink)
{
bool changed = true;
const int kMaxIterations = 8;
@@ -102,7 +102,7 @@ namespace Slang
changed = false;
changed |= applySparseConditionalConstantPropagation(func, sink);
- changed |= peepholeOptimize(func);
+ changed |= peepholeOptimize(target, func);
changed |= removeRedundancyInFunc(func);
changed |= simplifyCFG(func, options.cfgOptions);
diff --git a/source/slang/slang-ir-ssa-simplification.h b/source/slang/slang-ir-ssa-simplification.h
index 88347aa17..d338bf23d 100644
--- a/source/slang/slang-ir-ssa-simplification.h
+++ b/source/slang/slang-ir-ssa-simplification.h
@@ -8,6 +8,7 @@ namespace Slang
struct IRModule;
struct IRGlobalValueWithCode;
class DiagnosticSink;
+ class TargetRequest;
struct IRSimplificationOptions
{
@@ -28,10 +29,10 @@ namespace Slang
// Run a combination of SSA, SCCP, SimplifyCFG, and DeadCodeElimination pass
// until no more changes are possible.
- void simplifyIR(IRModule* module, IRSimplificationOptions options, DiagnosticSink* sink = nullptr);
+ void simplifyIR(TargetRequest* target, IRModule* module, IRSimplificationOptions options, DiagnosticSink* sink = nullptr);
// Run simplifications on IR that is out of SSA form.
- void simplifyNonSSAIR(IRModule* module, IRSimplificationOptions options);
+ void simplifyNonSSAIR(TargetRequest* target, IRModule* module, IRSimplificationOptions options);
- void simplifyFunc(IRGlobalValueWithCode* func, IRSimplificationOptions options, DiagnosticSink* sink = nullptr);
+ void simplifyFunc(TargetRequest* target, IRGlobalValueWithCode* func, IRSimplificationOptions options, DiagnosticSink* sink = nullptr);
}
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index b43821cf1..4ee4efc16 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -3956,6 +3956,16 @@ struct ExprLoweringVisitorBase : public ExprVisitor<Derived, LoweredValInfo>
}
return builder->emitSPIRVAsmOperandInst(i);
}
+ case SPIRVAsmOperand::SlangImmediateValue:
+ {
+ IRInst* i;
+ {
+ IRBuilderInsertLocScope insertScope(builder);
+ builder->setInsertBefore(spirvAsmInst);
+ i = getSimpleVal(context, lowerRValueExpr(context, operand.expr));
+ }
+ return builder->emitSPIRVAsmOperandEnum(i);
+ }
case SPIRVAsmOperand::SlangValueAddr:
{
IRInst* i;
@@ -10295,7 +10305,7 @@ RefPtr<IRModule> generateIRForTranslationUnit(
constructSSA(module);
simplifyCFG(module, CFGSimplificationOptions::getDefault());
applySparseConditionalConstantPropagation(module, compileRequest->getSink());
- peepholeOptimize(module);
+ peepholeOptimize(nullptr, module);
for (auto inst : module->getGlobalInsts())
{
@@ -10344,7 +10354,7 @@ RefPtr<IRModule> generateIRForTranslationUnit(
changed |= constructSSA(module);
simplifyCFG(module, CFGSimplificationOptions::getDefault());
changed |= applySparseConditionalConstantPropagation(module, compileRequest->getSink());
- changed |= peepholeOptimize(module);
+ changed |= peepholeOptimize(nullptr, module);
for (auto inst : module->getGlobalInsts())
{
if (auto func = as<IRGlobalValueWithCode>(inst))
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index 7be03a313..62ab71430 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -6995,7 +6995,12 @@ namespace Slang
{
return slangTypeExprOperand(SPIRVAsmOperand::SlangType);
}
-
+ // A !immediateValue
+ else if (AdvanceIf(parser, TokenType::OpNot))
+ {
+ Expr* expr = parseAtomicExpr(parser);
+ return SPIRVAsmOperand{ SPIRVAsmOperand::SlangImmediateValue, Token{}, expr };
+ }
Unexpected(parser);
return std::nullopt;
}