brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.5 KiB · 022c3f8 Raw
94 lines · c
1//===-- CSPreInliner.h - Profile guided preinliner ---------------- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_TOOLS_LLVM_PROFGEN_PGOINLINEADVISOR_H10#define LLVM_TOOLS_LLVM_PROFGEN_PGOINLINEADVISOR_H11 12#include "ProfiledBinary.h"13#include "llvm/ADT/PriorityQueue.h"14#include "llvm/ProfileData/ProfileCommon.h"15#include "llvm/ProfileData/SampleProf.h"16#include "llvm/Transforms/IPO/ProfiledCallGraph.h"17#include "llvm/Transforms/IPO/SampleContextTracker.h"18 19namespace llvm {20namespace sampleprof {21 22// Inline candidate seen from profile23struct ProfiledInlineCandidate {24  ProfiledInlineCandidate(const FunctionSamples *Samples, uint64_t Count,25                          uint32_t Size)26      : CalleeSamples(Samples), CallsiteCount(Count), SizeCost(Size) {}27  // Context-sensitive function profile for inline candidate28  const FunctionSamples *CalleeSamples;29  // Call site count for an inline candidate30  // TODO: make sure entry count for context profile and call site31  // target count for corresponding call are consistent.32  uint64_t CallsiteCount;33  // Size proxy for function under particular call context.34  uint64_t SizeCost;35};36 37// Inline candidate comparer using call site weight38struct ProfiledCandidateComparer {39  bool operator()(const ProfiledInlineCandidate &LHS,40                  const ProfiledInlineCandidate &RHS) {41    // Always prioritize inlining zero-sized functions as they do not affect the42    // size budget. This could happen when all of the callee's code is gone and43    // only pseudo probes are left.44    if ((LHS.SizeCost == 0 || RHS.SizeCost == 0) &&45        (LHS.SizeCost != RHS.SizeCost))46      return RHS.SizeCost == 0;47 48    if (LHS.CallsiteCount != RHS.CallsiteCount)49      return LHS.CallsiteCount < RHS.CallsiteCount;50 51    if (LHS.SizeCost != RHS.SizeCost)52      return LHS.SizeCost > RHS.SizeCost;53 54    // Tie breaker using GUID so we have stable/deterministic inlining order55    assert(LHS.CalleeSamples && RHS.CalleeSamples &&56           "Expect non-null FunctionSamples");57    return LHS.CalleeSamples->getGUID() < RHS.CalleeSamples->getGUID();58  }59};60 61using ProfiledCandidateQueue =62    PriorityQueue<ProfiledInlineCandidate, std::vector<ProfiledInlineCandidate>,63                  ProfiledCandidateComparer>;64 65// Pre-compilation inliner based on context-sensitive profile.66// The PreInliner estimates inline decision using hotness from profile67// and cost estimation from machine code size. It helps merges context68// profile globally and achieves better post-inine profile quality, which69// otherwise won't be possible for ThinLTO. It also reduce context profile70// size by only keep context that is estimated to be inlined.71class CSPreInliner {72public:73  CSPreInliner(SampleContextTracker &Tracker, ProfiledBinary &Binary,74               ProfileSummary *Summary);75  void run();76 77private:78  bool getInlineCandidates(ProfiledCandidateQueue &CQueue,79                           const FunctionSamples *FCallerContextSamples);80  std::vector<FunctionId> buildTopDownOrder();81  void processFunction(FunctionId Name);82  bool shouldInline(ProfiledInlineCandidate &Candidate);83  uint32_t getFuncSize(const ContextTrieNode *ContextNode);84  bool UseContextCost;85  SampleContextTracker &ContextTracker;86  ProfiledBinary &Binary;87  ProfileSummary *Summary;88};89 90} // end namespace sampleprof91} // end namespace llvm92 93#endif94