[Profiler] Improve region termination

We can terminate all the regions up to the last
AST node in the stack, since regions without AST
nodes are refinements of the region with the AST
node, and should be terminated the same. This
avoids leaving some regions that extend past e.g
the `return` of a function.

The region in the test case that changes here is:

```
[[@LINE+9]]:28 -> [[@LINE+12]]:4 : (0 - 1)
```

this was extending past the return. Now it is:

```
[[@LINE]]:6    -> [[@LINE+4]]:11 : (0 - 1)
```

Apologies, I also refactored the test case at the
same time which makes the difference harder to see,
but the main point is that this region now terminates
at the return, the same as the others.
This commit is contained in:
Hamish Knight
2023-11-16 17:28:57 +00:00
parent bb48233695
commit 4e48db550b
2 changed files with 24 additions and 22 deletions

View File

@@ -1057,9 +1057,18 @@ private:
/// Mark \c S as a terminator, starting a zero region.
void terminateRegion(ASTNode S) {
SourceMappingRegion &Region = getRegion();
if (!Region.hasEndLoc())
Region.setEndLoc(getEndLoc(S));
assert(!RegionStack.empty() && "Cannot terminate non-existant region");
// Walk up the region stack and cut short regions until we reach a region
// for an AST node. This ensures we correctly handle new regions that have
// been introduced as a result of replacing the count, e.g if errors have
// been thrown.
for (auto &Region : llvm::reverse(RegionStack)) {
if (!Region.hasEndLoc())
Region.setEndLoc(getEndLoc(S));
if (Region.getNode())
break;
}
replaceCount(CounterExpr::Zero(), /*Start*/ llvm::None);
}

View File

@@ -18,26 +18,19 @@
// CHECK-NEXT: increment_profiler_counter 1
// CHECK-LABEL: sil_coverage_map {{.*}} "$s11coverage_do3fooyyF"
// CHECK-NEXT: [[@LINE+11]]:12 -> [[@LINE+18]]:2 : 0
// CHECK-NEXT: [[@LINE+11]]:9 -> [[@LINE+15]]:4 : 0
// CHECK-NEXT: [[@LINE+11]]:8 -> [[@LINE+11]]:17 : 0
// CHECK-NEXT: [[@LINE+10]]:18 -> [[@LINE+10]]:28 : 1
// CHECK-NEXT: [[@LINE+9]]:28 -> [[@LINE+12]]:4 : (0 - 1)
// CHECK-NEXT: [[@LINE+9]]:8 -> [[@LINE+9]]:17 : (0 - 1)
// CHECK-NEXT: [[@LINE+8]]:18 -> [[@LINE+8]]:29 : 2
// CHECK-NEXT: [[@LINE+7]]:29 -> [[@LINE+8]]:11 : ((0 - 1) - 2)
// CHECK-NEXT: [[@LINE+8]]:4 -> [[@LINE+10]]:2 : 2
// CHECK-NEXT: [[@LINE+8]]:6 -> [[@LINE+8]]:8 : 2
// CHECK-NEXT: [[@LINE+7]]:8 -> [[@LINE+8]]:2 : 2
func foo() {
x: do {
if .random() { return }
if .random() { break x }
func foo() { // CHECK-NEXT: [[@LINE]]:12 -> [[@LINE+11]]:2 : 0
x: do { // CHECK-NEXT: [[@LINE]]:9 -> [[@LINE+8]]:4 : 0
if .random() { // CHECK-NEXT: [[@LINE]]:8 -> [[@LINE]]:17 : 0
return // CHECK-NEXT: [[@LINE-1]]:18 -> [[@LINE+1]]:6 : 1
} // CHECK-NEXT: [[@LINE]]:6 -> [[@LINE+4]]:11 : (0 - 1)
if .random() { // CHECK-NEXT: [[@LINE]]:8 -> [[@LINE]]:17 : (0 - 1)
break x // CHECK-NEXT: [[@LINE-1]]:18 -> [[@LINE+1]]:6 : 2
} // CHECK-NEXT: [[@LINE]]:6 -> [[@LINE+1]]:11 : ((0 - 1) - 2)
return
}
do {}
}
// CHECK-NEXT: }
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+2]]:2 : 2
do {} // CHECK-NEXT: [[@LINE]]:6 -> [[@LINE]]:8 : 2
} // CHECK-NEXT: [[@LINE-1]]:8 -> [[@LINE]]:2 : 2
// CHECK-NEXT: }
// CHECK-LABEL: sil_coverage_map {{.*}} "$s11coverage_do4foobyyF"
func foob() {