summaryrefslogtreecommitdiff
path: root/source/slang/slang-ir-use-uninitialized-values.cpp
diff options
context:
space:
mode:
authorvenkataram-nv <vedavamadath@nvidia.com>2024-07-31 11:51:09 -0700
committerGitHub <noreply@github.com>2024-07-31 11:51:09 -0700
commit93a3ba812dd33b10f166f9172bd781e84d938e21 (patch)
treefd5175d41a5b16f6de97ba37dd00267219ec3e4d /source/slang/slang-ir-use-uninitialized-values.cpp
parent134f8ccc930a8da28808c2e288344c21c67a577e (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.cpp99
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);