Use unordered_map instead of map in ReorderAlgorithm and BinaryFunction::BasicBlockIndices.

Summary:
Use unordered_map instead of map in ReorderAlgorithm and BinaryFunction::BasicBlockIndices.
Cuts about 30sec off the processing time for the hhvm binary. (~8.5 min to ~8min)

(cherry picked from FBD3530910)
This commit is contained in:
Bill Nell
2016-07-07 11:48:50 -07:00
committed by Maksim Panchenko
parent c20506c570
commit 90c9323511
3 changed files with 30 additions and 8 deletions

View File

@@ -36,7 +36,7 @@
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/raw_ostream.h"
#include <limits>
#include <map>
#include <unordered_map>
#include <vector>
using namespace llvm::object;
@@ -259,7 +259,7 @@ private:
// Map that keeps track of the index of each basic block in the BasicBlocks
// vector. Used to make getIndex fast.
std::map<const BinaryBasicBlock*, unsigned> BasicBlockIndices;
std::unordered_map<const BinaryBasicBlock*, unsigned> BasicBlockIndices;
// At each basic block entry we attach a CFI state to detect if reordering
// corrupts the CFI state for a block. The CFI state is simply the index in

View File

@@ -16,6 +16,7 @@
#include "BinaryFunction.h"
#include "llvm/Support/CommandLine.h"
#include <queue>
#include <functional>
using namespace llvm;
using namespace bolt;
@@ -27,6 +28,26 @@ PrintClusters("print-clusters", cl::desc("print clusters"), cl::Optional);
} // namespace opts
namespace {
template <class T>
inline void hashCombine(size_t &Seed, const T &Val) {
std::hash<T> Hasher;
Seed ^= Hasher(Val) + 0x9e3779b9 + (Seed << 6) + (Seed >> 2);
}
template <typename A, typename B>
struct HashPair {
size_t operator()(const std::pair<A,B>& Val) const {
std::hash<A> Hasher;
size_t Seed = Hasher(Val.first);
hashCombine(Seed, Val.second);
return Seed;
}
};
}
void ClusterAlgorithm::computeClusterAverageFrequency() {
AvgFreq.resize(Clusters.size(), 0.0);
for (uint32_t I = 0, E = Clusters.size(); I < E; ++I) {
@@ -70,7 +91,8 @@ void GreedyClusterAlgorithm::clusterBasicBlocks(const BinaryFunction &BF) {
// Encode an edge between two basic blocks, source and destination
typedef std::pair<BinaryBasicBlock *, BinaryBasicBlock *> EdgeTy;
std::map<EdgeTy, uint64_t> Weight;
typedef HashPair<BinaryBasicBlock *, BinaryBasicBlock *> Hasher;
std::unordered_map<EdgeTy, uint64_t, Hasher> Weight;
// Define a comparison function to establish SWO between edges
auto Comp = [&] (EdgeTy A, EdgeTy B) {
@@ -88,7 +110,7 @@ void GreedyClusterAlgorithm::clusterBasicBlocks(const BinaryFunction &BF) {
};
std::priority_queue<EdgeTy, std::vector<EdgeTy>, decltype(Comp)> Queue(Comp);
typedef std::map<BinaryBasicBlock *, int> BBToClusterMapTy;
typedef std::unordered_map<BinaryBasicBlock *, int> BBToClusterMapTy;
BBToClusterMapTy BBToClusterMap;
ClusterEdges.resize(BF.layout_size());
@@ -162,7 +184,7 @@ void GreedyClusterAlgorithm::clusterBasicBlocks(const BinaryFunction &BF) {
void OptimalReorderAlgorithm::reorderBasicBlocks(
const BinaryFunction &BF, BasicBlockOrder &Order) const {
std::vector<std::vector<uint64_t>> Weight;
std::map<BinaryBasicBlock *, int> BBToIndex;
std::unordered_map<BinaryBasicBlock *, int> BBToIndex;
std::vector<BinaryBasicBlock *> IndexToBB;
unsigned N = BF.layout_size();
@@ -280,7 +302,7 @@ void OptimizeBranchReorderAlgorithm::reorderBasicBlocks(
// Cluster basic blocks.
CAlgo->clusterBasicBlocks(BF);
std::vector<ClusterAlgorithm::ClusterTy> &Clusters = CAlgo->Clusters;;
std::vector<std::map<uint32_t, uint64_t>> &ClusterEdges = CAlgo->ClusterEdges;
auto &ClusterEdges = CAlgo->ClusterEdges;
// Compute clusters' average frequencies.
CAlgo->computeClusterAverageFrequency();

View File

@@ -15,7 +15,7 @@
#define LLVM_TOOLS_LLVM_BOLT_REORDER_ALGORITHM_H
#include "llvm/Support/ErrorHandling.h"
#include <map>
#include <unordered_map>
#include <memory>
#include <vector>
@@ -35,7 +35,7 @@ class ClusterAlgorithm {
public:
typedef std::vector<BinaryBasicBlock *> ClusterTy;
std::vector<ClusterTy> Clusters;
std::vector<std::map<uint32_t, uint64_t>> ClusterEdges;
std::vector<std::unordered_map<uint32_t, uint64_t>> ClusterEdges;
std::vector<double> AvgFreq;
/// Group the basic blocks the given function into clusters stored in the