add -alias-stats
MODIFY
ir/memory.cpp
ir/memory.cpp
#include "ir/value.h"
#include "smt/solver.h"
#include "util/compiler.h"
+#include <array>
+#include <numeric>
#include <string>
using namespace IR;
@@ -975,6 +977,54 @@ void Memory::AliasSet::unionWith(const AliasSet &other) {
unionfn(non_local, other.non_local);
}
+static const array<uint64_t, 5> alias_buckets_vals = { 1, 2, 3, 5, 10 };
+static array<uint64_t, 6> alias_buckets_hits = { 0 };
+static uint64_t only_local = 0, only_nonlocal = 0;
+
+
+void Memory::AliasSet::computeAccessStats() const {
+ auto nlocal = numMayAlias(true);
+ auto nnonlocal = numMayAlias(false);
+
+ if (nlocal > 0 && nnonlocal == 0)
+ ++only_local;
+ else if (nlocal == 0 && nnonlocal > 0)
+ ++only_nonlocal;
+
+ auto alias = nlocal + nnonlocal;
+ for (unsigned i = 0; i < alias_buckets_vals.size(); ++i) {
+ if (alias <= alias_buckets_vals[i]) {
+ ++alias_buckets_hits[i];
+ return;
+ }
+ }
+ ++alias_buckets_hits.back();
+}
+
+void Memory::AliasSet::printStats(ostream &os) {
+ double total
+ = accumulate(alias_buckets_hits.begin(), alias_buckets_hits.end(), 0);
+
+ if (!total)
+ return;
+
+ total /= 100.0;
+ os.precision(1);
+ os << fixed;
+
+ os << "\n\nAlias sets statistics\n=====================\n"
+ "Only local: " << (only_local / total)
+ << "%\nOnly non-local: " << (only_nonlocal / total)
+ << "%\n\nBuckets:\n";
+
+ for (unsigned i = 0; i < alias_buckets_vals.size(); ++i) {
+ os << "\u2264 " << alias_buckets_vals[i] << ": "
+ << (alias_buckets_hits[i] / total) << "%\n";
+ }
+ os << "> " << alias_buckets_vals.back() << ": "
+ << (alias_buckets_hits.back() / total) << "%\n";
+}
+
bool Memory::AliasSet::operator<(const AliasSet &rhs) const {
return tie(local, non_local) < tie(rhs.local, rhs.non_local);
}
@@ -1139,6 +1189,8 @@ end:
alias_info.intersectWith(aliasing);
}
+ alias_info.computeAccessStats();
+
unsigned has_local = alias_info.numMayAlias(true);
unsigned has_nonlocal = alias_info.numMayAlias(false);
bool has_both = has_local && has_nonlocal;

MODIFY
ir/memory.h
ir/memory.h
@@ -220,6 +220,9 @@ class Memory {
void intersectWith(const AliasSet &other);
void unionWith(const AliasSet &other);
+ void computeAccessStats() const;
+ static void printStats(std::ostream &os);
+
// for container use only
bool operator<(const AliasSet &rhs) const;
@@ -408,6 +411,10 @@ public:
// for container use only
bool operator<(const Memory &rhs) const;
+ static void printAliasStats(std::ostream &os) {
+ AliasSet::printStats(os);
+ }
+
void print(std::ostream &os, const smt::Model &m) const;
friend std::ostream& operator<<(std::ostream &os, const Memory &m);

MODIFY
tools/alive-tv.cpp
tools/alive-tv.cpp
// Distributed under the MIT license that can be found in the LICENSE file.
#include "llvm_util/llvm2alive.h"
+#include "ir/memory.h"
#include "smt/smt.h"
#include "tools/transform.h"
#include "util/config.h"
@@ -96,6 +97,10 @@ static llvm::cl::opt<bool> opt_smt_stats(
"smt-stats", llvm::cl::desc("Show SMT statistics"),
llvm::cl::cat(opt_alive), llvm::cl::init(false));
+static llvm::cl::opt<bool> opt_alias_stats(
+ "alias-stats", llvm::cl::desc("Show alias sets statistics"),
+ llvm::cl::cat(opt_alive), llvm::cl::init(false));
+
static llvm::cl::opt<bool> opt_succinct(
"succinct", llvm::cl::desc("Make the output succinct"),
llvm::cl::cat(opt_alive), llvm::cl::init(false));
@@ -495,5 +500,8 @@ end:
smt_init.reset();
+ if (opt_alias_stats)
+ IR::Memory::printAliasStats(cout);
+
return errorCount > 0;
}

MODIFY
tv/tv.cpp
tv/tv.cpp
// Distributed under the MIT license that can be found in the LICENSE file.
#include "llvm_util/llvm2alive.h"
+#include "ir/memory.h"
#include "smt/smt.h"
#include "smt/solver.h"
#include "tools/transform.h"
@@ -59,6 +60,10 @@ llvm::cl::opt<bool> opt_smt_stats(
"tv-smt-stats", llvm::cl::desc("Alive: show SMT statistics"),
llvm::cl::init(false));
+llvm::cl::opt<bool> opt_alias_stats(
+ "tv-alias-stats", llvm::cl::desc("Alive: show alias sets statistics"),
+ llvm::cl::init(false));
+
llvm::cl::opt<bool> opt_smt_skip(
"tv-smt-skip", llvm::cl::desc("Alive: skip SMT queries"),
llvm::cl::init(false));
@@ -271,6 +276,8 @@ struct TVPass final : public llvm::FunctionPass {
showed_stats = true;
if (opt_smt_stats)
smt::solver_print_stats(*out);
+ if (opt_alias_stats)
+ IR::Memory::printAliasStats(cout);
if (has_failure && !report_filename.empty())
cerr << "Report written to " << report_filename << endl;
}

add -alias-stats