2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
20 #include <unordered_set>
23 #include "hphp/util/hash.h"
25 namespace HPHP::hfsort
{
27 using TargetId
= int32_t;
28 constexpr TargetId InvalidId
= -1;
31 Arc(TargetId s
, TargetId d
, double w
= 0)
36 Arc(const Arc
&) = delete;
38 friend bool operator==(const Arc
& lhs
, const Arc
& rhs
) {
39 return lhs
.src
== rhs
.src
&& lhs
.dst
== rhs
.dst
;
44 mutable double weight
;
45 mutable double normalizedWeight
{0};
46 mutable double avgCallOffset
{0};
50 int64_t operator()(const Arc
& arc
) const {
51 return hash_int64_pair(int64_t(arc
.src
), int64_t(arc
.dst
));
56 explicit Target(uint32_t size
, uint64_t samples
= 0)
64 // preds and succs contain no duplicate elements and self arcs are not allowed
65 std::vector
<TargetId
> preds
;
66 std::vector
<TargetId
> succs
;
70 TargetId
addTarget(uint32_t size
, uint64_t samples
= 0);
71 void setSamples(TargetId id
, uint64_t samples
);
72 void addSamples(TargetId id
, uint64_t samples
);
73 uint64_t getSamples(TargetId id
);
74 const Arc
& incArcWeight(TargetId src
, TargetId dst
, double w
= 1.0);
75 void normalizeArcWeights();
78 void printDot(const char* fileName
, L getLabel
) const;
80 std::vector
<Target
> targets
;
81 std::unordered_set
<Arc
, ArcHash
> arcs
;
85 Cluster(TargetId id
, const Target
& f
);
86 Cluster(const std::vector
<TargetId
>& ids
, const TargetGraph
& cg
);
88 std::string
toString() const;
89 double density() const;
91 std::vector
<TargetId
> targets
;
94 bool frozen
; // not a candidate for merging
97 /////////////////////////////////////////////////////////////////////////
99 bool compareClustersDensity(const Cluster
& c1
, const Cluster
& c2
);
100 std::vector
<Cluster
> clusterize(const TargetGraph
& cg
);
103 * HFSortPlus - layout of hot functions with iTLB cache optimization
105 std::vector
<Cluster
> hfsortPlus(const TargetGraph
& cg
);
108 * Pettis-Hansen code layout algorithm
109 * reference: K. Pettis and R. C. Hansen, "Profile Guided Code Positioning",
112 std::vector
<Cluster
> pettisAndHansen(const TargetGraph
& cg
);
114 /////////////////////////////////////////////////////////////////////////
117 void TargetGraph::printDot(const char* fileName
, L getLabel
) const {
118 FILE* file
= fopen(fileName
, "wt");
121 fprintf(file
, "digraph g {\n");
122 for (size_t f
= 0; f
< targets
.size(); f
++) {
123 if (targets
[f
].samples
== 0) continue;
126 "f%lu [label=\"%s\\nsamples=%lu\\nsize=%u\"];\n",
132 for (size_t f
= 0; f
< targets
.size(); f
++) {
133 if (targets
[f
].samples
== 0) continue;
134 for (auto dst
: targets
[f
].succs
) {
135 auto& arc
= *arcs
.find(Arc(f
, dst
));
138 "f%lu -> f%u [label=\"normWgt=%.3lf,weight=%.0lf,callOffset=%.1lf\"];"
142 arc
.normalizedWeight
,
147 fprintf(file
, "}\n");