summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-exegesis/lib/Clustering.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/Clustering.h')
-rw-r--r--llvm/tools/llvm-exegesis/lib/Clustering.h28
1 files changed, 22 insertions, 6 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/Clustering.h b/llvm/tools/llvm-exegesis/lib/Clustering.h
index dccc28d9518..70082044f56 100644
--- a/llvm/tools/llvm-exegesis/lib/Clustering.h
+++ b/llvm/tools/llvm-exegesis/lib/Clustering.h
@@ -15,7 +15,9 @@
#define LLVM_TOOLS_LLVM_EXEGESIS_CLUSTERING_H
#include "BenchmarkResult.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/Error.h"
+#include <limits>
#include <vector>
namespace llvm {
@@ -27,21 +29,28 @@ public:
// for more explanations on the algorithm.
static llvm::Expected<InstructionBenchmarkClustering>
create(const std::vector<InstructionBenchmark> &Points, size_t MinPts,
- double Epsilon);
+ double Epsilon, llvm::Optional<unsigned> NumOpcodes = llvm::None);
class ClusterId {
public:
static ClusterId noise() { return ClusterId(kNoise); }
static ClusterId error() { return ClusterId(kError); }
static ClusterId makeValid(size_t Id) { return ClusterId(Id); }
- ClusterId() : Id_(kUndef) {}
+ static ClusterId makeValidUnstable(size_t Id) {
+ return ClusterId(Id, /*IsUnstable=*/true);
+ }
+
+ ClusterId() : Id_(kUndef), IsUnstable_(false) {}
+
+ // Compare id's, ignoring the 'unstability' bit.
bool operator==(const ClusterId &O) const { return Id_ == O.Id_; }
bool operator<(const ClusterId &O) const { return Id_ < O.Id_; }
bool isValid() const { return Id_ <= kMaxValid; }
- bool isUndef() const { return Id_ == kUndef; }
+ bool isUnstable() const { return IsUnstable_; }
bool isNoise() const { return Id_ == kNoise; }
bool isError() const { return Id_ == kError; }
+ bool isUndef() const { return Id_ == kUndef; }
// Precondition: isValid().
size_t getId() const {
@@ -50,14 +59,19 @@ public:
}
private:
- explicit ClusterId(size_t Id) : Id_(Id) {}
+ ClusterId(size_t Id, bool IsUnstable = false)
+ : Id_(Id), IsUnstable_(IsUnstable) {}
+
static constexpr const size_t kMaxValid =
- std::numeric_limits<size_t>::max() - 4;
+ (std::numeric_limits<size_t>::max() >> 1) - 4;
static constexpr const size_t kNoise = kMaxValid + 1;
static constexpr const size_t kError = kMaxValid + 2;
static constexpr const size_t kUndef = kMaxValid + 3;
- size_t Id_;
+
+ size_t Id_ : (std::numeric_limits<size_t>::digits - 1);
+ size_t IsUnstable_ : 1;
};
+ static_assert(sizeof(ClusterId) == sizeof(size_t), "should be a bit field.");
struct Cluster {
Cluster() = delete;
@@ -101,8 +115,10 @@ public:
private:
InstructionBenchmarkClustering(
const std::vector<InstructionBenchmark> &Points, double EpsilonSquared);
+
llvm::Error validateAndSetup();
void dbScan(size_t MinPts);
+ void stabilize(unsigned NumOpcodes);
void rangeQuery(size_t Q, std::vector<size_t> &Scratchpad) const;
const std::vector<InstructionBenchmark> &Points_;
OpenPOWER on IntegriCloud