| ; RUN: opt < %s -passes=pseudo-probe,sample-profile -sample-profile-use-profi -sample-profile-file=%S/Inputs/profile-inference.prof | opt -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s |
| ; RUN: opt < %s -passes=pseudo-probe,sample-profile -sample-profile-use-profi -sample-profile-file=%S/Inputs/profile-inference.prof | opt -passes='print<block-freq>' -disable-output 2>&1 | FileCheck %s --check-prefix=CHECK2 |
| |
| ; The test verifies that profile inference correctly builds branch probabilities |
| ; from sampling-based block counts. |
| ; |
| ; +---------+ +----------+ |
| ; | b3 [40] | <-- | b1 [100] | |
| ; +---------+ +----------+ |
| ; | |
| ; | |
| ; v |
| ; +----------+ |
| ; | b2 [60] | |
| ; +----------+ |
| |
| @yydebug = dso_local global i32 0, align 4 |
| |
| ; Function Attrs: nounwind uwtable |
| define dso_local i32 @test_1() #0 { |
| b1: |
| call void @llvm.pseudoprobe(i64 7964825052912775246, i64 1, i32 0, i64 -1) |
| %0 = load i32, ptr @yydebug, align 4 |
| %cmp = icmp ne i32 %0, 0 |
| br i1 %cmp, label %b2, label %b3 |
| ; CHECK: edge b1 -> b2 probability is 0x4ccccccd / 0x80000000 = 60.00% |
| ; CHECK: edge b1 -> b3 probability is 0x33333333 / 0x80000000 = 40.00% |
| ; CHECK2: - b1: float = {{.*}}, int = {{.*}}, count = 100 |
| |
| b2: |
| call void @llvm.pseudoprobe(i64 7964825052912775246, i64 2, i32 0, i64 -1) |
| ret i32 %0 |
| ; CHECK2: - b2: float = {{.*}}, int = {{.*}}, count = 60 |
| |
| b3: |
| call void @llvm.pseudoprobe(i64 7964825052912775246, i64 3, i32 0, i64 -1) |
| ret i32 %0 |
| ; CHECK2: - b3: float = {{.*}}, int = {{.*}}, count = 40 |
| } |
| |
| |
| ; The test verifies that profile inference correctly builds branch probabilities |
| ; from sampling-based block counts in the presence of "dangling" probes (whose |
| ; block counts are missing). |
| ; |
| ; +---------+ +----------+ |
| ; | b3 [10] | <-- | b1 [100] | |
| ; +---------+ +----------+ |
| ; | |
| ; | |
| ; v |
| ; +----------+ |
| ; | b2 [?] | |
| ; +----------+ |
| |
| ; Function Attrs: nounwind uwtable |
| define dso_local i32 @test_2() #0 { |
| b1: |
| call void @llvm.pseudoprobe(i64 -6216829535442445639, i64 1, i32 0, i64 -1) |
| %0 = load i32, ptr @yydebug, align 4 |
| %cmp = icmp ne i32 %0, 0 |
| br i1 %cmp, label %b2, label %b3 |
| ; CHECK: edge b1 -> b2 probability is 0x73333333 / 0x80000000 = 90.00% |
| ; CHECK: edge b1 -> b3 probability is 0x0ccccccd / 0x80000000 = 10.00% |
| ; CHECK2: - b1: float = {{.*}}, int = {{.*}}, count = 100 |
| |
| b2: |
| call void @llvm.pseudoprobe(i64 -6216829535442445639, i64 2, i32 0, i64 -1) |
| ret i32 %0 |
| ; CHECK2: - b2: float = {{.*}}, int = {{.*}}, count = 90 |
| |
| b3: |
| call void @llvm.pseudoprobe(i64 -6216829535442445639, i64 3, i32 0, i64 -1) |
| ret i32 %0 |
| } |
| ; CHECK2: - b3: float = {{.*}}, int = {{.*}}, count = 10 |
| |
| |
| ; The test verifies that profi is able to infer block counts from hot subgraphs. |
| ; |
| ; +---------+ +---------+ |
| ; | b4 [?] | <-- | b1 [?] | |
| ; +---------+ +---------+ |
| ; | | |
| ; | | |
| ; v v |
| ; +---------+ +---------+ |
| ; | b5 [89] | | b2 [?] | |
| ; +---------+ +---------+ |
| ; | |
| ; | |
| ; v |
| ; +---------+ |
| ; | b3 [13] | |
| ; +---------+ |
| |
| ; Function Attrs: nounwind uwtable |
| define dso_local i32 @test_3() #0 { |
| b1: |
| call void @llvm.pseudoprobe(i64 1649282507922421973, i64 1, i32 0, i64 -1) |
| %0 = load i32, ptr @yydebug, align 4 |
| %cmp = icmp ne i32 %0, 0 |
| br i1 %cmp, label %b2, label %b4 |
| ; CHECK: edge b1 -> b2 probability is 0x10505050 / 0x80000000 = 12.75% |
| ; CHECK: edge b1 -> b4 probability is 0x6fafafb0 / 0x80000000 = 87.25% |
| ; CHECK2: - b1: float = {{.*}}, int = {{.*}}, count = 102 |
| |
| b2: |
| call void @llvm.pseudoprobe(i64 1649282507922421973, i64 2, i32 0, i64 -1) |
| br label %b3 |
| ; CHECK: edge b2 -> b3 probability is 0x80000000 / 0x80000000 = 100.00% |
| ; CHECK2: - b2: float = {{.*}}, int = {{.*}}, count = 13 |
| |
| b3: |
| call void @llvm.pseudoprobe(i64 1649282507922421973, i64 3, i32 0, i64 -1) |
| ret i32 %0 |
| ; CHECK2: - b3: float = {{.*}}, int = {{.*}}, count = 13 |
| |
| b4: |
| call void @llvm.pseudoprobe(i64 1649282507922421973, i64 4, i32 0, i64 -1) |
| br label %b5 |
| ; CHECK: edge b4 -> b5 probability is 0x80000000 / 0x80000000 = 100.00% |
| ; CHECK2: - b4: float = {{.*}}, int = {{.*}}, count = 89 |
| |
| b5: |
| call void @llvm.pseudoprobe(i64 1649282507922421973, i64 5, i32 0, i64 -1) |
| ret i32 %0 |
| ; CHECK2: - b5: float = {{.*}}, int = {{.*}}, count = 89 |
| } |
| |
| |
| ; A larger test to verify that profile inference correctly identifies hot parts |
| ; of the control-flow graph. |
| ; |
| ; +-----------+ |
| ; | b1 [?] | |
| ; +-----------+ |
| ; | |
| ; | |
| ; v |
| ; +--------+ +-----------+ |
| ; | b3 [1] | <-- | b2 [5993] | |
| ; +--------+ +-----------+ |
| ; | | |
| ; | | |
| ; | v |
| ; | +-----------+ +--------+ |
| ; | | b4 [5992] | --> | b6 [?] | |
| ; | +-----------+ +--------+ |
| ; | | | |
| ; | | | |
| ; | v | |
| ; | +-----------+ | |
| ; | | b5 [5992] | | |
| ; | +-----------+ | |
| ; | | | |
| ; | | | |
| ; | v | |
| ; | +-----------+ | |
| ; | | b7 [?] | | |
| ; | +-----------+ | |
| ; | | | |
| ; | | | |
| ; | v | |
| ; | +-----------+ | |
| ; | | b8 [5992] | <-----+ |
| ; | +-----------+ |
| ; | | |
| ; | | |
| ; | v |
| ; | +-----------+ |
| ; +----------> | b9 [?] | |
| ; +-----------+ |
| |
| ; Function Attrs: nounwind uwtable |
| define dso_local i32 @sum_of_squares() #0 { |
| b1: |
| call void @llvm.pseudoprobe(i64 -907520326213521421, i64 1, i32 0, i64 -1) |
| %0 = load i32, ptr @yydebug, align 4 |
| %cmp = icmp ne i32 %0, 0 |
| br label %b2 |
| ; CHECK: edge b1 -> b2 probability is 0x80000000 / 0x80000000 = 100.00% |
| ; CHECK2: - b1: float = {{.*}}, int = {{.*}}, count = 5993 |
| |
| b2: |
| call void @llvm.pseudoprobe(i64 -907520326213521421, i64 2, i32 0, i64 -1) |
| br i1 %cmp, label %b4, label %b3 |
| ; CHECK: edge b2 -> b4 probability is 0x7ffa8844 / 0x80000000 = 99.98% |
| ; CHECK: edge b2 -> b3 probability is 0x000577bc / 0x80000000 = 0.02% |
| ; CHECK2: - b2: float = {{.*}}, int = {{.*}}, count = 5993 |
| |
| b3: |
| call void @llvm.pseudoprobe(i64 -907520326213521421, i64 3, i32 0, i64 -1) |
| br label %b9 |
| ; CHECK: edge b3 -> b9 probability is 0x80000000 / 0x80000000 = 100.00% |
| ; CHECK2: - b3: float = {{.*}}, int = {{.*}}, count = 1 |
| |
| b4: |
| call void @llvm.pseudoprobe(i64 -907520326213521421, i64 4, i32 0, i64 -1) |
| br i1 %cmp, label %b5, label %b6 |
| ; CHECK: edge b4 -> b5 probability is 0x80000000 / 0x80000000 = 100.00% |
| ; CHECK: edge b4 -> b6 probability is 0x00000000 / 0x80000000 = 0.00% |
| ; CHECK2: - b4: float = {{.*}}, int = {{.*}}, count = 5992 |
| |
| b5: |
| call void @llvm.pseudoprobe(i64 -907520326213521421, i64 5, i32 0, i64 -1) |
| br label %b7 |
| ; CHECK: edge b5 -> b7 probability is 0x80000000 / 0x80000000 = 100.00% |
| ; CHECK2: - b5: float = {{.*}}, int = {{.*}}, count = 5992 |
| |
| b6: |
| call void @llvm.pseudoprobe(i64 -907520326213521421, i64 6, i32 0, i64 -1) |
| br label %b8 |
| ; CHECK: edge b6 -> b8 probability is 0x80000000 / 0x80000000 = 100.00% |
| ; CHECK2: - b6: float = {{.*}}, int = {{.*}}, count = 0 |
| |
| b7: |
| call void @llvm.pseudoprobe(i64 -907520326213521421, i64 7, i32 0, i64 -1) |
| br label %b8 |
| ; CHECK: edge b7 -> b8 probability is 0x80000000 / 0x80000000 = 100.00% |
| ; CHECK2: - b7: float = {{.*}}, int = {{.*}}, count = 5992 |
| |
| b8: |
| call void @llvm.pseudoprobe(i64 -907520326213521421, i64 8, i32 0, i64 -1) |
| br label %b9 |
| ; CHECK: edge b8 -> b9 probability is 0x80000000 / 0x80000000 = 100.00% |
| ; CHECK2: - b8: float = {{.*}}, int = {{.*}}, count = 5992 |
| |
| b9: |
| call void @llvm.pseudoprobe(i64 -907520326213521421, i64 9, i32 0, i64 -1) |
| ret i32 %0 |
| } |
| ; CHECK2: - b9: float = {{.*}}, int = {{.*}}, count = 5993 |
| |
| |
| declare void @llvm.pseudoprobe(i64, i64, i32, i64) #1 |
| |
| attributes #0 = { noinline nounwind uwtable "use-sample-profile"} |
| attributes #1 = { nounwind } |
| |
| !llvm.pseudo_probe_desc = !{!6, !7, !8, !9} |
| |
| !6 = !{i64 7964825052912775246, i64 4294967295, !"test_1", null} |
| !7 = !{i64 -6216829535442445639, i64 37753817093, !"test_2", null} |
| !8 = !{i64 1649282507922421973, i64 69502983527, !"test_3", null} |
| !9 = !{i64 -907520326213521421, i64 175862120757, !"sum_of_squares", null} |