-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Deprecated][SampleFDO] Stale profile call-graph matching #92151
Changes from 7 commits
2629a77
f1e659d
6db01bc
b32bab8
6b90869
54bde5a
b86f224
db95b81
82db8bd
a28aa1b
091ab34
06ce1d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ namespace llvm { | |
|
||
using AnchorList = std::vector<std::pair<LineLocation, FunctionId>>; | ||
using AnchorMap = std::map<LineLocation, FunctionId>; | ||
using FunctionMap = HashKeyMap<std::unordered_map, FunctionId, Function *>; | ||
|
||
// Sample profile matching - fuzzy match. | ||
class SampleProfileMatcher { | ||
|
@@ -34,7 +35,7 @@ class SampleProfileMatcher { | |
// in the profile. | ||
StringMap<LocToLocMap> FuncMappings; | ||
|
||
// Match state for an anchor/callsite. | ||
// Match state for an anchor/callsite or function. | ||
enum class MatchState { | ||
Unknown = 0, | ||
// Initial match between input profile and current IR. | ||
|
@@ -58,6 +59,20 @@ class SampleProfileMatcher { | |
StringMap<std::unordered_map<LineLocation, MatchState, LineLocationHash>> | ||
FuncCallsiteMatchStates; | ||
|
||
struct FuncProfNameMapHash { | ||
uint64_t | ||
operator()(const std::pair<const Function *, FunctionId> &P) const { | ||
return hash_combine(P.first, P.second); | ||
} | ||
}; | ||
std::unordered_map<std::pair<const Function *, FunctionId>, bool, | ||
FuncProfNameMapHash> | ||
FunctionProfileNameMap; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I was suggesting
because symmetric naming helps readability. I saw you changed the other one, but not this one. |
||
|
||
FunctionMap *SymbolMap; | ||
wlei-llvm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
std::shared_ptr<ProfileSymbolList> PSL; | ||
|
||
// Profile mismatch statstics: | ||
uint64_t TotalProfiledFunc = 0; | ||
// Num of checksum-mismatched function. | ||
|
@@ -80,26 +95,37 @@ class SampleProfileMatcher { | |
public: | ||
SampleProfileMatcher(Module &M, SampleProfileReader &Reader, | ||
const PseudoProbeManager *ProbeManager, | ||
ThinOrFullLTOPhase LTOPhase) | ||
: M(M), Reader(Reader), ProbeManager(ProbeManager), LTOPhase(LTOPhase){}; | ||
void runOnModule(); | ||
ThinOrFullLTOPhase LTOPhase, | ||
std::shared_ptr<ProfileSymbolList> PSL) | ||
: M(M), Reader(Reader), ProbeManager(ProbeManager), LTOPhase(LTOPhase), | ||
PSL(PSL) {}; | ||
void runOnModule(FunctionMap &SymbolMap); | ||
void clearMatchingData() { | ||
// Do not clear FuncMappings, it stores IRLoc to ProfLoc remappings which | ||
// will be used for sample loader. | ||
FuncCallsiteMatchStates.clear(); | ||
} | ||
|
||
private: | ||
FunctionSamples *getFlattenedSamplesFor(const Function &F) { | ||
StringRef CanonFName = FunctionSamples::getCanonicalFnName(F); | ||
auto It = FlattenedProfiles.find(FunctionId(CanonFName)); | ||
FunctionSamples *getFlattenedSamplesFor(const FunctionId &Fname) { | ||
auto It = FlattenedProfiles.find(Fname); | ||
if (It != FlattenedProfiles.end()) | ||
return &It->second; | ||
return nullptr; | ||
} | ||
FunctionSamples *getFlattenedSamplesFor(const Function &F) { | ||
StringRef CanonFName = FunctionSamples::getCanonicalFnName(F); | ||
return getFlattenedSamplesFor(FunctionId(CanonFName)); | ||
} | ||
void getFilteredAnchorList(const AnchorMap &IRAnchors, | ||
const AnchorMap &ProfileAnchors, | ||
AnchorList &FilteredIRAnchorsList, | ||
AnchorList &FilteredProfileAnchorList); | ||
void runCFGMatching(Function &F); | ||
void runOnFunction(Function &F); | ||
void findIRAnchors(const Function &F, AnchorMap &IRAnchors); | ||
void findProfileAnchors(const FunctionSamples &FS, AnchorMap &ProfileAnchors); | ||
void findIRAnchors(const Function &F, AnchorMap &IRAnchors) const; | ||
void findProfileAnchors(const FunctionSamples &FS, | ||
AnchorMap &ProfileAnchors) const; | ||
// Record the callsite match states for profile staleness report, the result | ||
// is saved in FuncCallsiteMatchStates. | ||
void recordCallsiteMatchStates(const Function &F, const AnchorMap &IRAnchors, | ||
|
@@ -160,6 +186,48 @@ class SampleProfileMatcher { | |
void runStaleProfileMatching(const Function &F, const AnchorMap &IRAnchors, | ||
const AnchorMap &ProfileAnchors, | ||
LocToLocMap &IRToProfileLocationMap); | ||
/// Find the existing or new matched function using the profile name. | ||
/// | ||
/// \returns The function and a match state. | ||
std::pair<Function *, MatchState> | ||
findFunction(const FunctionId &ProfFunc, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe more clear if we name it |
||
const FunctionMap &OldProfToNewSymbolMap) const; | ||
/// Find the function using the profile name. If the function is not found but | ||
/// the \p NewIRCallees is provided, try to match the function profile with | ||
/// all functions in \p NewIRCallees and return the matched function. | ||
/// | ||
/// \param ProfFunc The function profile name. | ||
/// \param OldProfToNewSymbolMap The map from old profile name to new symbol. | ||
/// \param NewIRCallees The new candidate callees in the same scope to match. | ||
/// | ||
/// \returns The matched function and a match state. | ||
std::pair<Function *, MatchState> | ||
findOrMatchFunction(const FunctionId &ProfFunc, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. similarly |
||
FunctionMap &OldProfToNewSymbolMap, | ||
const std::vector<Function *> &NewIRCallees); | ||
std::vector<FunctionSamples *> sortFuncProfiles(SampleProfileMap &ProfileMap); | ||
void findNewIRCallees(Function &Caller, | ||
const StringMap<Function *> &NewIRFunctions, | ||
std::vector<Function *> &NewIRCallees); | ||
bool functionMatchesProfileHelper(const Function &IRFunc, | ||
const FunctionId &ProfFunc); | ||
/// Determine if the function matches profile by computing a similarity ratio | ||
/// between two callsite anchors extracted from function and profile. If it's | ||
/// above the threshold, the function matches the profile. | ||
/// | ||
/// \returns True if the function matches profile. | ||
bool functionMatchesProfile(const Function &IRFunc, | ||
wlei-llvm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const FunctionId &ProfFunc); | ||
void matchProfileForNewFunctions(const StringMap<Function *> &NewIRFunctions, | ||
FunctionSamples &FS, | ||
FunctionMap &OldProfToNewSymbolMap); | ||
/// Find functions that don't show in the profile or profile symbol list, | ||
/// which are supposed to be new functions. We use them as the targets for | ||
/// renaming matching. | ||
/// | ||
/// \param NewIRFunctions The map from function name to the IR function. | ||
void findNewIRFunctions(StringMap<Function *> &NewIRFunctions); | ||
void runCallGraphMatching(); | ||
void reportOrPersistProfileStats(); | ||
}; | ||
} // end namespace llvm | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This type is used elsewhere too (
SampleProfileLoader
). Either use the type alias everywhere or spell out the full type everywhere. Maybe it's better to just spell out the type name to be explicit?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to spell out to be explicit.