From 90c9323511de81a7b13a68c5fd89feb48b439259 Mon Sep 17 00:00:00 2001 From: Bill Nell Date: Thu, 7 Jul 2016 11:48:50 -0700 Subject: [PATCH] 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) --- bolt/BinaryFunction.h | 4 ++-- bolt/ReorderAlgorithm.cpp | 30 ++++++++++++++++++++++++++---- bolt/ReorderAlgorithm.h | 4 ++-- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/bolt/BinaryFunction.h b/bolt/BinaryFunction.h index 9c2a54e62c43..35ab0ba8ed6a 100644 --- a/bolt/BinaryFunction.h +++ b/bolt/BinaryFunction.h @@ -36,7 +36,7 @@ #include "llvm/Support/Dwarf.h" #include "llvm/Support/raw_ostream.h" #include -#include +#include #include 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 BasicBlockIndices; + std::unordered_map 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 diff --git a/bolt/ReorderAlgorithm.cpp b/bolt/ReorderAlgorithm.cpp index 8465b9aff4d1..23d1c31a5fe3 100644 --- a/bolt/ReorderAlgorithm.cpp +++ b/bolt/ReorderAlgorithm.cpp @@ -16,6 +16,7 @@ #include "BinaryFunction.h" #include "llvm/Support/CommandLine.h" #include +#include using namespace llvm; using namespace bolt; @@ -27,6 +28,26 @@ PrintClusters("print-clusters", cl::desc("print clusters"), cl::Optional); } // namespace opts +namespace { + +template +inline void hashCombine(size_t &Seed, const T &Val) { + std::hash Hasher; + Seed ^= Hasher(Val) + 0x9e3779b9 + (Seed << 6) + (Seed >> 2); +} + +template +struct HashPair { + size_t operator()(const std::pair& Val) const { + std::hash 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 EdgeTy; - std::map Weight; + typedef HashPair Hasher; + std::unordered_map 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, decltype(Comp)> Queue(Comp); - typedef std::map BBToClusterMapTy; + typedef std::unordered_map 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> Weight; - std::map BBToIndex; + std::unordered_map BBToIndex; std::vector IndexToBB; unsigned N = BF.layout_size(); @@ -280,7 +302,7 @@ void OptimizeBranchReorderAlgorithm::reorderBasicBlocks( // Cluster basic blocks. CAlgo->clusterBasicBlocks(BF); std::vector &Clusters = CAlgo->Clusters;; - std::vector> &ClusterEdges = CAlgo->ClusterEdges; + auto &ClusterEdges = CAlgo->ClusterEdges; // Compute clusters' average frequencies. CAlgo->computeClusterAverageFrequency(); diff --git a/bolt/ReorderAlgorithm.h b/bolt/ReorderAlgorithm.h index 9ea30ed19f81..4a4947c662ef 100644 --- a/bolt/ReorderAlgorithm.h +++ b/bolt/ReorderAlgorithm.h @@ -15,7 +15,7 @@ #define LLVM_TOOLS_LLVM_BOLT_REORDER_ALGORITHM_H #include "llvm/Support/ErrorHandling.h" -#include +#include #include #include @@ -35,7 +35,7 @@ class ClusterAlgorithm { public: typedef std::vector ClusterTy; std::vector Clusters; - std::vector> ClusterEdges; + std::vector> ClusterEdges; std::vector AvgFreq; /// Group the basic blocks the given function into clusters stored in the