summaryrefslogtreecommitdiff
path: root/src/ir/LocalGraph.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir/LocalGraph.cpp')
-rw-r--r--src/ir/LocalGraph.cpp39
1 files changed, 38 insertions, 1 deletions
diff --git a/src/ir/LocalGraph.cpp b/src/ir/LocalGraph.cpp
index bf1f7e576..2fdf1e4a4 100644
--- a/src/ir/LocalGraph.cpp
+++ b/src/ir/LocalGraph.cpp
@@ -227,7 +227,7 @@ struct Flower : public CFGWalker<Flower, Visitor<Flower>, Info> {
// LocalGraph implementation
-LocalGraph::LocalGraph(Function* func) {
+LocalGraph::LocalGraph(Function* func) : func(func) {
LocalGraphInternal::Flower flower(getSetses, locations, func);
#ifdef LOCAL_GRAPH_DEBUG
@@ -244,6 +244,43 @@ LocalGraph::LocalGraph(Function* func) {
#endif
}
+bool LocalGraph::equivalent(LocalGet* a, LocalGet* b) {
+ auto& aSets = getSetses[a];
+ auto& bSets = getSetses[b];
+ // The simple case of one set dominating two gets easily proves that they must
+ // have the same value. (Note that we can infer dominance from the fact that
+ // there is a single set: if the set did not dominate one of the gets then
+ // there would definitely be another set for that get, the zero initialization
+ // at the function entry, if nothing else.)
+ if (aSets.size() != 1 || bSets.size() != 1) {
+ // TODO: use a LinearExecutionWalker to find trivially equal gets in basic
+ // blocks. that plus the above should handle 80% of cases.
+ // TODO: handle chains, merges and other situations
+ return false;
+ }
+ auto* aSet = *aSets.begin();
+ auto* bSet = *bSets.begin();
+ if (aSet != bSet) {
+ return false;
+ }
+ if (!aSet) {
+ // They are both nullptr, indicating the implicit value for a parameter
+ // or the zero for a local.
+ if (func->isParam(a->index)) {
+ // For parameters to be equivalent they must have the exact same
+ // index.
+ return a->index == b->index;
+ } else {
+ // As locals, they are both of value zero, but must have the right
+ // type as well.
+ return func->getLocalType(a->index) == func->getLocalType(b->index);
+ }
+ } else {
+ // They are both the same actual set.
+ return true;
+ }
+}
+
void LocalGraph::computeInfluences() {
for (auto& pair : locations) {
auto* curr = pair.first;