summaryrefslogtreecommitdiffstats
path: root/source/slang/ir-ssa.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/ir-ssa.cpp')
-rw-r--r--source/slang/ir-ssa.cpp36
1 files changed, 31 insertions, 5 deletions
diff --git a/source/slang/ir-ssa.cpp b/source/slang/ir-ssa.cpp
index 432dfc1b1..53eefd81f 100644
--- a/source/slang/ir-ssa.cpp
+++ b/source/slang/ir-ssa.cpp
@@ -89,7 +89,9 @@ struct ConstructSSAContext
PhiInfo* getPhiInfo(IRParam* phi)
{
- return *phiInfos.TryGetValue(phi);
+ if(auto found = phiInfos.TryGetValue(phi))
+ return *found;
+ return nullptr;
}
};
@@ -219,7 +221,7 @@ PhiInfo* addPhi(
}
IRValue* tryRemoveTrivialPhi(
- ConstructSSAContext* /*context*/,
+ ConstructSSAContext* context,
PhiInfo* phiInfo)
{
auto phi = phiInfo->phi;
@@ -266,6 +268,26 @@ IRValue* tryRemoveTrivialPhi(
assert(!"unimplemented");
}
+ // Removing this phi as trivial may make other phi nodes
+ // become trivial. We will recognize such candidates
+ // by looking for phi nodes that use this node.
+ List<PhiInfo*> otherPhis;
+ for( auto u = phi->firstUse; u; u = u->nextUse )
+ {
+ auto user = u->user;
+ if(!user) continue;
+ if(user == phi) continue;
+
+ if( user->op == kIROp_Param )
+ {
+ auto maybeOtherPhi = (IRParam*) user;
+ if( auto otherPhiInfo = context->getPhiInfo(maybeOtherPhi) )
+ {
+ otherPhis.Add(otherPhiInfo);
+ }
+ }
+ }
+
// replace uses of the phi (including its possible uses
// of itself) with the unique non-phi value.
phi->replaceUsesWith(same);
@@ -281,8 +303,12 @@ IRValue* tryRemoveTrivialPhi(
// phi, so that we can easily look it up later.
phiInfo->replacement = same;
- // TODO: need to recursively consider chances to simplify
- // other phi nodes now.
+ // Now that we've cleaned up this phi, we need to consider
+ // other phis that might have become trivial.
+ for( auto otherPhi : otherPhis )
+ {
+ tryRemoveTrivialPhi(context, otherPhi);
+ }
return same;
}
@@ -320,7 +346,7 @@ IRValue* addPhiOperands(
phiInfo->operands.SetSize(operandCount);
for(UInt ii = 0; ii < operandCount; ++ii)
{
- phiInfo->operands[ii].init(nullptr, operandValues[ii]);
+ phiInfo->operands[ii].init(phiInfo->phi, operandValues[ii]);
}
return tryRemoveTrivialPhi(context, phiInfo);