1; -stats requires asserts 2; REQUIRES: asserts 3 4; Stop after 'finalize-isel' for simpler MIR, and lower the minimum number of 5; jump table entries so 'switch' needs fewer cases to generate a jump table. 6; RUN: llc -mtriple=x86_64-unknown-linux-gnu -stop-after=finalize-isel -min-jump-table-entries=2 %s -o %t.mir 7; RUN: llc -mtriple=x86_64-unknown-linux-gnu --run-pass=static-data-splitter -stats -x mir %t.mir -o - 2>&1 | FileCheck %s --check-prefix=STAT 8 9 ; @foo has 2 hot and 2 cold jump tables. 10 ; The two jump tables with unknown hotness come from @func_without_profile and 11 ; @bar respectively. 12; STAT: 2 static-data-splitter - Number of cold jump tables seen 13; STAT: 2 static-data-splitter - Number of hot jump tables seen 14; STAT: 2 static-data-splitter - Number of jump tables with unknown hotness 15 16; RUN: llc -mtriple=x86_64-unknown-linux-gnu -enable-split-machine-functions \ 17; RUN: -partition-static-data-sections=true -function-sections=true \ 18; RUN: -min-jump-table-entries=2 -unique-section-names=false \ 19; RUN: %s -o - 2>&1 | FileCheck %s --check-prefixes=NUM,JT 20 21; Section names will optionally have `.<func>` if -function-sections is enabled. 22; RUN: llc -mtriple=x86_64-unknown-linux-gnu -enable-split-machine-functions \ 23; RUN: -partition-static-data-sections=true -function-sections=true \ 24; RUN: -min-jump-table-entries=2 %s -o - 2>&1 | FileCheck %s --check-prefixes=FUNC,JT 25 26; RUN: llc -mtriple=x86_64-unknown-linux-gnu -enable-split-machine-functions \ 27; RUN: -partition-static-data-sections=true -function-sections=false \ 28; RUN: -min-jump-table-entries=2 %s -o - 2>&1 | FileCheck %s --check-prefixes=FUNCLESS,JT 29 30; In function @foo, the 2 switch instructions to jt0.* and jt1.* are placed in 31; hot-prefixed sections, and the 2 switch instructions to jt2.* and jt3.* are 32; placed in cold-prefixed sections. 33; NUM: .section .rodata.hot.,"a",@progbits,unique,2 34; FUNC: .section .rodata.hot.foo,"a",@progbits 35; FUNCLESS: .section .rodata.hot.,"a",@progbits 36; JT: .LJTI0_0: 37; JT: .LJTI0_2: 38; NUM: .section .rodata.unlikely.,"a",@progbits,unique,3 39; FUNC: .section .rodata.unlikely.foo,"a",@progbits 40; FUNCLESS: .section .rodata.unlikely.,"a",@progbits 41; JT: .LJTI0_1: 42; JT: .LJTI0_3: 43 44; @func_without_profile simulates the functions without profile information 45; (e.g., not instrumented or not profiled), its jump tables are placed in 46; sections without hot or unlikely prefixes. 47; NUM: .section .rodata,"a",@progbits,unique,5 48; FUNC: .section .rodata.func_without_profile,"a",@progbits 49; FUNCLESS: .section .rodata,"a",@progbits 50; JT: .LJTI1_0: 51 52; @bar doesn't have profile information and it has a section prefix. 53; Tests that its jump tables are placed in sections with function prefixes. 54; NUM: .section .rodata.bar_prefix.,"a",@progbits,unique,7 55; FUNC: .section .rodata.bar_prefix.bar 56; FUNCLESS: .section .rodata.bar_prefix.,"a" 57; JT: .LJTI2_0 58 59target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" 60target triple = "x86_64-unknown-linux-gnu" 61 62@str.9 = private constant [7 x i8] c".str.9\00" 63@str.10 = private constant [8 x i8] c".str.10\00" 64@str.11 = private constant [8 x i8] c".str.11\00" 65 66@case2 = private constant [7 x i8] c"case 2\00" 67@case1 = private constant [7 x i8] c"case 1\00" 68@default = private constant [8 x i8] c"default\00" 69@jt3 = private constant [4 x i8] c"jt3\00" 70 71; jt0 and jt2 are hot. jt1 and jt3 are cold. 72define i32 @foo(i32 %num) !prof !13 { 73entry: 74 %mod3 = sdiv i32 %num, 3 75 switch i32 %mod3, label %jt0.default [ 76 i32 1, label %jt0.bb1 77 i32 2, label %jt0.bb2 78 ], !prof !14 79 80jt0.bb1: 81 call i32 @puts(ptr @case1) 82 br label %jt0.epilog 83 84jt0.bb2: 85 call i32 @puts(ptr @case2) 86 br label %jt0.epilog 87 88jt0.default: 89 call i32 @puts(ptr @default) 90 br label %jt0.epilog 91 92jt0.epilog: 93 %zero = icmp eq i32 %num, 0 94 br i1 %zero, label %hot, label %cold, !prof !17 95 96hot: 97 %c2 = call i32 @transform(i32 %num) 98 switch i32 %c2, label %jt2.default [ 99 i32 1, label %jt2.bb1 100 i32 2, label %jt2.bb2 101 ], !prof !14 102 103jt2.bb1: 104 call i32 @puts(ptr @case1) 105 br label %jt1.epilog 106 107jt2.bb2: 108 call i32 @puts(ptr @case2) 109 br label %jt1.epilog 110 111jt2.default: 112 call i32 @puts(ptr @default) 113 br label %jt2.epilog 114 115jt2.epilog: 116 %c2cmp = icmp ne i32 %c2, 0 117 br i1 %c2cmp, label %return, label %jt3.prologue, !prof !18 118 119cold: 120 %c1 = call i32 @compute(i32 %num) 121 switch i32 %c1, label %jt1.default [ 122 i32 1, label %jt1.bb1 123 i32 2, label %jt1.bb2 124 ], !prof !14 125 126jt1.bb1: 127 call i32 @puts(ptr @case1) 128 br label %jt1.epilog 129 130jt1.bb2: 131 call i32 @puts(ptr @case2) 132 br label %jt1.epilog 133 134jt1.default: 135 call i32 @puts(ptr @default) 136 br label %jt1.epilog 137 138jt1.epilog: 139 br label %return 140 141jt3.prologue: 142 %c3 = call i32 @cleanup(i32 %num) 143 switch i32 %c3, label %jt3.default [ 144 i32 1, label %jt3.bb1 145 i32 2, label %jt3.bb2 146 ], !prof !14 147 148jt3.bb1: 149 call i32 @puts(ptr @case1) 150 br label %jt3.epilog 151 152jt3.bb2: 153 call i32 @puts(ptr @case2) 154 br label %jt3.epilog 155 156jt3.default: 157 call i32 @puts(ptr @default) 158 br label %jt3.epilog 159 160jt3.epilog: 161 call i32 @puts(ptr @jt3) 162 br label %return 163 164return: 165 ret i32 %mod3 166} 167 168define void @func_without_profile(i32 %num) { 169entry: 170 switch i32 %num, label %sw.default [ 171 i32 1, label %sw.bb 172 i32 2, label %sw.bb1 173 ] 174 175sw.bb: 176 call i32 @puts(ptr @str.10) 177 br label %sw.epilog 178 179sw.bb1: 180 call i32 @puts(ptr @str.9) 181 br label %sw.epilog 182 183sw.default: 184 call i32 @puts(ptr @str.11) 185 br label %sw.epilog 186 187sw.epilog: 188 ret void 189} 190 191define void @bar(i32 %num) !section_prefix !20 { 192entry: 193 switch i32 %num, label %sw.default [ 194 i32 1, label %sw.bb 195 i32 2, label %sw.bb1 196 ] 197 198sw.bb: 199 call i32 @puts(ptr @str.10) 200 br label %sw.epilog 201 202sw.bb1: 203 call i32 @puts(ptr @str.9) 204 br label %sw.epilog 205 206sw.default: 207 call i32 @puts(ptr @str.11) 208 br label %sw.epilog 209 210sw.epilog: 211 ret void 212} 213 214declare i32 @puts(ptr) 215declare i32 @printf(ptr, ...) 216declare i32 @compute(i32) 217declare i32 @transform(i32) 218declare i32 @cleanup(i32) 219 220!llvm.module.flags = !{!0} 221 222!0 = !{i32 1, !"ProfileSummary", !1} 223!1 = !{!2, !3, !4, !5, !6, !7, !8, !9} 224!2 = !{!"ProfileFormat", !"InstrProf"} 225!3 = !{!"TotalCount", i64 230002} 226!4 = !{!"MaxCount", i64 100000} 227!5 = !{!"MaxInternalCount", i64 50000} 228!6 = !{!"MaxFunctionCount", i64 100000} 229!7 = !{!"NumCounts", i64 14} 230!8 = !{!"NumFunctions", i64 3} 231!9 = !{!"DetailedSummary", !10} 232!10 = !{!11, !12} 233!11 = !{i32 990000, i64 10000, i32 7} 234!12 = !{i32 999999, i64 1, i32 9} 235!13 = !{!"function_entry_count", i64 100000} 236!14 = !{!"branch_weights", i32 60000, i32 20000, i32 20000} 237!15 = !{!"function_entry_count", i64 1} 238!16 = !{!"branch_weights", i32 1, i32 0, i32 0, i32 0, i32 0, i32 0} 239!17 = !{!"branch_weights", i32 99999, i32 1} 240!18 = !{!"branch_weights", i32 99998, i32 1} 241!19 = !{!"branch_weights", i32 97000, i32 1000, i32 1000, i32 1000} 242!20 = !{!"function_section_prefix", !"bar_prefix"} 243