summaryrefslogtreecommitdiffstats
path: root/source/slang/ir-ssa.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2018-02-13 10:22:54 -0800
committerGitHub <noreply@github.com>2018-02-13 10:22:54 -0800
commit32549707cc9aa67dbc19cbdc0490ffebc8ec253c (patch)
tree4a8d50d9e42d73e045cd6cddf5e5879a43ce7f6b /source/slang/ir-ssa.cpp
parent214a1fced7c53b81c00bec67fa2b91a357d5ece4 (diff)
Fix a bug in IR use-def information (#406)
The basic problem here is that when unlinking an `IRUse` from the linked list of uses, there were several cases where I was failing to set the `prevLink` field of the next node to match the `prevLink` field of the node being removed. That doesn't show up when walking the linked list of uses forward, but it breaks it whenever you have subsequent unlinking operations. This change fixes the bugs of that kind I could find, and also adds a debug validation method to try to avoid breaking it again. I also made more access to `IRUse` go through accessor methods rather than using fields directly, to try to avoid this kind of error. I stopped short of making anything `private`, because I tend to find that it creates more hassles than it avoids. A few other fixes along the way: - Made the `List<T>` type default-initialize elements when you resize it. I hadn't realized we weren't doing that. - Add a standalone `dumpIR(IRGlobalValue*)` so help when debugging issues.
Diffstat (limited to 'source/slang/ir-ssa.cpp')
-rw-r--r--source/slang/ir-ssa.cpp19
1 files changed, 10 insertions, 9 deletions
diff --git a/source/slang/ir-ssa.cpp b/source/slang/ir-ssa.cpp
index d58fd22e4..432dfc1b1 100644
--- a/source/slang/ir-ssa.cpp
+++ b/source/slang/ir-ssa.cpp
@@ -110,7 +110,7 @@ bool isPromotableVar(
for (auto u = var->firstUse; u; u = u->nextUse)
{
- auto user = u->user;
+ auto user = u->getUser();
switch (user->op)
{
default:
@@ -231,7 +231,7 @@ IRValue* tryRemoveTrivialPhi(
IRValue* same = nullptr;
for (auto u : phiInfo->operands)
{
- auto usedVal = u.usedValue;
+ auto usedVal = u.get();
assert(usedVal);
if (usedVal == same || usedVal == phi)
@@ -542,8 +542,8 @@ void processBlock(
case kIROp_Store:
{
auto storeInst = (IRStore*)ii;
- auto ptrArg = storeInst->ptr.usedValue;
- auto valArg = storeInst->val.usedValue;
+ auto ptrArg = storeInst->ptr.get();
+ auto valArg = storeInst->val.get();
if (auto var = asPromotableVar(context, ptrArg))
{
@@ -563,7 +563,7 @@ void processBlock(
case kIROp_Load:
{
IRLoad* loadInst = (IRLoad*)ii;
- auto ptrArg = loadInst->ptr.usedValue;
+ auto ptrArg = loadInst->ptr.get();
if (auto var = asPromotableVar(context, ptrArg))
{
@@ -669,10 +669,10 @@ static void breakCriticalEdges(
for (auto edgeUse : criticalEdges)
{
- auto pred = (IRBlock*) edgeUse->user->parent;
+ auto pred = (IRBlock*) edgeUse->getUser()->parent;
assert(pred->op == kIROp_Block);
- auto succ = (IRBlock*)edgeUse->usedValue;
+ auto succ = (IRBlock*)edgeUse->get();
assert(succ->op == kIROp_Block);
IRBuilder builder;
@@ -683,6 +683,8 @@ static void breakCriticalEdges(
// Create a new block that will sit "along" the edge
IRBlock* edgeBlock = builder.createBlock();
+ edgeUse->debugValidate();
+
// The predecessor block should now branch to
// the edge block.
edgeUse->set(edgeBlock);
@@ -709,7 +711,6 @@ void constructSSA(ConstructSSAContext* context)
// because our representation of SSA form doesn't allow for them.
breakCriticalEdges(context);
-
// Figure out what variables we can promote to
// SSA temporaries.
identifyPromotableVars(context);
@@ -766,7 +767,7 @@ void constructSSA(ConstructSSAContext* context)
UInt predIndex = predCounter++;
auto predInfo = *context->blockInfos.TryGetValue(pp);
- IRValue* operandVal = phiInfo->operands[predIndex].usedValue;
+ IRValue* operandVal = phiInfo->operands[predIndex].get();
phiInfo->operands[predIndex].clear();