diff options
Diffstat (limited to 'bolt')
-rw-r--r-- | bolt/docs/CommandLineArgumentReference.md | 7 | ||||
-rw-r--r-- | bolt/lib/Profile/StaleProfileMatching.cpp | 30 | ||||
-rw-r--r-- | bolt/test/X86/Inputs/blarge_profile_stale_low_matched_blocks.yaml | 57 | ||||
-rw-r--r-- | bolt/test/X86/stale-matching-min-matched-block.test | 10 |
4 files changed, 96 insertions, 8 deletions
diff --git a/bolt/docs/CommandLineArgumentReference.md b/bolt/docs/CommandLineArgumentReference.md index 8887d1f5..49e2265 100644 --- a/bolt/docs/CommandLineArgumentReference.md +++ b/bolt/docs/CommandLineArgumentReference.md @@ -802,6 +802,11 @@ The maximum size of a function to consider for inference. +- `--stale-matching-min-matched-block=<uint>` + + Minimum percent of exact match block for a function to be considered for + profile inference. + - `--stale-threshold=<uint>` Maximum percentage of stale functions to tolerate (default: 100) @@ -1161,4 +1166,4 @@ - `--print-options` - Print non-default options after command line parsing
\ No newline at end of file + Print non-default options after command line parsing diff --git a/bolt/lib/Profile/StaleProfileMatching.cpp b/bolt/lib/Profile/StaleProfileMatching.cpp index 365bc53..c9bcd04 100644 --- a/bolt/lib/Profile/StaleProfileMatching.cpp +++ b/bolt/lib/Profile/StaleProfileMatching.cpp @@ -51,6 +51,12 @@ cl::opt<bool> cl::desc("Infer counts from stale profile data."), cl::init(false), cl::Hidden, cl::cat(BoltOptCategory)); +cl::opt<unsigned> StaleMatchingMinMatchedBlock( + "stale-matching-min-matched-block", + cl::desc("Percentage threshold of matched basic blocks at which stale " + "profile inference is executed."), + cl::init(0), cl::Hidden, cl::cat(BoltOptCategory)); + cl::opt<unsigned> StaleMatchingMaxFuncSize( "stale-matching-max-func-size", cl::desc("The maximum size of a function to consider for inference."), @@ -391,10 +397,9 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) { /// of the basic blocks in the binary, the count is "matched" to the block. /// Similarly, if both the source and the target of a count in the profile are /// matched to a jump in the binary, the count is recorded in CFG. -void matchWeightsByHashes(BinaryContext &BC, - const BinaryFunction::BasicBlockOrderType &BlockOrder, - const yaml::bolt::BinaryFunctionProfile &YamlBF, - FlowFunction &Func) { +size_t matchWeightsByHashes( + BinaryContext &BC, const BinaryFunction::BasicBlockOrderType &BlockOrder, + const yaml::bolt::BinaryFunctionProfile &YamlBF, FlowFunction &Func) { assert(Func.Blocks.size() == BlockOrder.size() + 1); std::vector<FlowBlock *> Blocks; @@ -500,6 +505,8 @@ void matchWeightsByHashes(BinaryContext &BC, Block.HasUnknownWeight = false; Block.Weight = std::max(OutWeight[Block.Index], InWeight[Block.Index]); } + + return MatchedBlocks.size(); } /// The function finds all blocks that are (i) reachable from the Entry block @@ -575,10 +582,16 @@ void preprocessUnreachableBlocks(FlowFunction &Func) { /// Decide if stale profile matching can be applied for a given function. /// Currently we skip inference for (very) large instances and for instances /// having "unexpected" control flow (e.g., having no sink basic blocks). -bool canApplyInference(const FlowFunction &Func) { +bool canApplyInference(const FlowFunction &Func, + const yaml::bolt::BinaryFunctionProfile &YamlBF, + const uint64_t &MatchedBlocks) { if (Func.Blocks.size() > opts::StaleMatchingMaxFuncSize) return false; + if (MatchedBlocks * 100 < + opts::StaleMatchingMinMatchedBlock * YamlBF.Blocks.size()) + return false; + bool HasExitBlocks = llvm::any_of( Func.Blocks, [&](const FlowBlock &Block) { return Block.isExit(); }); if (!HasExitBlocks) @@ -725,18 +738,21 @@ bool YAMLProfileReader::inferStaleProfile( const BinaryFunction::BasicBlockOrderType BlockOrder( BF.getLayout().block_begin(), BF.getLayout().block_end()); + // Tracks the number of matched blocks. + // Create a wrapper flow function to use with the profile inference algorithm. FlowFunction Func = createFlowFunction(BlockOrder); // Match as many block/jump counts from the stale profile as possible - matchWeightsByHashes(BF.getBinaryContext(), BlockOrder, YamlBF, Func); + size_t MatchedBlocks = + matchWeightsByHashes(BF.getBinaryContext(), BlockOrder, YamlBF, Func); // Adjust the flow function by marking unreachable blocks Unlikely so that // they don't get any counts assigned. preprocessUnreachableBlocks(Func); // Check if profile inference can be applied for the instance. - if (!canApplyInference(Func)) + if (!canApplyInference(Func, YamlBF, MatchedBlocks)) return false; // Apply the profile inference algorithm. diff --git a/bolt/test/X86/Inputs/blarge_profile_stale_low_matched_blocks.yaml b/bolt/test/X86/Inputs/blarge_profile_stale_low_matched_blocks.yaml new file mode 100644 index 0000000..785e239 --- /dev/null +++ b/bolt/test/X86/Inputs/blarge_profile_stale_low_matched_blocks.yaml @@ -0,0 +1,57 @@ +--- +header: + profile-version: 1 + binary-name: 'reader-yaml.test.tmp.exe' + binary-build-id: '<unknown>' + profile-flags: [ lbr ] + profile-origin: branch profile reader + profile-events: '' + dfs-order: false + hash-func: xxh3 +functions: + - name: SolveCubic + fid: 6 + hash: 0x0000000000000000 + exec: 151 + nblocks: 18 + blocks: + - bid: 0 + insns: 43 + hash: 0x4600940a609c0000 + exec: 151 + succ: [ { bid: 1, cnt: 151, mis: 2 }, { bid: 7, cnt: 0 } ] + - bid: 1 + insns: 7 + hash: 0x167a1f084f130088 + succ: [ { bid: 13, cnt: 151 }, { bid: 2, cnt: 0 } ] + - bid: 13 + insns: 26 + hash: 0xa8d50000f81902a7 + succ: [ { bid: 3, cnt: 89 }, { bid: 2, cnt: 10 } ] + - bid: 3 + insns: 9 + hash: 0xc516000073dc00a0 + succ: [ { bid: 5, cnt: 151 } ] + - bid: 5 + insns: 9 + hash: 0x6446e1ea500111 + - name: usqrt + fid: 7 + hash: 0x0000000000000000 + exec: 20 + nblocks: 6 + blocks: + - bid: 0 + insns: 4 + hash: 0x0000000000000001 + exec: 20 + succ: [ { bid: 1, cnt: 0 } ] + - bid: 1 + insns: 9 + hash: 0x0000000000000001 + succ: [ { bid: 3, cnt: 320, mis: 171 }, { bid: 2, cnt: 0 } ] + - bid: 3 + insns: 2 + hash: 0x0000000000000001 + succ: [ { bid: 1, cnt: 300, mis: 33 }, { bid: 4, cnt: 20 } ] +... diff --git a/bolt/test/X86/stale-matching-min-matched-block.test b/bolt/test/X86/stale-matching-min-matched-block.test new file mode 100644 index 0000000..383d4d7 --- /dev/null +++ b/bolt/test/X86/stale-matching-min-matched-block.test @@ -0,0 +1,10 @@ +## This script checks the stale-matching-min-matched-block flag. + +RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe + +## Testing "usqrt" +RUN: llvm-bolt %t.exe -o %t.null --b %p/Inputs/blarge_profile_stale_low_matched_blocks.yaml \ +RUN: --infer-stale-profile=1 --stale-matching-min-matched-block=75 \ +RUN: --profile-ignore-hash=1 --debug-only=bolt-prof 2>&1 | FileCheck %s + +CHECK: BOLT-INFO: inferred profile for 1 (50.00% of profiled, 50.00% of stale) functions responsible for 46.31% samples (552 out of 1192) |