diff options
| author | venkataram-nv <vedavamadath@nvidia.com> | 2024-07-31 11:51:09 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-31 11:51:09 -0700 |
| commit | 93a3ba812dd33b10f166f9172bd781e84d938e21 (patch) | |
| tree | fd5175d41a5b16f6de97ba37dd00267219ec3e4d /source/slang/slang-ir-use-uninitialized-values.cpp | |
| parent | 134f8ccc930a8da28808c2e288344c21c67a577e (diff) | |
Warnings target switch intrinsic asm (#4727)
* Proper warning generation for target switches and intrinsic asm
* Relaxing terminators
* Fix compiler warnings
* Rectified target switch reachability check
* Simplify target switch reachability check
* Refactoring variable names
* Using getBlocks
* Moving ad hoc special case to diagnostics source
* Using the LINE directive for testing
* Simplifying reliance on target switches
* Skipping IR generation for empty target switches
---------
Co-authored-by: Yong He <yonghe@outlook.com>
Diffstat (limited to 'source/slang/slang-ir-use-uninitialized-values.cpp')
| -rw-r--r-- | source/slang/slang-ir-use-uninitialized-values.cpp | 99 |
1 files changed, 51 insertions, 48 deletions
diff --git a/source/slang/slang-ir-use-uninitialized-values.cpp b/source/slang/slang-ir-use-uninitialized-values.cpp index 9f2cbe7a7..ca723a97c 100644 --- a/source/slang/slang-ir-use-uninitialized-values.cpp +++ b/source/slang/slang-ir-use-uninitialized-values.cpp @@ -2,6 +2,7 @@ #include "slang-ir-insts.h" #include "slang-ir-reachability.h" #include "slang-ir.h" +#include "slang-ir-util.h" namespace Slang { @@ -37,30 +38,30 @@ namespace Slang || (inst->m_op == kIROp_Var); } - static bool isUndefinedParam(IRParam* param) + static bool isPotentiallyUnintended(IRParam* param) { - auto outType = as<IROutType>(param->getFullType()); - if (!outType) - return false; - - // Don't check `out Vertices<T>` or `out Indices<T>` parameters - // in mesh shaders. - // TODO: we should find a better way to represent these mesh shader - // parameters so they conform to the initialize before use convention. - // For example, we can use a `OutputVetices` and `OutputIndices` type - // to represent an output, like `OutputPatch` in domain shader. - // For now, we just skip the check for these parameters. - switch (outType->getValueType()->getOp()) - { - case kIROp_VerticesType: - case kIROp_IndicesType: - case kIROp_PrimitivesType: - return false; - default: - break; - } + auto outType = as<IROutType>(param->getFullType()); + if (!outType) + return false; + + // Don't check `out Vertices<T>` or `out Indices<T>` parameters + // in mesh shaders. + // TODO: we should find a better way to represent these mesh shader + // parameters so they conform to the initialize before use convention. + // For example, we can use a `OutputVetices` and `OutputIndices` type + // to represent an output, like `OutputPatch` in domain shader. + // For now, we just skip the check for these parameters. + switch (outType->getValueType()->getOp()) + { + case kIROp_VerticesType: + case kIROp_IndicesType: + case kIROp_PrimitivesType: + return false; + default: + break; + } - return true; + return true; } static bool isAliasable(IRInst* inst) @@ -220,6 +221,15 @@ namespace Slang loads.add(call); } + static void collectSpecialCaseInstructions(List<IRInst*>& stores, IRBlock* block) + { + for (auto inst = block->getFirstInst(); inst; inst = inst->next) + { + if (as<IRGenericAsm>(inst)) + stores.add(inst); + } + } + static void collectLoadStore(List<IRInst*>& stores, List<IRInst*>& loads, IRInst* user, IRInst* inst) { // Meta intrinsics (which evaluate on type) do nothing @@ -248,8 +258,6 @@ namespace Slang case kIROp_Store: case kIROp_SwizzledStore: case kIROp_SPIRVAsm: - case kIROp_GenericAsm: - // For now assume that __intrinsic_asm blocks will do the right thing... stores.add(user); break; @@ -277,7 +285,7 @@ namespace Slang } } - static void cancelLoads(ReachabilityContext &reachability, const List<IRInst*>& stores, List<IRInst*>& loads) + static void cancelLoads(ReachabilityContext& reachability, const List<IRInst*>& stores, List<IRInst*>& loads) { // Remove all loads which are reachable from stores for (auto store : stores) @@ -292,15 +300,10 @@ namespace Slang } } - static List<IRInst*> getUnresolvedParamLoads(ReachabilityContext &reachability, IRFunc* func, IRInst* inst) + static void collectAliasableLoadStores(IRInst* inst, List<IRInst*>& stores, List<IRInst*>& loads) { - // Collect all aliasable addresses auto addresses = getAliasableInstructions(inst); - // Partition instructions - List<IRInst*> stores; - List<IRInst*> loads; - for (auto alias : addresses) { // TODO: Mark specific parts assigned to for partial initialization checks @@ -310,15 +313,24 @@ namespace Slang collectLoadStore(stores, loads, user, alias); } } + } + + static List<IRInst*> getUnresolvedParamLoads(ReachabilityContext &reachability, IRFunc* func, IRInst* inst) + { + // Partition instructions + List<IRInst*> stores; + List<IRInst*> loads; + + collectAliasableLoadStores(inst, stores, loads); - // Only for out params we shall add all returns + // Special cases for parameters for (const auto& b : func->getBlocks()) { - auto t = as<IRReturn>(b->getTerminator()); - if (!t) - continue; + collectSpecialCaseInstructions(stores, b); - loads.add(t); + auto t = b->getTerminator(); + if (as<IRReturn>(t)) + loads.add(t); } cancelLoads(reachability, stores, loads); @@ -328,20 +340,11 @@ namespace Slang static List<IRInst*> getUnresolvedVariableLoads(ReachabilityContext &reachability, IRInst* inst) { - auto addresses = getAliasableInstructions(inst); - // Partition instructions List<IRInst*> stores; List<IRInst*> loads; - for (auto alias : addresses) - { - for (auto use = alias->firstUse; use; use = use->nextUse) - { - IRInst* user = use->getUser(); - collectLoadStore(stores, loads, user, alias); - } - } + collectAliasableLoadStores(inst, stores, loads); cancelLoads(reachability, stores, loads); @@ -497,14 +500,14 @@ namespace Slang // Check out parameters for (auto param : firstBlock->getParams()) { - if (!isUndefinedParam(param)) + if (!isPotentiallyUnintended(param)) continue; auto loads = getUnresolvedParamLoads(reachability, func, param); for (auto load : loads) { sink->diagnose(load, - as <IRReturn> (load) + as<IRTerminatorInst>(load) ? Diagnostics::returningWithUninitializedOut : Diagnostics::usingUninitializedOut, param); |
