mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
This patch moves the ownership of profiling state from SILGenProfiling to SILFunction, where it always belonged. Similarly, it moves ownership of the profile reader from SILGenModule to SILModule. The refactor sets us up to fix a few outstanding code coverage bugs and does away with sad hacks like ProfilerRAII. It also allows us to locally guarantee that a profile counter increment actually corresponds to the SILFunction at hand. That local guarantee causes a bugfix to accidentally fall out of this refactor: we now set up the profiling state for delayed functions correctly. Previously, we would set up a ProfilerRAII for the delayed function, but its counter increment would never be emitted :(. This fix constitutes the only functional change in this patch -- the rest is NFC. As a follow-up, I plan on removing some dead code in the profiling logic and fixing a few naming inconsistencies. I've left that for later to keep this patch simple.
85 lines
2.9 KiB
C++
85 lines
2.9 KiB
C++
//===--- SILCoverageMap.cpp - Defines the SILCoverageMap class ------------===//
|
|
//
|
|
// This source file is part of the Swift.org 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 https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines the SILCoverageMap class, which is used to relay coverage
|
|
// mapping information from the AST to lower layers of the compiler.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "swift/SIL/SILCoverageMap.h"
|
|
#include "swift/SIL/SILModule.h"
|
|
|
|
using namespace swift;
|
|
|
|
using llvm::coverage::CounterExpression;
|
|
|
|
SILCoverageMap *
|
|
SILCoverageMap::create(SILModule &M, StringRef Filename, StringRef Name,
|
|
bool External, uint64_t Hash,
|
|
ArrayRef<MappedRegion> MappedRegions,
|
|
ArrayRef<CounterExpression> Expressions) {
|
|
auto *Buf = M.allocate<SILCoverageMap>(1);
|
|
SILCoverageMap *CM = ::new (Buf) SILCoverageMap(Hash, External);
|
|
|
|
// Store a copy of the names so that we own the lifetime.
|
|
CM->Filename = M.allocateCopy(Filename);
|
|
CM->Name = M.allocateCopy(Name);
|
|
|
|
// Since we have two arrays, we need to manually tail allocate each of them,
|
|
// rather than relying on the flexible array trick.
|
|
CM->MappedRegions = M.allocateCopy(MappedRegions);
|
|
CM->Expressions = M.allocateCopy(Expressions);
|
|
|
|
M.coverageMaps.push_back(CM);
|
|
return CM;
|
|
}
|
|
|
|
SILCoverageMap::SILCoverageMap(uint64_t Hash, bool External)
|
|
: External(External), Hash(Hash), HasSymtabEntry(false) {}
|
|
|
|
SILCoverageMap::~SILCoverageMap() {}
|
|
|
|
namespace {
|
|
struct Printer {
|
|
const llvm::coverage::Counter &C;
|
|
ArrayRef<llvm::coverage::CounterExpression> Exprs;
|
|
Printer(const llvm::coverage::Counter &C,
|
|
ArrayRef<llvm::coverage::CounterExpression> Exprs)
|
|
: C(C), Exprs(Exprs) {}
|
|
|
|
void print(raw_ostream &OS) const {
|
|
// TODO: This format's nice and human readable, but does it fit well with
|
|
// SIL's relatively simple structure?
|
|
if (C.isZero())
|
|
OS << "zero";
|
|
else if (C.isExpression()) {
|
|
assert(C.getExpressionID() < Exprs.size() && "expression out of range");
|
|
const auto &E = Exprs[C.getExpressionID()];
|
|
OS << '(' << Printer(E.LHS, Exprs)
|
|
<< (E.Kind == CounterExpression::Add ? " + " : " - ")
|
|
<< Printer(E.RHS, Exprs) << ')';
|
|
} else
|
|
OS << C.getCounterID();
|
|
}
|
|
|
|
friend raw_ostream &operator<<(raw_ostream &OS, const Printer &P) {
|
|
P.print(OS);
|
|
return OS;
|
|
}
|
|
};
|
|
} // end anonymous namespace
|
|
|
|
void SILCoverageMap::printCounter(llvm::raw_ostream &OS,
|
|
llvm::coverage::Counter C) const {
|
|
OS << Printer(C, getExpressions());
|
|
}
|