diff options
| author | Yong He <yonghe@outlook.com> | 2023-12-15 17:05:32 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-15 17:05:32 -0800 |
| commit | b507d881ca47135bfa46237767e7183f61e7d8e3 (patch) | |
| tree | 3bbe4652a6972d940fd4df92a113b760c3a9e115 /source/slang | |
| parent | f8b3027d0be0b890152a6a649822741cd3a3b6b6 (diff) | |
Add ConstBufferPointer::subscript. (#3415)
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source/slang')
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; } |
