Skip to content

Commit 651d9f9

Browse files
committed
Merge pull request #2334 from vedantk/skip-implicit-regions
[Coverage] Do not emit increments in certain implicitly-generated reg…
2 parents 5523266 + c5873f3 commit 651d9f9

File tree

4 files changed

+40
-13
lines changed

4 files changed

+40
-13
lines changed

lib/SILGen/SILGenFunction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
465465

466466
/// Emit code to increment a counter for profiling.
467467
void emitProfilerIncrement(ASTNode N) {
468-
if (SGM.Profiler)
468+
if (SGM.Profiler && SGM.Profiler->hasRegionCounters())
469469
SGM.Profiler->emitCounterIncrement(B, N);
470470
}
471471

lib/SILGen/SILGenProfiling.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,24 @@
2929
using namespace swift;
3030
using namespace Lowering;
3131

32+
static bool isUnmappedDecl(Decl *D) {
33+
if (isa<ConstructorDecl>(D) || isa<DestructorDecl>(D))
34+
return false;
35+
36+
return D->isImplicit() || isa<EnumCaseDecl>(D);
37+
}
38+
3239
ProfilerRAII::ProfilerRAII(SILGenModule &SGM, AbstractFunctionDecl *D)
33-
: SGM(SGM) {
40+
: SGM(SGM), PreviousProfiler(std::move(SGM.Profiler)) {
3441
const auto &Opts = SGM.M.getOptions();
35-
if (!Opts.GenerateProfile)
42+
if (!Opts.GenerateProfile || isUnmappedDecl(D))
3643
return;
3744
SGM.Profiler =
3845
llvm::make_unique<SILGenProfiling>(SGM, Opts.EmitProfileCoverageMapping);
3946
SGM.Profiler->assignRegionCounters(D);
4047
}
4148

42-
ProfilerRAII::~ProfilerRAII() { SGM.Profiler = nullptr; }
49+
ProfilerRAII::~ProfilerRAII() { SGM.Profiler = std::move(PreviousProfiler); }
4350

4451
namespace {
4552

@@ -55,6 +62,8 @@ struct MapRegionCounters : public ASTWalker {
5562
: NextCounter(0), CounterMap(CounterMap) {}
5663

5764
bool walkToDeclPre(Decl *D) override {
65+
if (isUnmappedDecl(D))
66+
return false;
5867
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D))
5968
CounterMap[AFD->getBody()] = NextCounter++;
6069
return true;
@@ -435,7 +444,7 @@ struct CoverageMapping : public ASTWalker {
435444
}
436445

437446
bool walkToDeclPre(Decl *D) override {
438-
if (D->isImplicit())
447+
if (isUnmappedDecl(D))
439448
return false;
440449
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D))
441450
assignCounter(AFD->getBody());

lib/SILGen/SILGenProfiling.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,7 @@ namespace Lowering {
2727
class SILGenModule;
2828
class SILGenBuilder;
2929

30-
/// RAII object to set up profiling for a function.
31-
struct ProfilerRAII {
32-
SILGenModule &SGM;
33-
ProfilerRAII(SILGenModule &SGM, AbstractFunctionDecl *D);
34-
~ProfilerRAII();
35-
};
30+
struct ProfilerRAII;
3631

3732
/// Profiling state.
3833
class SILGenProfiling {
@@ -57,11 +52,23 @@ class SILGenProfiling {
5752

5853
bool hasRegionCounters() const { return NumRegionCounters != 0; }
5954

55+
/// Emit SIL to increment the counter for \c Node.
56+
void emitCounterIncrement(SILGenBuilder &Builder, ASTNode Node);
57+
58+
private:
6059
/// Map counters to ASTNodes and set them up for profiling the given function.
6160
void assignRegionCounters(AbstractFunctionDecl *Root);
6261

63-
/// Emit SIL to increment the counter for \c Node.
64-
void emitCounterIncrement(SILGenBuilder &Builder, ASTNode Node);
62+
friend struct ProfilerRAII;
63+
};
64+
65+
/// RAII object to set up profiling for a function.
66+
struct ProfilerRAII {
67+
SILGenModule &SGM;
68+
std::unique_ptr<SILGenProfiling> PreviousProfiler;
69+
70+
ProfilerRAII(SILGenModule &SGM, AbstractFunctionDecl *D);
71+
~ProfilerRAII();
6572
};
6673

6774
} // end namespace Lowering

test/SILGen/coverage_smoke.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,15 @@ func main() {
5353
let _ = Class1()
5454
}
5555

56+
// rdar://problem/22761498 - enum declaration suppresses coverage
57+
func foo() {
58+
var x : Int32 = 0 // CHECK-COV: 1|{{.*}}[[@LINE]]
59+
enum ETy { case A } // CHECK-COV: 1|{{.*}}[[@LINE]]
60+
repeat { // CHECK-COV: 1|{{.*}}[[@LINE]]
61+
x += 1 // CHECK-COV: 1|{{.*}}[[@LINE]]
62+
} while x == 0 // CHECK-COV: 1|{{.*}}[[@LINE]]
63+
x += 1 // CHECK-COV: 1|{{.*}}[[@LINE]]
64+
}
65+
5666
main()
67+
foo()

0 commit comments

Comments
 (0)