private boolean matchesPhi(final Expr real, final Phi phi) {
		final Bool match = new Bool();
		match.value = true;

		real.visitChildren(new TreeVisitor() {
			public void visitExpr(final Expr expr) {
				if (match.value) {
					expr.visitChildren(this);
				}
			}

			public void visitStoreExpr(final StoreExpr expr) {
				// A store means a new SSA number, so they won't match
				match.value = false;
			}

			public void visitVarExpr(final VarExpr expr) {
				if (!match.value) {
					return;
				}

				// We're dealing with one of the operands of the real
				// occurrence. If the operand is defined by a phi-statement
				// that occurrs in the same block as the PHI-statement, then
				// the variable in the real occurrence is the same as that in
				// the PHI-statement. Similarly, is the block in which the
				// real occurrence's definition occurs dominate the block in
				// which the PHI-statement occurs, the two versions of the
				// variable are the same. Otherwise the variable has been
				// modified between the PHI-statement and the real occurrence.

				final VarExpr def = (VarExpr) expr.def();

				if (def == null) {
					match.value = false;
					return;
				}

				final Block block = phi.block();

				final Node p = def.parent();

				if (block == p.block()) {
					// Anything other than a var-phi means the real occurrence
					// uses a variable defined after the Phi.
					if (p instanceof PhiJoinStmt) {
						return;
					}

				} else if (p.block().dominates(block)) {
					// The real uses a var defined above the phi.
					// This, too, is okay.
					return;
				}

				// The real uses a variable defined after the Phi.
				match.value = false;
			}
		});

		return match.value;
	}