brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.7 KiB · 1944b64 Raw
157 lines · c
1//===--- CodeGenPGO.h - PGO Instrumentation for LLVM CodeGen ----*- 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// Instrumentation-based profile-guided optimization10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENPGO_H14#define LLVM_CLANG_LIB_CODEGEN_CODEGENPGO_H15 16#include "CGBuilder.h"17#include "CodeGenModule.h"18#include "CodeGenTypes.h"19#include "MCDCState.h"20#include "llvm/ProfileData/InstrProfReader.h"21#include <array>22#include <memory>23#include <optional>24 25namespace clang {26namespace CodeGen {27 28/// Per-function PGO state.29class CodeGenPGO {30private:31  CodeGenModule &CGM;32  std::string FuncName;33  llvm::GlobalVariable *FuncNameVar;34 35  std::array <unsigned, llvm::IPVK_Last + 1> NumValueSites;36  unsigned NumRegionCounters;37  uint64_t FunctionHash;38  std::unique_ptr<llvm::DenseMap<const Stmt *, CounterPair>> RegionCounterMap;39  std::unique_ptr<llvm::DenseMap<const Stmt *, uint64_t>> StmtCountMap;40  std::unique_ptr<llvm::InstrProfRecord> ProfRecord;41  std::unique_ptr<MCDC::State> RegionMCDCState;42  std::vector<uint64_t> RegionCounts;43  uint64_t CurrentRegionCount;44 45public:46  CodeGenPGO(CodeGenModule &CGModule)47      : CGM(CGModule), FuncNameVar(nullptr), NumValueSites({{0}}),48        NumRegionCounters(0), FunctionHash(0), CurrentRegionCount(0) {}49 50  /// Whether or not we have PGO region data for the current function. This is51  /// false both when we have no data at all and when our data has been52  /// discarded.53  bool haveRegionCounts() const { return !RegionCounts.empty(); }54 55  /// Return the counter value of the current region.56  uint64_t getCurrentRegionCount() const { return CurrentRegionCount; }57 58  /// Set the counter value for the current region. This is used to keep track59  /// of changes to the most recent counter from control flow and non-local60  /// exits.61  void setCurrentRegionCount(uint64_t Count) { CurrentRegionCount = Count; }62 63  /// Check if an execution count is known for a given statement. If so, return64  /// true and put the value in Count; else return false.65  std::optional<uint64_t> getStmtCount(const Stmt *S) const {66    if (!StmtCountMap)67      return std::nullopt;68    auto I = StmtCountMap->find(S);69    if (I == StmtCountMap->end())70      return std::nullopt;71    return I->second;72  }73 74  /// If the execution count for the current statement is known, record that75  /// as the current count.76  void setCurrentStmt(const Stmt *S) {77    if (auto Count = getStmtCount(S))78      setCurrentRegionCount(*Count);79  }80 81  /// Assign counters to regions and configure them for PGO of a given82  /// function. Does nothing if instrumentation is not enabled and either83  /// generates global variables or associates PGO data with each of the84  /// counters depending on whether we are generating or using instrumentation.85  void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn);86  /// Emit a coverage mapping range with a counter zero87  /// for an unused declaration.88  void emitEmptyCounterMapping(const Decl *D, StringRef FuncName,89                               llvm::GlobalValue::LinkageTypes Linkage);90  // Insert instrumentation or attach profile metadata at value sites91  void valueProfile(CGBuilderTy &Builder, uint32_t ValueKind,92                    llvm::Instruction *ValueSite, llvm::Value *ValuePtr);93 94  // Set a module flag indicating if value profiling is enabled.95  void setValueProfilingFlag(llvm::Module &M);96 97  void setProfileVersion(llvm::Module &M);98 99private:100  void setFuncName(llvm::Function *Fn);101  void setFuncName(StringRef Name, llvm::GlobalValue::LinkageTypes Linkage);102  void mapRegionCounters(const Decl *D);103  void computeRegionCounts(const Decl *D);104  void applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,105                               llvm::Function *Fn);106  void loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,107                        bool IsInMainFile);108  bool skipRegionMappingForDecl(const Decl *D);109  void emitCounterRegionMapping(const Decl *D);110  bool canEmitMCDCCoverage(const CGBuilderTy &Builder);111 112public:113  std::pair<bool, bool> getIsCounterPair(const Stmt *S) const;114  void emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S,115                                 llvm::Value *StepV);116  void emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder, const Expr *S,117                                      Address MCDCCondBitmapAddr,118                                      CodeGenFunction &CGF);119  void emitMCDCParameters(CGBuilderTy &Builder);120  void emitMCDCCondBitmapReset(CGBuilderTy &Builder, const Expr *S,121                               Address MCDCCondBitmapAddr);122  void emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S,123                                Address MCDCCondBitmapAddr, llvm::Value *Val,124                                CodeGenFunction &CGF);125 126  void markStmtAsUsed(bool Skipped, const Stmt *S) {127    // Do nothing.128  }129 130  void markStmtMaybeUsed(const Stmt *S) {131    // Do nothing.132  }133 134  void verifyCounterMap() const {135    // Do nothing.136  }137 138  /// Return the region count for the counter at the given index.139  uint64_t getRegionCount(const Stmt *S) {140    if (!RegionCounterMap)141      return 0;142    if (!haveRegionCounts())143      return 0;144    // With profiles from a differing version of clang we can have mismatched145    // decl counts. Don't crash in such a case.146    auto Index = (*RegionCounterMap)[S].Executed;147    if (Index >= RegionCounts.size())148      return 0;149    return RegionCounts[Index];150  }151};152 153}  // end namespace CodeGen154}  // end namespace clang155 156#endif157