Skip to content

Commit 01c7c16

Browse files
committed
[IRGen] Allow lazy emission of coverage mapped functions
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.
1 parent cc46593 commit 01c7c16

File tree

5 files changed

+34
-16
lines changed

5 files changed

+34
-16
lines changed

lib/IRGen/GenCoverage.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,8 @@ void IRGenModule::emitCoverageMapping() {
192192
CovData->setAlignment(llvm::Align(8));
193193
addUsedGlobal(CovData);
194194
}
195+
196+
void IRGenerator::emitCoverageMapping() {
197+
for (auto &IGM : *this)
198+
IGM.second->emitCoverageMapping();
199+
}

lib/IRGen/GenDecl.cpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,23 +1158,15 @@ void IRGenModule::emitGlobalLists() {
11581158
/*isConstant*/false, /*asContiguousArray*/true);
11591159
}
11601160

1161-
static bool hasCodeCoverageInstrumentation(SILFunction &f, SILModule &m) {
1162-
return f.getProfiler() && m.getOptions().EmitProfileCoverageMapping;
1163-
}
1164-
1165-
// Eagerly emit functions that are externally visible. Functions with code
1166-
// coverage instrumentation must also be eagerly emitted. So must functions
1167-
// that are a dynamic replacement for another.
1161+
// Eagerly emit functions that are externally visible. Functions that are
1162+
// dynamic replacements must also be eagerly emitted.
11681163
static bool isLazilyEmittedFunction(SILFunction &f, SILModule &m) {
11691164
if (f.isPossiblyUsedExternally())
11701165
return false;
11711166

11721167
if (f.getDynamicallyReplacedFunction())
11731168
return false;
11741169

1175-
if (hasCodeCoverageInstrumentation(f, m))
1176-
return false;
1177-
11781170
// Needed by lldb to print global variables which are propagated by the
11791171
// mandatory GlobalOpt.
11801172
if (m.getOptions().OptMode == OptimizationMode::NoOptimization &&
@@ -1258,12 +1250,6 @@ void IRGenerator::emitGlobalTopLevel(
12581250
IGM->emitSILDifferentiabilityWitness(&dw);
12591251
}
12601252

1261-
// Emit code coverage mapping data for all modules
1262-
for (auto Iter : *this) {
1263-
IRGenModule *IGM = Iter.second;
1264-
IGM->emitCoverageMapping();
1265-
}
1266-
12671253
for (auto Iter : *this) {
12681254
IRGenModule *IGM = Iter.second;
12691255
IGM->finishEmitAfterTopLevel();

lib/IRGen/IRGen.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,6 +1358,11 @@ GeneratedModule IRGenRequest::evaluate(Evaluator &evaluator,
13581358
irgen.emitDynamicReplacements();
13591359
}
13601360

1361+
// Emit coverage mapping info. This needs to happen after we've emitted
1362+
// any lazy definitions, as we need to know whether or not we emitted a
1363+
// profiler increment for a given coverage map.
1364+
IGM.emitCoverageMapping();
1365+
13611366
// Emit symbols for eliminated dead methods.
13621367
IGM.emitVTableStubs();
13631368

@@ -1608,6 +1613,11 @@ static void performParallelIRGeneration(IRGenDescriptor desc) {
16081613
// Emit reflection metadata for builtin and imported types.
16091614
irgen.emitBuiltinReflectionMetadata();
16101615

1616+
// Emit coverage mapping info. This needs to happen after we've emitted
1617+
// any lazy definitions, as we need to know whether or not we emitted a
1618+
// profiler increment for a given coverage map.
1619+
irgen.emitCoverageMapping();
1620+
16111621
IRGenModule *PrimaryGM = irgen.getPrimaryIGM();
16121622

16131623
// Emit symbols for eliminated dead methods.

lib/IRGen/IRGenModule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,9 @@ class IRGenerator {
427427
// Emit info that describes the entry point to the module, if it has one.
428428
void emitEntryPointInfo();
429429

430+
/// Emit coverage mapping info.
431+
void emitCoverageMapping();
432+
430433
/// Checks if metadata for this type can be emitted lazily. This is true for
431434
/// non-public types as well as imported types, except for classes and
432435
/// protocols which are always emitted eagerly.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-frontend -emit-sil -profile-generate -profile-coverage-mapping -module-name coverage_deadcode %s | %FileCheck %s -check-prefix SIL
2+
// RUN: %target-swift-frontend -emit-ir -profile-generate -profile-coverage-mapping -module-name coverage_deadcode %s | %FileCheck %s -check-prefix IR
3+
4+
// This function needs to be present in the SIL for the mandatory passes, but
5+
// we can drop it in IRGen. We still need to emit its coverage map though.
6+
func unused() -> Int { 5 }
7+
8+
// SIL: sil hidden @$s17coverage_deadcode6unusedSiyF : $@convention(thin) () -> Int
9+
// SIL: sil_coverage_map {{.*}} "$s17coverage_deadcode6unusedSiyF"
10+
11+
// IR: @__covrec
12+
// IR: @__llvm_coverage_mapping
13+
// IR: @__llvm_prf_nm
14+
// IR-NOT: define {{.*}} @"$s17coverage_deadcode6unusedSiyF"

0 commit comments

Comments
 (0)