[llvm] [coro][pgp] Do not insert counters in the `suspend` block (PR #71262)
Mircea Trofin via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 13 13:10:56 PST 2023
mtrofin wrote:
> Still trying to understand the details here. Is the problem here that new instructions are inserted between a `llvm.coro.suspend` call and the corresponding `switch` of the results? If so wouldn't it be easier to just move the instrumentation upwards in the basic block?
No, it's inserted in the `suspend` block. Let's use `llvm/test/Transforms/Coroutines/coro-split-musttail.ll` as an example.
Without pgo instrumentation, the end of the `opt` mini-pipeline looks like this:
```
entry.resume:
%index.addr = getelementptr inbounds %f.Frame, ptr %vFrame, i32 0, i32 2
%index = load i1, ptr %index.addr, align 1
switch i1 %index, label %unreachable [
i1 false, label %AfterCoroSuspend
i1 true, label %CoroEnd
]
AfterCoroSuspend: ; preds = %entry.resume
br i1 true, label %CoroSave1, label %CoroEnd
CoroSave1: ; preds = %AfterCoroSuspend
store i1 true, ptr %index.addr, align 1
%addr2 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0)
musttail call fastcc void %addr2(ptr null)
ret void
```
Note how the call to `%addr2` is a tail call.
OK, now with pgo instrumentation. First, right after `pgo-instr-gen`, without this PR, it'd look like this:
```
entry:
...
%suspend = call i8 @llvm.coro.suspend(token %save, i1 false)
switch i8 %suspend, label %entry.exit_crit_edge [
i8 0, label %await.ready
i8 1, label %exit
]
entry.exit_crit_edge: ; preds = %entry
call void @llvm.instrprof.increment(ptr @__profn_f, i64 1063614631108132880, i32 5, i32 0)
br label %exit
```
The effect after `coro-split` is that, in `f.resume`, we'd end up with this:
```
entry.resume:
%index.addr = getelementptr inbounds %f.Frame, ptr %vFrame, i32 0, i32 2
%index = load i1, ptr %index.addr, align 1
switch i1 %index, label %unreachable [
i1 false, label %await.ready
i1 true, label %AfterCoroSuspend5
]
await.ready: ; preds = %entry.resume
...
%addr2 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0)
...
call fastcc void %addr2(ptr null)
br label %AfterCoroSuspend5
```
so the call to `%addr2` is a regular call instead of a tail call. With the fix:
```
entry.resume:
%index.addr = getelementptr inbounds %f.Frame, ptr %vFrame, i32 0, i32 2
%index = load i1, ptr %index.addr, align 1
switch i1 %index, label %unreachable [
i1 false, label %AfterCoroSuspend
i1 true, label %CoroEnd
]
AfterCoroSuspend: ; preds = %entry.resume
br i1 true, label %CoroSave1, label %CoroEnd
CoroSave1: ; preds = %AfterCoroSuspend
...
%addr2 = call ptr @llvm.coro.subfn.addr(ptr null, i8 0)
...
musttail call fastcc void %addr2(ptr null)
ret void
```
https://github.com/llvm/llvm-project/pull/71262
More information about the llvm-commits
mailing list