1651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===--- CodeGenPGO.h - PGO Instrumentation for LLVM CodeGen ----*- C++ -*-===//
2651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//
3651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//                     The LLVM Compiler Infrastructure
4651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//
5651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// This file is distributed under the University of Illinois Open Source
6651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// License. See LICENSE.TXT for details.
7651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//
8651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===----------------------------------------------------------------------===//
9651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//
10651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Instrumentation-based profile-guided optimization
11651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//
12651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines//===----------------------------------------------------------------------===//
13651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
14651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#ifndef CLANG_CODEGEN_CODEGENPGO_H
15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#define CLANG_CODEGEN_CODEGENPGO_H
16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "CGBuilder.h"
18651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "CodeGenModule.h"
19651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "CodeGenTypes.h"
20651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/Frontend/CodeGenOptions.h"
21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/ADT/StringMap.h"
22651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/Support/MemoryBuffer.h"
23651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <memory>
24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
25651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace clang {
26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace CodeGen {
27651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass RegionCounter;
28651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
29651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Per-function PGO state. This class should generally not be used directly,
30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// but instead through the CodeGenFunction and RegionCounter types.
31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass CodeGenPGO {
32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesprivate:
33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CodeGenModule &CGM;
34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<std::string> PrefixedFuncName;
35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  StringRef RawFuncName;
36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm::GlobalValue::LinkageTypes VarLinkage;
37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned NumRegionCounters;
39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  uint64_t FunctionHash;
40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm::GlobalVariable *RegionCounters;
41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<llvm::DenseMap<const Stmt *, unsigned>> RegionCounterMap;
42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<llvm::DenseMap<const Stmt *, uint64_t>> StmtCountMap;
43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<std::vector<uint64_t>> RegionCounts;
44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  uint64_t CurrentRegionCount;
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic:
47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CodeGenPGO(CodeGenModule &CGM)
486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      : CGM(CGM), NumRegionCounters(0), FunctionHash(0),
496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        RegionCounters(nullptr), CurrentRegionCount(0) {}
50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Whether or not we have PGO region data for the current function. This is
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// false both when we have no data at all and when our data has been
53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// discarded.
546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool haveRegionCounts() const { return RegionCounts != nullptr; }
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Get the string used to identify this function in the profile data.
57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// For functions with local linkage, this includes the main file name.
58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  StringRef getFuncName() const { return StringRef(*PrefixedFuncName); }
59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::string getFuncVarName(StringRef VarName) const {
60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return ("__llvm_profile_" + VarName + "_" + RawFuncName).str();
61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Return the counter value of the current region.
64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  uint64_t getCurrentRegionCount() const { return CurrentRegionCount; }
65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Set the counter value for the current region. This is used to keep track
67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// of changes to the most recent counter from control flow and non-local
68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// exits.
69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void setCurrentRegionCount(uint64_t Count) { CurrentRegionCount = Count; }
70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Indicate that the current region is never reached, and thus should have a
72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// counter value of zero. This is important so that subsequent regions can
73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// correctly track their parent counts.
74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void setCurrentRegionUnreachable() { setCurrentRegionCount(0); }
75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Check if an execution count is known for a given statement. If so, return
77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// true and put the value in Count; else return false.
78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool getStmtCount(const Stmt *S, uint64_t &Count) {
79651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!StmtCountMap)
80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return false;
81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    llvm::DenseMap<const Stmt*, uint64_t>::const_iterator
82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      I = StmtCountMap->find(S);
83651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (I == StmtCountMap->end())
84651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return false;
85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Count = I->second;
86651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return true;
87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// If the execution count for the current statement is known, record that
90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// as the current count.
91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void setCurrentStmt(const Stmt *S) {
92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    uint64_t Count;
93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (getStmtCount(S, Count))
94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      setCurrentRegionCount(Count);
95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Calculate branch weights appropriate for PGO data
98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm::MDNode *createBranchWeights(uint64_t TrueCount, uint64_t FalseCount);
99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm::MDNode *createBranchWeights(ArrayRef<uint64_t> Weights);
100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm::MDNode *createLoopWeights(const Stmt *Cond, RegionCounter &Cnt);
101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Assign counters to regions and configure them for PGO of a given
103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// function. Does nothing if instrumentation is not enabled and either
104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// generates global variables or associates PGO data with each of the
105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// counters depending on whether we are generating or using instrumentation.
106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void assignRegionCounters(const Decl *D, llvm::Function *Fn);
107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Emit static data structures for instrumentation data.
108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void emitInstrumentationData();
109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Clean up region counter state. Must be called if assignRegionCounters is
110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// used.
111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void destroyRegionCounters();
112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Emit static initialization code, if any.
113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  static llvm::Function *emitInitialization(CodeGenModule &CGM);
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesprivate:
116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void setFuncName(llvm::Function *Fn);
117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void mapRegionCounters(const Decl *D);
118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void computeRegionCounts(const Decl *D);
1196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                               llvm::Function *Fn);
121ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  void loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
122ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                        bool IsInMainFile);
123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void emitCounterVariables();
124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  llvm::GlobalVariable *buildDataVar();
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Emit code to increment the counter at the given index
127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter);
128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Return the region counter for the given statement. This should only be
130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// called on statements that have a dedicated counter.
131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned getRegionCounter(const Stmt *S) {
1326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (!RegionCounterMap)
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return 0;
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return (*RegionCounterMap)[S];
135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Return the region count for the counter at the given index.
138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  uint64_t getRegionCount(unsigned Counter) {
139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!haveRegionCounts())
140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return 0;
141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return (*RegionCounts)[Counter];
142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  friend class RegionCounter;
145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// A counter for a particular region. This is the primary interface through
148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// which clients manage PGO counters and their values.
149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass RegionCounter {
150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CodeGenPGO *PGO;
151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned Counter;
152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  uint64_t Count;
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  uint64_t ParentCount;
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  uint64_t RegionCount;
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int64_t Adjust;
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  RegionCounter(CodeGenPGO &PGO, unsigned CounterIndex)
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    : PGO(&PGO), Counter(CounterIndex), Count(PGO.getRegionCount(Counter)),
159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ParentCount(PGO.getCurrentRegionCount()), Adjust(0) {}
160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic:
162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  RegionCounter(CodeGenPGO &PGO, const Stmt *S)
163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    : PGO(&PGO), Counter(PGO.getRegionCounter(S)),
164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Count(PGO.getRegionCount(Counter)),
165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ParentCount(PGO.getCurrentRegionCount()), Adjust(0) {}
166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Get the value of the counter. In most cases this is the number of times
168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// the region of the counter was entered, but for switch labels it's the
169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// number of direct jumps to that label.
170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  uint64_t getCount() const { return Count; }
171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Get the value of the counter with adjustments applied. Adjustments occur
173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// when control enters or leaves the region abnormally; i.e., if there is a
174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// jump to a label within the region, or if the function can return from
175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// within the region. The adjusted count, then, is the value of the counter
176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// at the end of the region.
177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  uint64_t getAdjustedCount() const {
178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return Count + Adjust;
179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Get the value of the counter in this region's parent, i.e., the region
182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// that was active when this region began. This is useful for deriving
183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// counts in implicitly counted regions, like the false case of a condition
184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// or the normal exits of a loop.
185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  uint64_t getParentCount() const { return ParentCount; }
186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Activate the counter by emitting an increment and starting to track
188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// adjustments. If AddIncomingFallThrough is true, the current region count
189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// will be added to the counter for the purposes of tracking the region.
190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void beginRegion(CGBuilderTy &Builder, bool AddIncomingFallThrough=false) {
191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    beginRegion(AddIncomingFallThrough);
192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PGO->emitCounterIncrement(Builder, Counter);
193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void beginRegion(bool AddIncomingFallThrough=false) {
195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    RegionCount = Count;
196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (AddIncomingFallThrough)
197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      RegionCount += PGO->getCurrentRegionCount();
198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PGO->setCurrentRegionCount(RegionCount);
199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// For counters on boolean branches, begins tracking adjustments for the
202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// uncounted path.
203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void beginElseRegion() {
204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    RegionCount = ParentCount - Count;
205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PGO->setCurrentRegionCount(RegionCount);
206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Reset the current region count.
209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void setCurrentRegionCount(uint64_t CurrentCount) {
210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    RegionCount = CurrentCount;
211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PGO->setCurrentRegionCount(RegionCount);
212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Adjust for non-local control flow after emitting a subexpression or
215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// substatement. This must be called to account for constructs such as gotos,
216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// labels, and returns, so that we can ensure that our region's count is
217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// correct in the code that follows.
218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void adjustForControlFlow() {
219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Adjust += PGO->getCurrentRegionCount() - RegionCount;
220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // Reset the region count in case this is called again later.
221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    RegionCount = PGO->getCurrentRegionCount();
222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// Commit all adjustments to the current region. If the region is a loop,
225651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// the LoopAdjust value should be the count of all the breaks and continues
226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// from the loop, to compensate for those counts being deducted from the
227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// adjustments for the body of the loop.
228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void applyAdjustmentsToRegion(uint64_t LoopAdjust) {
229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    PGO->setCurrentRegionCount(ParentCount + Adjust + LoopAdjust);
230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}  // end namespace CodeGen
234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}  // end namespace clang
235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif
237