Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
The coverage format version we use is automatically
set to whatever the latest version LLVM has. This
resulting in us outputting version 6 as our
format without having made the changes necessary
to reflect the new format. Update the emission
logic to take account for [the new changes in
version 6][1] (we need to include the current
working directory as the first element of the list
of files we output). Additionally, add a
`static_assert` so we don't get caught out by
version bumps in the future. Note we can't pin our
version, as it must stay in sync with the version
Clang is using.
[1]: https://llvm.org/docs/CoverageMappingFormat.html#llvm-ir-representation
Iterating over the IRGenModules and emitting every
SILCoverageMap in the SILModule meant that we
were emitting N copies of the coverage maps for
parallel IRGen, where N is the number of output
object files.
This has always been wrong, but was previously
saved by the fact that we would drop the coverage
map on the floor if we didn't have the name data
available. This would only be the case for the
IRGenModule that had the emitted entity to
profile, in addition to any IRGenModules that
had inlined the body of a profiled enitity. As
such, this prevented the duplication from being
too egregious. However with the recent change to
emit unused name data in the case where we don't
already have name data available, we're now fully
duplicating every coverage mapping, and emitting a
ton of redundant name data.
Fix things such that we only emit coverage mapping
records for the IRGenModule that corresponds to
the entity being profiled.
rdar://102905496
We previously eagerly emitted such functions to
ensure that their name data is emitted through the
profiler increment. Now that are able to emit the
profile name data separately, this is unnecessary,
and we can avoid emitting their definitions.
Previously, if all the coverage counters for a
given SIL function were optimized out, we would
have dropped the coverage map on the floor,
leading to inaccurate coverage reports in `-O`.
However LLVM allows us to emit the name data for
the coverage maps separately by defining an
`__llvm_coverage_names` global with the name data,
which is picked up by its instrumentation lowering
pass. Use this to continue to emit coverage maps
for functions that do not get emitted.
rdar://99813754
`CoverageFilenamesSectionWriter` now takes an `ArrayRef<std::string>`
rather than `ArrayRef<StringRef>`. stable/20210726 reverted that change
so that the coverage formats were the same. stable/20211026 doesn't have
that revert though.
Previously the path to covered files in the __LLVM_COV / __llvm_covmap
section were absolute. This made remote builds with coverage information
difficult because all machines would have to have the same build root.
This change uses the values for `-coverage-prefix-map` to remap files in
the coverage info to relative paths. These paths work correctly with
llvm-cov when it is run from the same source directory as the
compilation, or from a different directory using the `-path-equivalence`
argument.
This is analogous to this change in clang https://reviews.llvm.org/D81122
A function may be eliminated as dead code after initial builtin lowering
occurs. When this happens, an entry in the profile symbol table for the
function is not guaranteed. Its coverage record should be dropped.
rdar://42564768
The compiler shouldn't emit coverage mappings for functions which don't
contain profiling instrumentation. However, due to bugs in the profiling
code, this sometimes happens. In this case, it's better to defensively
drop just the malformed coverage mappings instead of allowing corrupted
profiles to be created.
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.
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.
While invoking the instrprof_increment intrinsic, we used to pass the
profile name variable by using a GEP instruction to get to the string
constant. That prevented llvm from uniquing the names. Use a constexpr
GEP to fix the issue.
Passing {FileID} into the CoverageMappingWriter constructor causes UB.
The ArrayRef constructed from the initializer list becomes invalid once
the constructor returns, because the lifetime of the initializer list
expires. Use an alternate ArrayRef constructor which outlives the
CoverageMappingWriter instance.
This commit also re-reenables coverage_smoke.swift.
rdar://problem/29591622
Instead, pass name pointers to InstrProfiling::lowerCoverageData() using
the new API (via getCoverageUnusedNamesVarName). This ensures that we
don't emit an uncompressed *and* a compressed version of all function
names into the module, fixing rdar://problem/25493310.
Fix a crash in emitBuiltinCall() which occurs because we drop function
linkage information when creating SILCoverageMaps.
This re-applies 45c7e4e86 with the MachO-specific checks in the test
case removed.
Update our usage of llvm's coverage API and fix the way we lower
instrprof_increment intrinsics.
This keeps us up-to-date with llvm/stable and makes instrumented IR
easier to read.
Changes to the coverage mapping API in upstream llvm have caused merge
conflicts and breakage in swift. This commit phases in bits of the new
API in a way that can be safely cherry-picked to swift-{2.2,3.0}-branch.
This commit is NFC for master-next and swift-2.2-branch, but constitutes
an actual bugfix for 3.0. That's because 3.0 is paired with a version of
llvm that takes advantage of the new coverage API to reduce the size of
instrumented binaries.
This effectively closes Swift PR-1053.
(cherry picked from commit a079d313fe)