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 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_UTIL_HFSORT_H
18 #define incl_HPHP_UTIL_HFSORT_H
21 #include <unordered_set>
24 #include "hphp/util/hash.h"
26 namespace HPHP
{ namespace hfsort
{
28 using TargetId
= int32_t;
29 constexpr TargetId InvalidId
= -1;
32 Arc(TargetId s
, TargetId d
, double w
= 0)
37 Arc(const Arc
&) = delete;
39 friend bool operator==(const Arc
& lhs
, const Arc
& rhs
) {
40 return lhs
.src
== rhs
.src
&& lhs
.dst
== rhs
.dst
;
45 mutable double weight
;
46 mutable double normalizedWeight
{0};
47 mutable double avgCallOffset
{0};
51 int64_t operator()(const Arc
& arc
) const {
52 return hash_int64_pair(int64_t(arc
.src
), int64_t(arc
.dst
));
57 explicit Target(uint32_t size
, uint32_t samples
= 0)
65 // preds and succs contain no duplicate elements and self arcs are not allowed
66 std::vector
<TargetId
> preds
;
67 std::vector
<TargetId
> succs
;
71 TargetId
addTarget(uint32_t size
, uint32_t samples
= 0);
72 void setSamples(TargetId id
, uint32_t samples
);
73 uint32_t getSamples(TargetId id
);
74 const Arc
& incArcWeight(TargetId src
, TargetId dst
, double w
= 1.0);
75 void normalizeArcWeights();
78 void printDot(char* fileName
, L getLabel
) const;
80 std::vector
<Target
> targets
;
81 std::unordered_set
<Arc
, ArcHash
> arcs
;
85 Cluster(TargetId id
, const Target
& f
);
87 std::string
toString() const;
88 double density() const;
90 std::vector
<TargetId
> targets
;
93 bool frozen
; // not a candidate for merging
96 /////////////////////////////////////////////////////////////////////////
98 bool compareClustersDensity(const Cluster
& c1
, const Cluster
& c2
);
99 std::vector
<Cluster
> clusterize(const TargetGraph
& cg
);
102 * HFSortPlus - layout of hot functions with iTLB cache optimization
104 std::vector
<Cluster
> hfsortPlus(const TargetGraph
& cg
);
107 * Pettis-Hansen code layout algorithm
108 * reference: K. Pettis and R. C. Hansen, "Profile Guided Code Positioning",
111 std::vector
<Cluster
> pettisAndHansen(const TargetGraph
& cg
);
113 /////////////////////////////////////////////////////////////////////////
116 void TargetGraph::printDot(char* fileName
, L getLabel
) const {
117 FILE* file
= fopen(fileName
, "wt");
120 fprintf(file
, "digraph g {\n");
121 for (size_t f
= 0; f
< targets
.size(); f
++) {
122 if (targets
[f
].samples
== 0) continue;
125 "f%lu [label=\"%s\\nsamples=%u\\nsize=%u\"];\n",
131 for (size_t f
= 0; f
< targets
.size(); f
++) {
132 if (targets
[f
].samples
== 0) continue;
133 for (auto dst
: targets
[f
].succs
) {
134 auto& arc
= *arcs
.find(Arc(f
, dst
));
137 "f%lu -> f%u [label=\"normWgt=%.3lf,weight=%.0lf,callOffset=%.1lf\"];"
141 arc
.normalizedWeight
,
146 fprintf(file
, "}\n");