27
27
28
28
#include " bolt/Core/HashUtilities.h"
29
29
#include " bolt/Profile/YAMLProfileReader.h"
30
+ #include " llvm/ADT/Bitfields.h"
30
31
#include " llvm/ADT/Hashing.h"
31
32
#include " llvm/Support/CommandLine.h"
32
33
#include " llvm/Transforms/Utils/SampleProfileInference.h"
33
34
34
35
#include < queue>
35
36
37
+ using namespace llvm ;
38
+
36
39
#undef DEBUG_TYPE
37
40
#define DEBUG_TYPE " bolt-prof"
38
41
39
- using namespace llvm ;
40
-
41
42
namespace opts {
42
43
43
44
extern cl::OptionCategory BoltOptCategory;
@@ -141,49 +142,29 @@ namespace bolt {
141
142
// / components are of smaller size (e.g., uint16_t or uint8_t).
142
143
struct BlendedBlockHash {
143
144
private:
144
- static uint64_t combineHashes (uint16_t Hash1, uint16_t Hash2, uint16_t Hash3,
145
- uint16_t Hash4) {
146
- uint64_t Hash = 0 ;
147
-
148
- Hash |= uint64_t (Hash4);
149
- Hash <<= 16 ;
150
-
151
- Hash |= uint64_t (Hash3);
152
- Hash <<= 16 ;
153
-
154
- Hash |= uint64_t (Hash2);
155
- Hash <<= 16 ;
156
-
157
- Hash |= uint64_t (Hash1);
158
-
159
- return Hash;
160
- }
161
-
162
- static void parseHashes (uint64_t Hash, uint16_t &Hash1, uint16_t &Hash2,
163
- uint16_t &Hash3, uint16_t &Hash4) {
164
- Hash1 = Hash & 0xffff ;
165
- Hash >>= 16 ;
166
-
167
- Hash2 = Hash & 0xffff ;
168
- Hash >>= 16 ;
169
-
170
- Hash3 = Hash & 0xffff ;
171
- Hash >>= 16 ;
172
-
173
- Hash4 = Hash & 0xffff ;
174
- Hash >>= 16 ;
175
- }
145
+ using ValueOffset = Bitfield::Element<uint16_t , 0 , 16 >;
146
+ using ValueOpcode = Bitfield::Element<uint16_t , 16 , 16 >;
147
+ using ValueInstr = Bitfield::Element<uint16_t , 32 , 16 >;
148
+ using ValueNeighbor = Bitfield::Element<uint16_t , 48 , 16 >;
176
149
177
150
public:
178
151
explicit BlendedBlockHash () {}
179
152
180
- explicit BlendedBlockHash (uint64_t CombinedHash) {
181
- parseHashes (CombinedHash, Offset, OpcodeHash, InstrHash, NeighborHash);
153
+ explicit BlendedBlockHash (uint64_t Hash) {
154
+ Offset = Bitfield::get<ValueOffset>(Hash);
155
+ OpcodeHash = Bitfield::get<ValueOpcode>(Hash);
156
+ InstrHash = Bitfield::get<ValueInstr>(Hash);
157
+ NeighborHash = Bitfield::get<ValueNeighbor>(Hash);
182
158
}
183
159
184
160
// / Combine the blended hash into uint64_t.
185
161
uint64_t combine () const {
186
- return combineHashes (Offset, OpcodeHash, InstrHash, NeighborHash);
162
+ uint64_t Hash = 0 ;
163
+ Bitfield::set<ValueOffset>(Hash, Offset);
164
+ Bitfield::set<ValueOpcode>(Hash, OpcodeHash);
165
+ Bitfield::set<ValueInstr>(Hash, InstrHash);
166
+ Bitfield::set<ValueNeighbor>(Hash, NeighborHash);
167
+ return Hash;
187
168
}
188
169
189
170
// / Compute a distance between two given blended hashes. The smaller the
@@ -311,6 +292,7 @@ void BinaryFunction::computeBlockHashes() const {
311
292
BB->setHash (BlendedHashes[I].combine ());
312
293
}
313
294
}
295
+
314
296
// / Create a wrapper flow function to use with the profile inference algorithm,
315
297
// / and initialize its jumps and metadata.
316
298
FlowFunction
@@ -319,7 +301,7 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
319
301
320
302
// Add a special "dummy" source so that there is always a unique entry point.
321
303
// Because of the extra source, for all other blocks in FlowFunction it holds
322
- // that Block.Index == BB->getLayoutIndex () + 1
304
+ // that Block.Index == BB->getIndex () + 1
323
305
FlowBlock EntryBlock;
324
306
EntryBlock.Index = 0 ;
325
307
Func.Blocks .push_back (EntryBlock);
@@ -330,7 +312,7 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
330
312
FlowBlock &Block = Func.Blocks .back ();
331
313
Block.Index = Func.Blocks .size () - 1 ;
332
314
(void )BB;
333
- assert (Block.Index == BB->getLayoutIndex () + 1 &&
315
+ assert (Block.Index == BB->getIndex () + 1 &&
334
316
" incorrectly assigned basic block index" );
335
317
}
336
318
@@ -346,8 +328,8 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
346
328
347
329
Func.Jumps .emplace_back ();
348
330
FlowJump &Jump = Func.Jumps .back ();
349
- Jump.Source = SrcBB->getLayoutIndex () + 1 ;
350
- Jump.Target = DstBB->getLayoutIndex () + 1 ;
331
+ Jump.Source = SrcBB->getIndex () + 1 ;
332
+ Jump.Target = DstBB->getIndex () + 1 ;
351
333
InDegree[Jump.Target ]++;
352
334
UniqueSuccs.insert (DstBB);
353
335
}
@@ -359,8 +341,8 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
359
341
360
342
Func.Jumps .emplace_back ();
361
343
FlowJump &Jump = Func.Jumps .back ();
362
- Jump.Source = SrcBB->getLayoutIndex () + 1 ;
363
- Jump.Target = DstBB->getLayoutIndex () + 1 ;
344
+ Jump.Source = SrcBB->getIndex () + 1 ;
345
+ Jump.Target = DstBB->getIndex () + 1 ;
364
346
InDegree[Jump.Target ]++;
365
347
UniqueSuccs.insert (DstBB);
366
348
}
@@ -707,31 +689,33 @@ void assignProfile(BinaryFunction &BF,
707
689
708
690
bool YAMLProfileReader::inferStaleProfile (
709
691
BinaryFunction &BF, const yaml::bolt::BinaryFunctionProfile &YamlBF) {
710
- // Make sure that block indices and hashes are up to date
711
- BF.getLayout ().updateLayoutIndices ();
692
+ LLVM_DEBUG (dbgs () << " BOLT-INFO: applying profile inference for "
693
+ << " \" " << BF.getPrintName () << " \"\n " );
694
+
695
+ // Make sure that block hashes are up to date.
712
696
BF.computeBlockHashes ();
713
697
714
698
const BinaryFunction::BasicBlockOrderType BlockOrder (
715
699
BF.getLayout ().block_begin (), BF.getLayout ().block_end ());
716
700
717
- // Create a wrapper flow function to use with the profile inference algorithm
701
+ // Create a wrapper flow function to use with the profile inference algorithm.
718
702
FlowFunction Func = createFlowFunction (BlockOrder);
719
703
720
704
// Match as many block/jump counts from the stale profile as possible
721
705
matchWeightsByHashes (BF.getBinaryContext (), BlockOrder, YamlBF, Func);
722
706
723
707
// Adjust the flow function by marking unreachable blocks Unlikely so that
724
- // they don't get any counts assigned
708
+ // they don't get any counts assigned.
725
709
preprocessUnreachableBlocks (Func);
726
710
727
- // Check if profile inference can be applied for the instance
711
+ // Check if profile inference can be applied for the instance.
728
712
if (!canApplyInference (Func))
729
713
return false ;
730
714
731
- // Apply the profile inference algorithm
715
+ // Apply the profile inference algorithm.
732
716
applyInference (Func);
733
717
734
- // Collect inferred counts and update function annotations
718
+ // Collect inferred counts and update function annotations.
735
719
assignProfile (BF, BlockOrder, Func);
736
720
737
721
// As of now, we always mark the binary function having "correct" profile.
0 commit comments