diff --git a/llvm/include/llvm/ProfileData/SampleProf.h b/llvm/include/llvm/ProfileData/SampleProf.h --- a/llvm/include/llvm/ProfileData/SampleProf.h +++ b/llvm/include/llvm/ProfileData/SampleProf.h @@ -1412,7 +1412,7 @@ /// Note: when populating container, make sure to assign the SampleContext to /// the mapped value immediately because the key no longer holds it. class SampleProfileMap - : public HashKeyMap { + : public HashKeyMap { public: // Convenience method because this is being used in many places. Set the // FunctionSamples' context if its newly inserted. @@ -1424,12 +1424,12 @@ } iterator find(const SampleContext &Ctx) { - return HashKeyMap::find( + return HashKeyMap::find( Ctx); } const_iterator find(const SampleContext &Ctx) const { - return HashKeyMap::find( + return HashKeyMap::find( Ctx); } @@ -1449,8 +1449,8 @@ } size_t erase(const SampleContext &Ctx) { - return HashKeyMap:: - erase(Ctx); + return HashKeyMap::erase( + Ctx); } size_t erase(const key_type &Key) { return base_type::erase(Key); } @@ -1562,6 +1562,17 @@ private: static void flattenNestedProfile(SampleProfileMap &OutputProfiles, const FunctionSamples &FS) { + // Use postorder traversal here so that the reference to the newly added + // profile remains valid for duration of the function, even if the output + // profile map relocates. + for (const auto &I : FS.getCallsiteSamples()) { + for (const auto &Callee : I.second) { + const auto &CalleeProfile = Callee.second; + // Recursively convert callee profile. + flattenNestedProfile(OutputProfiles, CalleeProfile); + } + } + // To retain the context, checksum, attributes of the original profile, make // a copy of it if no profile is found. SampleContext &Context = FS.getContext(); @@ -1603,8 +1614,6 @@ ? TotalSamples - CalleeProfile.getTotalSamples() : 0; TotalSamples += CalleeProfile.getHeadSamplesEstimate(); - // Recursively convert callee profile. - flattenNestedProfile(OutputProfiles, CalleeProfile); } } Profile.addTotalSamples(TotalSamples);