Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Unified Diff: lib/compiler/implementation/ssa/codegen_helpers.dart

Issue 10050010: Avoid some unnecessary variables for phis. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/compiler/implementation/ssa/codegen_helpers.dart
diff --git a/lib/compiler/implementation/ssa/codegen_helpers.dart b/lib/compiler/implementation/ssa/codegen_helpers.dart
index 2945a055735bd88b6796d76b3e7c6c66e11c00c7..cb2239659f0727c25595a285e87cfe79262b6bab 100644
--- a/lib/compiler/implementation/ssa/codegen_helpers.dart
+++ b/lib/compiler/implementation/ssa/codegen_helpers.dart
@@ -351,3 +351,69 @@ class JSBinaryOperatorPrecedence {
// All binary operators (excluding assignment) are left associative.
int get precedence() => left;
}
+
+class PhiEquivalator {
+ final Equivalence<HPhi> equivalence;
+ final Map<HPhi, String> logicalOperations;
+ PhiEquivalator(this.equivalence, this.logicalOperations);
+
+ void analyzeGraph(HGraph graph) {
+ graph.blocks.forEach((HBasicBlock block) => analyzeBlock(block));
+ }
+
+ void analyzeBlock(HBasicBlock block) {
+ for (HPhi phi = block.phis.first; phi !== null; phi = phi.next) {
+ if (!logicalOperations.containsKey(phi) &&
+ phi.usedBy.length == 1 &&
+ phi.usedBy[0] is HPhi) {
+ equivalence.makeEquivalent(phi, phi.usedBy[0]);
+ }
+ }
+ }
+}
+
+
+/**
+ * Try to figure out which phis can be represented by the same temporary
+ * variable, to avoid creating a new variable for each phi.
+ */
+class Equivalence<T extends Hashable> {
+ // Represent equivalence classes of HPhi nodes as a forest of trees,
+ // where each tree is one equivalence class, and the root is the
+ // canonical representative for the equivalence class.
+ // Implement the forest by having each phi point to its parent in the tree,
+ // transitively linking it to the root, which itself doesn't have a parent.
+ final Map<T,T> representative;
+
+ Equivalence() : representative = new Map<T,T>();
+
+ T makeEquivalent(T a, T b) {
+ T root1 = getRepresentative(a);
+ T root2 = getRepresentative(b);
+ if (root1 !== root2) {
+ // Merge the trees for the two classes into one.
+ representative[root1] = root2;
+ }
+ }
+
+ /**
+ * Get the canonical representative for an equivalence class of phis.
+ */
+ T getRepresentative(T element) {
+ T parent = representative[element];
+ if (parent === null) {
+ // This is the root of a tree (a previously unseen node is considered
+ // the root of its own tree).
+ return element;
+ }
+ // Shorten the path for all the elements on the way to the root,
+ // improving the performance of future lookups.
+ T root = getRepresentative(parent);
+ if (root !== parent) representative[element] = root;
+ return root;
+ }
+
+ bool areEquivalent(T a, T b) {
+ return getRepresentative(a) === getRepresentative(b);
+ }
+}
« lib/compiler/implementation/ssa/codegen.dart ('K') | « lib/compiler/implementation/ssa/codegen.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698