2727
2828#include " bolt/Core/HashUtilities.h"
2929#include " bolt/Profile/YAMLProfileReader.h"
30+ #include " llvm/ADT/Bitfields.h"
3031#include " llvm/ADT/Hashing.h"
3132#include " llvm/Support/CommandLine.h"
3233#include " llvm/Transforms/Utils/SampleProfileInference.h"
3334
3435#include < queue>
3536
37+ using namespace llvm ;
38+
3639#undef DEBUG_TYPE
3740#define DEBUG_TYPE " bolt-prof"
3841
39- using namespace llvm ;
40-
4142namespace opts {
4243
4344extern cl::OptionCategory BoltOptCategory;
@@ -141,49 +142,29 @@ namespace bolt {
141142// / components are of smaller size (e.g., uint16_t or uint8_t).
142143struct BlendedBlockHash {
143144private:
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 >;
176149
177150public:
178151 explicit BlendedBlockHash () {}
179152
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);
182158 }
183159
184160 // / Combine the blended hash into uint64_t.
185161 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;
187168 }
188169
189170 // / Compute a distance between two given blended hashes. The smaller the
@@ -311,6 +292,7 @@ void BinaryFunction::computeBlockHashes() const {
311292 BB->setHash (BlendedHashes[I].combine ());
312293 }
313294}
295+
314296// / Create a wrapper flow function to use with the profile inference algorithm,
315297// / and initialize its jumps and metadata.
316298FlowFunction
@@ -319,7 +301,7 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
319301
320302 // Add a special "dummy" source so that there is always a unique entry point.
321303 // 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
323305 FlowBlock EntryBlock;
324306 EntryBlock.Index = 0 ;
325307 Func.Blocks .push_back (EntryBlock);
@@ -330,7 +312,7 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
330312 FlowBlock &Block = Func.Blocks .back ();
331313 Block.Index = Func.Blocks .size () - 1 ;
332314 (void )BB;
333- assert (Block.Index == BB->getLayoutIndex () + 1 &&
315+ assert (Block.Index == BB->getIndex () + 1 &&
334316 " incorrectly assigned basic block index" );
335317 }
336318
@@ -346,8 +328,8 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
346328
347329 Func.Jumps .emplace_back ();
348330 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 ;
351333 InDegree[Jump.Target ]++;
352334 UniqueSuccs.insert (DstBB);
353335 }
@@ -359,8 +341,8 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) {
359341
360342 Func.Jumps .emplace_back ();
361343 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 ;
364346 InDegree[Jump.Target ]++;
365347 UniqueSuccs.insert (DstBB);
366348 }
@@ -707,31 +689,33 @@ void assignProfile(BinaryFunction &BF,
707689
708690bool YAMLProfileReader::inferStaleProfile (
709691 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.
712696 BF.computeBlockHashes ();
713697
714698 const BinaryFunction::BasicBlockOrderType BlockOrder (
715699 BF.getLayout ().block_begin (), BF.getLayout ().block_end ());
716700
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.
718702 FlowFunction Func = createFlowFunction (BlockOrder);
719703
720704 // Match as many block/jump counts from the stale profile as possible
721705 matchWeightsByHashes (BF.getBinaryContext (), BlockOrder, YamlBF, Func);
722706
723707 // 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.
725709 preprocessUnreachableBlocks (Func);
726710
727- // Check if profile inference can be applied for the instance
711+ // Check if profile inference can be applied for the instance.
728712 if (!canApplyInference (Func))
729713 return false ;
730714
731- // Apply the profile inference algorithm
715+ // Apply the profile inference algorithm.
732716 applyInference (Func);
733717
734- // Collect inferred counts and update function annotations
718+ // Collect inferred counts and update function annotations.
735719 assignProfile (BF, BlockOrder, Func);
736720
737721 // As of now, we always mark the binary function having "correct" profile.
0 commit comments