annotate llvm/docs/BranchWeightMetadata.rst @ 235:edfff9242030 cbc-llvm13

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 21 Jul 2021 11:30:30 +0900
parents 2e18cbf3894f
children 1f2b6ac9f198
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 ===========================
anatofuz
parents:
diff changeset
2 LLVM Branch Weight Metadata
anatofuz
parents:
diff changeset
3 ===========================
anatofuz
parents:
diff changeset
4
anatofuz
parents:
diff changeset
5 .. contents::
anatofuz
parents:
diff changeset
6 :local:
anatofuz
parents:
diff changeset
7
anatofuz
parents:
diff changeset
8 Introduction
anatofuz
parents:
diff changeset
9 ============
anatofuz
parents:
diff changeset
10
anatofuz
parents:
diff changeset
11 Branch Weight Metadata represents branch weights as its likeliness to be taken
anatofuz
parents:
diff changeset
12 (see :doc:`BlockFrequencyTerminology`). Metadata is assigned to an
anatofuz
parents:
diff changeset
13 ``Instruction`` that is a terminator as a ``MDNode`` of the ``MD_prof`` kind.
anatofuz
parents:
diff changeset
14 The first operator is always a ``MDString`` node with the string
anatofuz
parents:
diff changeset
15 "branch_weights". Number of operators depends on the terminator type.
anatofuz
parents:
diff changeset
16
anatofuz
parents:
diff changeset
17 Branch weights might be fetch from the profiling file, or generated based on
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
18 `__builtin_expect`_ and `__builtin_expect_with_probability`_ instruction.
150
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 All weights are represented as an unsigned 32-bit values, where higher value
anatofuz
parents:
diff changeset
21 indicates greater chance to be taken.
anatofuz
parents:
diff changeset
22
anatofuz
parents:
diff changeset
23 Supported Instructions
anatofuz
parents:
diff changeset
24 ======================
anatofuz
parents:
diff changeset
25
anatofuz
parents:
diff changeset
26 ``BranchInst``
anatofuz
parents:
diff changeset
27 ^^^^^^^^^^^^^^
anatofuz
parents:
diff changeset
28
anatofuz
parents:
diff changeset
29 Metadata is only assigned to the conditional branches. There are two extra
anatofuz
parents:
diff changeset
30 operands for the true and the false branch.
anatofuz
parents:
diff changeset
31
anatofuz
parents:
diff changeset
32 .. code-block:: none
anatofuz
parents:
diff changeset
33
anatofuz
parents:
diff changeset
34 !0 = metadata !{
anatofuz
parents:
diff changeset
35 metadata !"branch_weights",
anatofuz
parents:
diff changeset
36 i32 <TRUE_BRANCH_WEIGHT>,
anatofuz
parents:
diff changeset
37 i32 <FALSE_BRANCH_WEIGHT>
anatofuz
parents:
diff changeset
38 }
anatofuz
parents:
diff changeset
39
anatofuz
parents:
diff changeset
40 ``SwitchInst``
anatofuz
parents:
diff changeset
41 ^^^^^^^^^^^^^^
anatofuz
parents:
diff changeset
42
anatofuz
parents:
diff changeset
43 Branch weights are assigned to every case (including the ``default`` case which
anatofuz
parents:
diff changeset
44 is always case #0).
anatofuz
parents:
diff changeset
45
anatofuz
parents:
diff changeset
46 .. code-block:: none
anatofuz
parents:
diff changeset
47
anatofuz
parents:
diff changeset
48 !0 = metadata !{
anatofuz
parents:
diff changeset
49 metadata !"branch_weights",
anatofuz
parents:
diff changeset
50 i32 <DEFAULT_BRANCH_WEIGHT>
anatofuz
parents:
diff changeset
51 [ , i32 <CASE_BRANCH_WEIGHT> ... ]
anatofuz
parents:
diff changeset
52 }
anatofuz
parents:
diff changeset
53
anatofuz
parents:
diff changeset
54 ``IndirectBrInst``
anatofuz
parents:
diff changeset
55 ^^^^^^^^^^^^^^^^^^
anatofuz
parents:
diff changeset
56
anatofuz
parents:
diff changeset
57 Branch weights are assigned to every destination.
anatofuz
parents:
diff changeset
58
anatofuz
parents:
diff changeset
59 .. code-block:: none
anatofuz
parents:
diff changeset
60
anatofuz
parents:
diff changeset
61 !0 = metadata !{
anatofuz
parents:
diff changeset
62 metadata !"branch_weights",
anatofuz
parents:
diff changeset
63 i32 <LABEL_BRANCH_WEIGHT>
anatofuz
parents:
diff changeset
64 [ , i32 <LABEL_BRANCH_WEIGHT> ... ]
anatofuz
parents:
diff changeset
65 }
anatofuz
parents:
diff changeset
66
anatofuz
parents:
diff changeset
67 ``CallInst``
anatofuz
parents:
diff changeset
68 ^^^^^^^^^^^^^^^^^^
anatofuz
parents:
diff changeset
69
anatofuz
parents:
diff changeset
70 Calls may have branch weight metadata, containing the execution count of
anatofuz
parents:
diff changeset
71 the call. It is currently used in SamplePGO mode only, to augment the
anatofuz
parents:
diff changeset
72 block and entry counts which may not be accurate with sampling.
anatofuz
parents:
diff changeset
73
anatofuz
parents:
diff changeset
74 .. code-block:: none
anatofuz
parents:
diff changeset
75
anatofuz
parents:
diff changeset
76 !0 = metadata !{
anatofuz
parents:
diff changeset
77 metadata !"branch_weights",
anatofuz
parents:
diff changeset
78 i32 <CALL_BRANCH_WEIGHT>
anatofuz
parents:
diff changeset
79 }
anatofuz
parents:
diff changeset
80
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
81 ``InvokeInst``
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
82 ^^^^^^^^^^^^^^^^^^
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
83
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
84 Invoke instruction may have branch weight metadata with one or two weights.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
85 The second weight is optional and corresponds to the unwind branch.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
86 If only one weight is set then it contains the execution count of the call
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
87 and used in SamplePGO mode only as described for the call instruction. If both
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
88 weights are specified then the second weight contains count of unwind branch
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
89 taken and the first weights contains the execution count of the call minus
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
90 the count of unwind branch taken. Both weights specified are used to calculate
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
91 BranchProbability as for BranchInst and for SamplePGO the sum of both weights
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
92 is used.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
93
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
94 .. code-block:: none
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
95
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
96 !0 = metadata !{
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
97 metadata !"branch_weights",
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
98 i32 <INVOKE_NORMAL_WEIGHT>
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
99 [ , i32 <INVOKE_UNWIND_WEIGHT> ]
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
100 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
101
150
anatofuz
parents:
diff changeset
102 Other
anatofuz
parents:
diff changeset
103 ^^^^^
anatofuz
parents:
diff changeset
104
anatofuz
parents:
diff changeset
105 Other terminator instructions are not allowed to contain Branch Weight Metadata.
anatofuz
parents:
diff changeset
106
anatofuz
parents:
diff changeset
107 .. _\__builtin_expect:
anatofuz
parents:
diff changeset
108
anatofuz
parents:
diff changeset
109 Built-in ``expect`` Instructions
anatofuz
parents:
diff changeset
110 ================================
anatofuz
parents:
diff changeset
111
anatofuz
parents:
diff changeset
112 ``__builtin_expect(long exp, long c)`` instruction provides branch prediction
anatofuz
parents:
diff changeset
113 information. The return value is the value of ``exp``.
anatofuz
parents:
diff changeset
114
anatofuz
parents:
diff changeset
115 It is especially useful in conditional statements. Currently Clang supports two
anatofuz
parents:
diff changeset
116 conditional statements:
anatofuz
parents:
diff changeset
117
anatofuz
parents:
diff changeset
118 ``if`` statement
anatofuz
parents:
diff changeset
119 ^^^^^^^^^^^^^^^^
anatofuz
parents:
diff changeset
120
anatofuz
parents:
diff changeset
121 The ``exp`` parameter is the condition. The ``c`` parameter is the expected
anatofuz
parents:
diff changeset
122 comparison value. If it is equal to 1 (true), the condition is likely to be
anatofuz
parents:
diff changeset
123 true, in other case condition is likely to be false. For example:
anatofuz
parents:
diff changeset
124
anatofuz
parents:
diff changeset
125 .. code-block:: c++
anatofuz
parents:
diff changeset
126
anatofuz
parents:
diff changeset
127 if (__builtin_expect(x > 0, 1)) {
anatofuz
parents:
diff changeset
128 // This block is likely to be taken.
anatofuz
parents:
diff changeset
129 }
anatofuz
parents:
diff changeset
130
anatofuz
parents:
diff changeset
131 ``switch`` statement
anatofuz
parents:
diff changeset
132 ^^^^^^^^^^^^^^^^^^^^
anatofuz
parents:
diff changeset
133
anatofuz
parents:
diff changeset
134 The ``exp`` parameter is the value. The ``c`` parameter is the expected
anatofuz
parents:
diff changeset
135 value. If the expected value doesn't show on the cases list, the ``default``
anatofuz
parents:
diff changeset
136 case is assumed to be likely taken.
anatofuz
parents:
diff changeset
137
anatofuz
parents:
diff changeset
138 .. code-block:: c++
anatofuz
parents:
diff changeset
139
anatofuz
parents:
diff changeset
140 switch (__builtin_expect(x, 5)) {
anatofuz
parents:
diff changeset
141 default: break;
anatofuz
parents:
diff changeset
142 case 0: // ...
anatofuz
parents:
diff changeset
143 case 3: // ...
anatofuz
parents:
diff changeset
144 case 5: // This case is likely to be taken.
anatofuz
parents:
diff changeset
145 }
anatofuz
parents:
diff changeset
146
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
147 .. _\__builtin_expect_with_probability:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
148
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
149 Built-in ``expect.with.probability`` Instruction
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
150 ================================================
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
151
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
152 ``__builtin_expect_with_probability(long exp, long c, double probability)`` has
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
153 the same semantics as ``__builtin_expect``, but the caller provides the
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
154 probability that ``exp == c``. The last argument ``probability`` must be
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
155 constant floating-point expression and be in the range [0.0, 1.0] inclusive.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
156 The usage is also similar as ``__builtin_expect``, for example:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
157
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
158 ``if`` statement
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
159 ^^^^^^^^^^^^^^^^
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
160
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
161 If the expect comparison value ``c`` is equal to 1(true), and probability
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
162 value ``probability`` is set to 0.8, that means the probability of condition
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
163 to be true is 80% while that of false is 20%.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
164
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
165 .. code-block:: c++
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
166
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
167 if (__builtin_expect_with_probability(x > 0, 1, 0.8)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
168 // This block is likely to be taken with probability 80%.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
169 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
170
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
171 ``switch`` statement
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
172 ^^^^^^^^^^^^^^^^^^^^
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
173
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
174 This is basically the same as ``switch`` statement in ``__builtin_expect``.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
175 The probability that ``exp`` is equal to the expect value is given in
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
176 the third argument ``probability``, while the probability of other value is
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
177 the average of remaining probability(``1.0 - probability``). For example:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
178
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
179 .. code-block:: c++
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
180
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
181 switch (__builtin_expect_with_probability(x, 5, 0.7)) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
182 default: break; // Take this case with probability 10%
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
183 case 0: break; // Take this case with probability 10%
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
184 case 3: break; // Take this case with probability 10%
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
185 case 5: break; // This case is likely to be taken with probability 70%
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
186 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
187
150
anatofuz
parents:
diff changeset
188 CFG Modifications
anatofuz
parents:
diff changeset
189 =================
anatofuz
parents:
diff changeset
190
anatofuz
parents:
diff changeset
191 Branch Weight Metatada is not proof against CFG changes. If terminator operands'
anatofuz
parents:
diff changeset
192 are changed some action should be taken. In other case some misoptimizations may
anatofuz
parents:
diff changeset
193 occur due to incorrect branch prediction information.
anatofuz
parents:
diff changeset
194
anatofuz
parents:
diff changeset
195 Function Entry Counts
anatofuz
parents:
diff changeset
196 =====================
anatofuz
parents:
diff changeset
197
anatofuz
parents:
diff changeset
198 To allow comparing different functions during inter-procedural analysis and
anatofuz
parents:
diff changeset
199 optimization, ``MD_prof`` nodes can also be assigned to a function definition.
anatofuz
parents:
diff changeset
200 The first operand is a string indicating the name of the associated counter.
anatofuz
parents:
diff changeset
201
anatofuz
parents:
diff changeset
202 Currently, one counter is supported: "function_entry_count". The second operand
anatofuz
parents:
diff changeset
203 is a 64-bit counter that indicates the number of times that this function was
anatofuz
parents:
diff changeset
204 invoked (in the case of instrumentation-based profiles). In the case of
anatofuz
parents:
diff changeset
205 sampling-based profiles, this operand is an approximation of how many times
anatofuz
parents:
diff changeset
206 the function was invoked.
anatofuz
parents:
diff changeset
207
anatofuz
parents:
diff changeset
208 For example, in the code below, the instrumentation for function foo()
anatofuz
parents:
diff changeset
209 indicates that it was called 2,590 times at runtime.
anatofuz
parents:
diff changeset
210
anatofuz
parents:
diff changeset
211 .. code-block:: llvm
anatofuz
parents:
diff changeset
212
anatofuz
parents:
diff changeset
213 define i32 @foo() !prof !1 {
anatofuz
parents:
diff changeset
214 ret i32 0
anatofuz
parents:
diff changeset
215 }
anatofuz
parents:
diff changeset
216 !1 = !{!"function_entry_count", i64 2590}
anatofuz
parents:
diff changeset
217
anatofuz
parents:
diff changeset
218 If "function_entry_count" has more than 2 operands, the later operands are
anatofuz
parents:
diff changeset
219 the GUID of the functions that needs to be imported by ThinLTO. This is only
anatofuz
parents:
diff changeset
220 set by sampling based profile. It is needed because the sampling based profile
anatofuz
parents:
diff changeset
221 was collected on a binary that had already imported and inlined these functions,
anatofuz
parents:
diff changeset
222 and we need to ensure the IR matches in the ThinLTO backends for profile
anatofuz
parents:
diff changeset
223 annotation. The reason why we cannot annotate this on the callsite is that it
anatofuz
parents:
diff changeset
224 can only goes down 1 level in the call chain. For the cases where
anatofuz
parents:
diff changeset
225 foo_in_a_cc()->bar_in_b_cc()->baz_in_c_cc(), we will need to go down 2 levels
anatofuz
parents:
diff changeset
226 in the call chain to import both bar_in_b_cc and baz_in_c_cc.