299 lines · plain
1;; This test case is the same as memprof-icp.ll but manually modified to2;; add recursive cycles into the allocation contexts, and it has3;; -memprof-allow-recursive-callsites enabled to test that handling.4;; The call contexts are somewhat nonsensical, but designed to provoke5;; several scenarios that were seen in large applications and caused6;; failures until they were addressed. In particular, converting mutual7;; recursion to direct recursion when stack nodes are matched onto inlined8;; callsites; edge partitioning due to multiple calls with the same debug9;; info (here because it is an indirect call) requiring updating/moving10;; of recursive contexts; and the necessary updates of recursive contexts11;; and edges during cloning.12 13;; The checks are however not modified from the original memprof-icp.ll test:14;; when basic recursive callsite handling is enabled (which currently doesn't15;; clone through recursive cycles but is designed to at least allow cloning16;; across them for the the non-recursive call sequence of the context) we17;; should successfully get the same cloning as without any recursion.18 19;; -stats requires asserts20; REQUIRES: asserts21 22; RUN: split-file %s %t23 24;; For now explicitly turn on this handling, which is off by default.25; RUN: opt -thinlto-bc %t/main.ll -enable-memprof-indirect-call-support=true >%t/main.o26; RUN: opt -thinlto-bc %t/foo.ll -enable-memprof-indirect-call-support=true >%t/foo.o27 28;; First perform in-process ThinLTO29; RUN: llvm-lto2 run %t/main.o %t/foo.o -enable-memprof-context-disambiguation \30; RUN: -enable-memprof-indirect-call-support=true \31; RUN: -memprof-allow-recursive-callsites \32; RUN: -supports-hot-cold-new \33; RUN: -r=%t/foo.o,_Z3fooR2B0j,plx \34; RUN: -r=%t/foo.o,_ZN2B03barEj, \35; RUN: -r=%t/foo.o,_ZN1B3barEj, \36; RUN: -r=%t/main.o,_Z3fooR2B0j, \37; RUN: -r=%t/main.o,_Znwm, \38; RUN: -r=%t/main.o,_ZdlPvm, \39; RUN: -r=%t/main.o,_Z8externalPi, \40; RUN: -r=%t/main.o,main,plx \41; RUN: -r=%t/main.o,_ZN2B03barEj,plx \42; RUN: -r=%t/main.o,_ZN1B3barEj,plx \43; RUN: -r=%t/main.o,_ZTV1B,plx \44; RUN: -r=%t/main.o,_ZTVN10__cxxabiv120__si_class_type_infoE,plx \45; RUN: -r=%t/main.o,_ZTS1B,plx \46; RUN: -r=%t/main.o,_ZTVN10__cxxabiv117__class_type_infoE,plx \47; RUN: -r=%t/main.o,_ZTS2B0,plx \48; RUN: -r=%t/main.o,_ZTI2B0,plx \49; RUN: -r=%t/main.o,_ZTI1B,plx \50; RUN: -r=%t/main.o,_ZTV2B0,plx \51; RUN: -thinlto-threads=1 \52; RUN: -memprof-verify-ccg -memprof-verify-nodes -stats \53; RUN: -pass-remarks=. -save-temps \54; RUN: -o %t.out 2>&1 | FileCheck %s --check-prefix=STATS \55; RUN: --check-prefix=REMARKS56 57; RUN: llvm-dis %t.out.2.4.opt.bc -o - | FileCheck %s --check-prefixes=IR,IR-INLINE58 59;; Next, add a threshold to prevent inlining of the promoted calls which have60;; count 2 (the default threshold of 2 means they are inlinable by default).61; RUN: llvm-lto2 run %t/main.o %t/foo.o -enable-memprof-context-disambiguation \62; RUN: -memprof-icp-noinline-threshold=3 \63; RUN: -enable-memprof-indirect-call-support=true \64; RUN: -memprof-allow-recursive-callsites \65; RUN: -supports-hot-cold-new \66; RUN: -r=%t/foo.o,_Z3fooR2B0j,plx \67; RUN: -r=%t/foo.o,_ZN2B03barEj, \68; RUN: -r=%t/foo.o,_ZN1B3barEj, \69; RUN: -r=%t/main.o,_Z3fooR2B0j, \70; RUN: -r=%t/main.o,_Znwm, \71; RUN: -r=%t/main.o,_ZdlPvm, \72; RUN: -r=%t/main.o,_Z8externalPi, \73; RUN: -r=%t/main.o,main,plx \74; RUN: -r=%t/main.o,_ZN2B03barEj,plx \75; RUN: -r=%t/main.o,_ZN1B3barEj,plx \76; RUN: -r=%t/main.o,_ZTV1B,plx \77; RUN: -r=%t/main.o,_ZTVN10__cxxabiv120__si_class_type_infoE,plx \78; RUN: -r=%t/main.o,_ZTS1B,plx \79; RUN: -r=%t/main.o,_ZTVN10__cxxabiv117__class_type_infoE,plx \80; RUN: -r=%t/main.o,_ZTS2B0,plx \81; RUN: -r=%t/main.o,_ZTI2B0,plx \82; RUN: -r=%t/main.o,_ZTI1B,plx \83; RUN: -r=%t/main.o,_ZTV2B0,plx \84; RUN: -thinlto-threads=1 \85; RUN: -memprof-verify-ccg -memprof-verify-nodes -stats \86; RUN: -pass-remarks=. -save-temps \87; RUN: -o %t.out 2>&1 | FileCheck %s --check-prefix=STATS \88; RUN: --check-prefix=REMARKS89 90; RUN: llvm-dis %t.out.2.4.opt.bc -o - | FileCheck %s --check-prefixes=IR,IR-NOINLINE91 92; REMARKS: call in clone main assigned to call function clone _Z3fooR2B0j.memprof.193; REMARKS: call in clone main assigned to call function clone _Z3fooR2B0j.memprof.194; REMARKS: created clone _ZN2B03barEj.memprof.195; REMARKS: call in clone _ZN2B03barEj marked with memprof allocation attribute notcold96; REMARKS: call in clone _ZN2B03barEj.memprof.1 marked with memprof allocation attribute cold97; REMARKS: call in clone _ZN2B03barEj marked with memprof allocation attribute notcold98; REMARKS: call in clone _ZN2B03barEj.memprof.1 marked with memprof allocation attribute cold99; REMARKS: created clone _ZN1B3barEj.memprof.1100; REMARKS: call in clone _ZN1B3barEj marked with memprof allocation attribute notcold101; REMARKS: call in clone _ZN1B3barEj.memprof.1 marked with memprof allocation attribute cold102; REMARKS: call in clone _ZN1B3barEj marked with memprof allocation attribute notcold103; REMARKS: call in clone _ZN1B3barEj.memprof.1 marked with memprof allocation attribute cold104; REMARKS: created clone _Z3fooR2B0j.memprof.1105;; In each version of foo we should have promoted the indirect call to two conditional106;; direct calls, one to B::bar and one to B0::bar. The cloned version of foo should call107;; the cloned versions of bar for both promotions.108; REMARKS: Promote indirect call to _ZN1B3barEj with count 2 out of 4109; REMARKS: call in clone _Z3fooR2B0j promoted and assigned to call function clone _ZN1B3barEj110; REMARKS: Promote indirect call to _ZN1B3barEj with count 2 out of 4111; REMARKS: call in clone _Z3fooR2B0j.memprof.1 promoted and assigned to call function clone _ZN1B3barEj.memprof.1112; REMARKS: Promote indirect call to _ZN2B03barEj with count 2 out of 2113; REMARKS: call in clone _Z3fooR2B0j promoted and assigned to call function clone _ZN2B03barEj114; REMARKS: Promote indirect call to _ZN2B03barEj with count 2 out of 2115; REMARKS: call in clone _Z3fooR2B0j.memprof.1 promoted and assigned to call function clone _ZN2B03barEj.memprof.1116; REMARKS: created clone _ZN2B03barEj.memprof.1117; REMARKS: call in clone _ZN2B03barEj marked with memprof allocation attribute notcold118; REMARKS: call in clone _ZN2B03barEj.memprof.1 marked with memprof allocation attribute cold119; REMARKS: created clone _ZN1B3barEj.memprof.1120; REMARKS: call in clone _ZN1B3barEj marked with memprof allocation attribute notcold121; REMARKS: call in clone _ZN1B3barEj.memprof.1 marked with memprof allocation attribute cold122 123; STATS: 4 memprof-context-disambiguation - Number of cold static allocations (possibly cloned) during whole program analysis124; STATS: 8 memprof-context-disambiguation - Number of cold static allocations (possibly cloned) during ThinLTO backend125; STATS: 4 memprof-context-disambiguation - Number of not cold static allocations (possibly cloned) during whole program analysis126; STATS: 8 memprof-context-disambiguation - Number of not cold static allocations (possibly cloned) during ThinLTO backend127; STATS: 3 memprof-context-disambiguation - Number of function clones created during whole program analysis128; STATS: 5 memprof-context-disambiguation - Number of function clones created during ThinLTO backend129 130; IR: define {{.*}} @_Z3fooR2B0j(131; IR: %[[R1:[0-9]+]] = icmp eq ptr %0, @_ZN1B3barEj132; IR: br i1 %[[R1]], label %if.true.direct_targ, label %if.false.orig_indirect133; IR: if.true.direct_targ:134; IR-INLINE: call {{.*}} @_Znwm(i64 noundef 4) #[[NOTCOLD:[0-9]+]]135; IR-NOINLINE: call {{.*}} @_ZN1B3barEj(ptr null, i32 0) #[[NOINLINE:[0-9]+]]136; IR: if.false.orig_indirect:137; IR: %[[R2:[0-9]+]] = icmp eq ptr %0, @_ZN2B03barEj138; IR: br i1 %[[R2]], label %if.true.direct_targ1, label %if.false.orig_indirect2139; IR: if.true.direct_targ1:140; IR-INLINE: call {{.*}} @_Znwm(i64 noundef 4) #[[NOTCOLD]]141; IR-NOINLINE: call {{.*}} @_ZN2B03barEj(ptr null, i32 0) #[[NOINLINE]]142; IR: if.false.orig_indirect2:143; IR: call {{.*}} %0144 145; IR: define {{.*}} @_Z3fooR2B0j.memprof.1(146;; We should still compare against the original versions of bar since that is147;; what is in the vtable. However, we should have called the cloned versions148;; that perform cold allocations, which were subsequently inlined.149; IR: %[[R3:[0-9]+]] = icmp eq ptr %0, @_ZN1B3barEj150; IR: br i1 %[[R3]], label %if.true.direct_targ, label %if.false.orig_indirect151; IR: if.true.direct_targ:152; IR-INLINE: call {{.*}} @_Znwm(i64 noundef 4) #[[COLD:[0-9]+]]153; IR-NOINLINE: call {{.*}} @_ZN1B3barEj.memprof.1(ptr null, i32 0) #[[NOINLINE]]154; IR: if.false.orig_indirect:155; IR: %[[R4:[0-9]+]] = icmp eq ptr %0, @_ZN2B03barEj156; IR: br i1 %[[R4]], label %if.true.direct_targ1, label %if.false.orig_indirect2157; IR: if.true.direct_targ1:158; IR-INLINE: call {{.*}} @_Znwm(i64 noundef 4) #[[COLD]]159; IR-NOINLINE: call {{.*}} @_ZN2B03barEj.memprof.1(ptr null, i32 0) #[[NOINLINE]]160; IR: if.false.orig_indirect2:161; IR: call {{.*}} %0162 163; IR-INLINE: attributes #[[NOTCOLD]] = {{.*}} "memprof"="notcold"164; IR-INLINE: attributes #[[COLD]] = {{.*}} "memprof"="cold"165; IR-NOINLINE: attributes #[[NOINLINE]] = { noinline }166 167;--- foo.ll168target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"169target triple = "x86_64-unknown-linux-gnu"170 171declare i32 @_ZN2B03barEj(ptr %this, i32 %s)172declare i32 @_ZN1B3barEj(ptr %this, i32 %s)173 174define i32 @_Z3fooR2B0j(ptr %b) {175entry:176 %0 = load ptr, ptr %b, align 8177 %call = tail call i32 %0(ptr null, i32 0), !prof !0, !callsite !1178 ret i32 0179}180 181!0 = !{!"VP", i32 0, i64 4, i64 4445083295448962937, i64 2, i64 -2718743882639408571, i64 2}182!1 = !{i64 -2101080423462424381, i64 3456}183 184;--- main.ll185target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"186target triple = "x86_64-unknown-linux-gnu"187 188@_ZTV1B = external constant { [3 x ptr] }189@_ZTVN10__cxxabiv120__si_class_type_infoE = external global [0 x ptr]190@_ZTS1B = external constant [3 x i8]191@_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]192@_ZTS2B0 = external constant [4 x i8]193@_ZTI2B0 = external constant { ptr, ptr }194@_ZTI1B = external constant { ptr, ptr, ptr }195@_ZTV2B0 = external constant { [3 x ptr] }196 197define i32 @main() !prof !29 {198entry:199 %call2 = call i32 @_Z3fooR2B0j(ptr null, i32 0), !callsite !30200 %call4 = call i32 @_Z3fooR2B0j(ptr null, i32 0), !callsite !31201 %call6 = call i32 @_Z3fooR2B0j(ptr null, i32 0), !callsite !32202 %call8 = call i32 @_Z3fooR2B0j(ptr null, i32 0), !callsite !57203 ret i32 0204}205 206declare i32 @_Z3fooR2B0j(ptr, i32)207 208define i32 @_ZN2B03barEj(ptr %this, i32 %s) {209entry:210 %call = tail call ptr @_Znwm(i64 noundef 4) #0, !memprof !33, !callsite !38211 ;; Second allocation in this function, to ensure that indirect edges to the212 ;; same callee are partitioned correctly.213 %call2 = tail call ptr @_Znwm(i64 noundef 4) #0, !memprof !45, !callsite !50214 store volatile i32 0, ptr %call, align 4215 ret i32 0216}217 218declare ptr @_Znwm(i64)219 220declare void @_Z8externalPi()221 222declare void @_ZdlPvm()223 224define i32 @_ZN1B3barEj(ptr %this, i32 %s) {225entry:226 %call = tail call ptr @_Znwm(i64 noundef 4) #0, !memprof !39, !callsite !44227 ;; Second allocation in this function, to ensure that indirect edges to the228 ;; same callee are partitioned correctly.229 %call2 = tail call ptr @_Znwm(i64 noundef 4) #0, !memprof !51, !callsite !56230 store volatile i32 0, ptr %call, align 4231 ret i32 0232}233 234; uselistorder directives235uselistorder ptr @_Z3fooR2B0j, { 3, 2, 1, 0 }236 237attributes #0 = { builtin allocsize(0) }238 239!llvm.module.flags = !{!0}240 241!0 = !{i32 1, !"ProfileSummary", !1}242!1 = !{!2, !3, !4, !5, !6, !7, !8, !9, !10, !11}243!2 = !{!"ProfileFormat", !"InstrProf"}244!3 = !{!"TotalCount", i64 13}245!4 = !{!"MaxCount", i64 4}246!5 = !{!"MaxInternalCount", i64 0}247!6 = !{!"MaxFunctionCount", i64 4}248!7 = !{!"NumCounts", i64 5}249!8 = !{!"NumFunctions", i64 5}250!9 = !{!"IsPartialProfile", i64 0}251!10 = !{!"PartialProfileRatio", double 0.000000e+00}252!11 = !{!"DetailedSummary", !12}253!12 = !{!13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28}254!13 = !{i32 10000, i64 0, i32 0}255!14 = !{i32 100000, i64 4, i32 2}256!15 = !{i32 200000, i64 4, i32 2}257!16 = !{i32 300000, i64 4, i32 2}258!17 = !{i32 400000, i64 4, i32 2}259!18 = !{i32 500000, i64 4, i32 2}260!19 = !{i32 600000, i64 4, i32 2}261!20 = !{i32 700000, i64 2, i32 4}262!21 = !{i32 800000, i64 2, i32 4}263!22 = !{i32 900000, i64 2, i32 4}264!23 = !{i32 950000, i64 2, i32 4}265!24 = !{i32 990000, i64 2, i32 4}266!25 = !{i32 999000, i64 2, i32 4}267!26 = !{i32 999900, i64 2, i32 4}268!27 = !{i32 999990, i64 2, i32 4}269!28 = !{i32 999999, i64 2, i32 4}270!29 = !{!"function_entry_count", i64 1}271!30 = !{i64 -6490791336773930154}272!31 = !{i64 5188446645037944434}273!32 = !{i64 5583420417449503557}274!57 = !{i64 132626519179914298}275!33 = !{!34, !36}276!34 = !{!35, !"notcold"}277!35 = !{i64 -852997907418798798, i64 -2101080423462424381, i64 3456, i64 -2101080423462424381, i64 3456, i64 5188446645037944434}278!36 = !{!37, !"cold"}279!37 = !{i64 -852997907418798798, i64 -2101080423462424381, i64 3456, i64 -2101080423462424381, i64 3456, i64 5583420417449503557}280!38 = !{i64 -852997907418798798}281!39 = !{!40, !42}282!40 = !{!41, !"notcold"}283!41 = !{i64 4457553070050523782, i64 -2101080423462424381, i64 3456, i64 -2101080423462424381, i64 3456, i64 132626519179914298}284!42 = !{!43, !"cold"}285!43 = !{i64 4457553070050523782, i64 -2101080423462424381, i64 3456, i64 -2101080423462424381, i64 3456, i64 -6490791336773930154}286!44 = !{i64 4457553070050523782}287!45 = !{!46, !48}288!46 = !{!47, !"notcold"}289!47 = !{i64 456, i64 -2101080423462424381, i64 3456, i64 5188446645037944434}290!48 = !{!49, !"cold"}291!49 = !{i64 456, i64 -2101080423462424381, i64 3456, i64 5583420417449503557}292!50 = !{i64 456}293!51 = !{!52, !54}294!52 = !{!53, !"notcold"}295!53 = !{i64 789, i64 -2101080423462424381, i64 3456, i64 132626519179914298}296!54 = !{!55, !"cold"}297!55 = !{i64 789, i64 -2101080423462424381, i64 3456, i64 -6490791336773930154}298!56 = !{i64 789}299