
Before all the call probe ids are after block ids, in this change, it mixed the call probe and block probe by reordering them in lexical(line-number) order. For example: ``` main(): BB1 if(...) BB2 foo(..); else BB3 bar(...); BB4 ``` Before the profile is ``` main 1: .. 2: .. 3: ... 4: ... 5: foo ... 6: bar ... ``` Now the new order is ``` main 1: .. 2: .. 3: foo ... 4: ... 5: bar ... 6: ... ``` This can potentially make it more tolerant of profile mismatch, either from stale profile or frontend change. e.g. before if we add one block, even the block is the last one, all the call probes are shifted and mismatched. Moreover, this makes better use of call-anchor based stale profile matching. Blocks are matched based on the closest anchor, there would be more anchors used for the matching, reduce the mismatch scope.
75 lines
2.4 KiB
LLVM
75 lines
2.4 KiB
LLVM
; REQUIRES: x86_64-linux
|
|
; RUN: opt < %s -passes='pseudo-probe,jump-threading' -S -o %t
|
|
; RUN: FileCheck %s < %t --check-prefix=JT
|
|
; RUN: llc -function-sections <%t -filetype=asm | FileCheck %s --check-prefix=ASM
|
|
; RUN: opt < %s -passes='pseudo-probe' -S -o %t1
|
|
; RUN: llc -stop-after=tailduplication <%t1 | FileCheck %s --check-prefix=MIR-tail
|
|
; RUN: opt < %s -passes='pseudo-probe,simplifycfg' -S | FileCheck %s --check-prefix=SC
|
|
|
|
declare i32 @f1()
|
|
|
|
define i32 @foo(i1 %cond) {
|
|
; JT-LABEL: @foo(
|
|
; JT: call void @llvm.pseudoprobe(i64 [[#GUID:]], i64 1, i32 0, i64 -1)
|
|
; ASM: pseudoprobe 6699318081062747564 1 0 0
|
|
%call = call i32 @f1()
|
|
br i1 %cond, label %T, label %F
|
|
T:
|
|
br label %Merge
|
|
F:
|
|
br label %Merge
|
|
Merge:
|
|
;; Check branch T and F are gone, and their probes (probe 2 and 3) are gone too.
|
|
; JT-LABEL-NO: T
|
|
; JT-LABEL-NO: F
|
|
; JT-LABEL: Merge
|
|
; JT-NOT: call void @llvm.pseudoprobe(i64 [[#GUID:]], i64 4
|
|
; JT-NOT: call void @llvm.pseudoprobe(i64 [[#GUID:]], i64 3
|
|
; JT: call void @llvm.pseudoprobe(i64 [[#GUID:]], i64 5, i32 0, i64 -1)
|
|
; ASM-NOT: .pseudoprobe 6699318081062747564 4
|
|
; ASM-NOT: .pseudoprobe 6699318081062747564 3
|
|
; ASM: .pseudoprobe 6699318081062747564 5 0 0
|
|
ret i32 %call
|
|
}
|
|
|
|
;; Check block T and F are gone, and their probes (probe 2 and 3) are gone too.
|
|
; MIR-tail: bb.0
|
|
; MIR-tail: PSEUDO_PROBE [[#GUID:]], 1, 0, 0
|
|
; MIR-tail-NOT: PSEUDO_PROBE [[#GUID:]], 3
|
|
; MIR-tail-NOT: PSEUDO_PROBE [[#GUID:]], 4
|
|
; MIR-tail: PSEUDO_PROBE [[#GUID:]], 5, 0, 0
|
|
|
|
|
|
define i32 @test(i32 %a, i32 %b, i32 %c) {
|
|
;; Check block bb1 and bb2 are gone, and their probes (probe 2 and 3) are gone too.
|
|
; SC-LABEL: @test(
|
|
; SC-LABEL-NO: bb1
|
|
; SC-LABEL-NO: bb2
|
|
; SC: [[T1:%.*]] = icmp eq i32 [[B:%.*]], 0
|
|
; SC-NOT: call void @llvm.pseudoprobe(i64 [[#]], i64 2
|
|
; SC-NOT: call void @llvm.pseudoprobe(i64 [[#]], i64 3
|
|
; SC: [[T2:%.*]] = icmp sgt i32 [[C:%.*]], 1
|
|
; SC: [[T3:%.*]] = add i32 [[A:%.*]], 1
|
|
; SC: [[SPEC_SELECT:%.*]] = select i1 [[T2]], i32 [[T3]], i32 [[A]]
|
|
; SC: [[T4:%.*]] = select i1 [[T1]], i32 [[SPEC_SELECT]], i32 [[B]]
|
|
; SC: [[T5:%.*]] = sub i32 [[T4]], 1
|
|
; SC: ret i32 [[T5]]
|
|
|
|
entry:
|
|
%t1 = icmp eq i32 %b, 0
|
|
br i1 %t1, label %bb1, label %bb3
|
|
|
|
bb1:
|
|
%t2 = icmp sgt i32 %c, 1
|
|
br i1 %t2, label %bb2, label %bb3
|
|
|
|
bb2:
|
|
%t3 = add i32 %a, 1
|
|
br label %bb3
|
|
|
|
bb3:
|
|
%t4 = phi i32 [ %b, %entry ], [ %a, %bb1 ], [ %t3, %bb2 ]
|
|
%t5 = sub i32 %t4, 1
|
|
ret i32 %t5
|
|
}
|