blob: caa5de30d3f5a46ad3906d186eab9ccbd5004027 [file] [log] [blame]
//===--- SILProfiler.h - Instrumentation based profiling ===-----*- C++ -*-===//
// This source file is part of the open source project
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
// See for license information
// See for the list of Swift project authors
// This file defines SILProfiler, which contains the profiling state for one
// function. It's used to drive PGO and generate code coverage reports.
#include "swift/AST/ASTNode.h"
#include "swift/Basic/ProfileCounter.h"
#include "swift/SIL/SILAllocated.h"
#include "swift/SIL/SILDeclRef.h"
#include "llvm/ADT/DenseMap.h"
namespace swift {
class AbstractFunctionDecl;
class SILCoverageMap;
class SILFunction;
class SILModule;
/// Returns whether the given AST node requires profiling instrumentation.
bool doesASTRequireProfiling(SILModule &M, ASTNode N);
/// SILProfiler - Maps AST nodes to profile counters.
class SILProfiler : public SILAllocated<SILProfiler> {
SILModule &M;
ASTNode Root;
SILDeclRef forDecl;
bool EmitCoverageMapping;
SILCoverageMap *CovMap = nullptr;
StringRef CurrentFileName;
std::string PGOFuncName;
uint64_t PGOFuncHash = 0;
unsigned NumRegionCounters = 0;
llvm::DenseMap<ASTNode, unsigned> RegionCounterMap;
llvm::DenseMap<ASTNode, ProfileCounter> RegionLoadedCounterMap;
llvm::DenseMap<ASTNode, ASTNode> RegionCondToParentMap;
std::vector<std::tuple<std::string, uint64_t, std::string>> CoverageData;
SILProfiler(SILModule &M, ASTNode Root, SILDeclRef forDecl,
bool EmitCoverageMapping)
: M(M), Root(Root), forDecl(forDecl),
EmitCoverageMapping(EmitCoverageMapping) {}
static SILProfiler *create(SILModule &M, ForDefinition_t forDefinition,
ASTNode N, SILDeclRef forDecl);
/// Check if the function is set up for profiling.
bool hasRegionCounters() const { return NumRegionCounters != 0; }
/// Get the execution count corresponding to \p Node from a profile, if one
/// is available.
ProfileCounter getExecutionCount(ASTNode Node);
/// Get the node's parent ASTNode (e.g to get the parent IfStmt or IfCond of
/// a condition), if one is available.
Optional<ASTNode> getPGOParent(ASTNode Node);
/// Get the function name mangled for use with PGO.
StringRef getPGOFuncName() const { return PGOFuncName; }
/// Get the function hash.
uint64_t getPGOFuncHash() const { return PGOFuncHash; }
/// Get the number of region counters.
unsigned getNumRegionCounters() const { return NumRegionCounters; }
/// Get the mapping from \c ASTNode to its corresponding profile counter.
const llvm::DenseMap<ASTNode, unsigned> &getRegionCounterMap() const {
return RegionCounterMap;
/// Map counters to ASTNodes and set them up for profiling the function.
void assignRegionCounters();
} // end namespace swift