diff options
author | shawbyoung <shawbyoung@gmail.com> | 2024-06-13 16:51:12 -0700 |
---|---|---|
committer | shawbyoung <shawbyoung@gmail.com> | 2024-06-13 16:51:12 -0700 |
commit | 9cd7c8e4f939464ef1a1d8f161a2645a80b36684 (patch) | |
tree | f215d9a099de3555335a704a2efbb2b154d66e7b | |
parent | f3b212cd123398b563da3a9a69c2903d8b355d19 (diff) | |
parent | e83a03722cbd643f3b56869a9f21b65c6113586f (diff) | |
download | llvm-users/shawbyoung/spr/using-matched-block-counts-to-measure-discrepancy.zip llvm-users/shawbyoung/spr/using-matched-block-counts-to-measure-discrepancy.tar.gz llvm-users/shawbyoung/spr/using-matched-block-counts-to-measure-discrepancy.tar.bz2 |
[𝘀𝗽𝗿] initial versionusers/shawbyoung/spr/using-matched-block-counts-to-measure-discrepancy
Created using spr 1.3.4
-rw-r--r-- | bolt/lib/Profile/StaleProfileMatching.cpp | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/bolt/lib/Profile/StaleProfileMatching.cpp b/bolt/lib/Profile/StaleProfileMatching.cpp index 365bc53..cbd98f4 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> MatchedProfileThreshold( + "matched-profile-threshold", + cl::desc("Percentage threshold of matched basic blocks at which stale " + "profile inference is executed."), + cl::init(50), 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."), @@ -180,6 +186,17 @@ public: uint8_t SuccHash{0}; }; +/// A data object containing function matching information. +struct FunctionMatchingData { +public: + /// The number of blocks matched exactly. + uint64_t MatchedExactBlocks{0}; + /// The number of blocks matched loosely. + uint64_t MatchedLooseBlocks{0}; + /// The number of execution counts matched. + uint64_t MatchedExecCounts{0}; +}; + /// The object is used to identify and match basic blocks in a BinaryFunction /// given their hashes computed on a binary built from several revisions behind /// release. @@ -394,7 +411,8 @@ createFlowFunction(const BinaryFunction::BasicBlockOrderType &BlockOrder) { void matchWeightsByHashes(BinaryContext &BC, const BinaryFunction::BasicBlockOrderType &BlockOrder, const yaml::bolt::BinaryFunctionProfile &YamlBF, - FlowFunction &Func) { + FlowFunction &Func, + FunctionMatchingData &FuncMatchingData) { assert(Func.Blocks.size() == BlockOrder.size() + 1); std::vector<FlowBlock *> Blocks; @@ -434,8 +452,11 @@ void matchWeightsByHashes(BinaryContext &BC, if (Matcher.isHighConfidenceMatch(BinHash, YamlHash)) { ++BC.Stats.NumMatchedBlocks; BC.Stats.MatchedSampleCount += YamlBB.ExecCount; + FuncMatchingData.MatchedExecCounts += YamlBB.ExecCount; + FuncMatchingData.MatchedExactBlocks += 1; LLVM_DEBUG(dbgs() << " exact match\n"); } else { + FuncMatchingData.MatchedLooseBlocks += 1; LLVM_DEBUG(dbgs() << " loose match\n"); } if (YamlBB.NumInstructions == BB->size()) @@ -575,10 +596,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 FunctionMatchingData &FuncMatchingData) { if (Func.Blocks.size() > opts::StaleMatchingMaxFuncSize) return false; + if ((double)FuncMatchingData.MatchedExactBlocks / YamlBF.Blocks.size() >= + opts::MatchedProfileThreshold / 100.0) + return false; + bool HasExitBlocks = llvm::any_of( Func.Blocks, [&](const FlowBlock &Block) { return Block.isExit(); }); if (!HasExitBlocks) @@ -725,18 +752,22 @@ bool YAMLProfileReader::inferStaleProfile( const BinaryFunction::BasicBlockOrderType BlockOrder( BF.getLayout().block_begin(), BF.getLayout().block_end()); + // Create a containter for function matching data. + FunctionMatchingData FuncMatchingData; + // 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); + matchWeightsByHashes(BF.getBinaryContext(), BlockOrder, YamlBF, Func, + FuncMatchingData); // 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, FuncMatchingData)) return false; // Apply the profile inference algorithm. |