brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.5 KiB · af93d56 Raw
238 lines · plain
1;; This test ensures that the logic which assigns calls to stack nodes2;; correctly handles cloning of a callsite for a trimmed cold context3;; that partially overlaps with a longer context for a different allocation.4 5;; The profile data and call stacks were all manually added, but the code6;; would be structured something like the following (fairly contrived to7;; result in the type of control flow needed to test):8 9;; void A(bool b) {10;;   if (b)11;;     // cold: stack ids 10, 12, 13, 15 (trimmed ids 19, 20)12;;     // not cold: stack ids 10, 12, 13, 14 (trimmed id 21)13;;     new char[10]; // stack id 1014;;   else15;;     // not cold: stack ids 11, 12, 13, 15, 16, 17 (trimmed id 22)16;;     // cold: stack ids 11, 12, 13, 15, 16, 18 (trimmed id 23)17;;     new char[10]; // stack id 1118;; }19;;20;; void X(bool b) {21;;   A(b); // stack ids 1222;; }23;;24;; void B(bool b) {25;;   X(b); // stack id 1326;; }27;;28;; void D() {29;;   B(true); // stack id 1430;; }31;;32;; void C(bool b) {33;;   B(b); // stack id 1534;; }35;;36;; void E(bool b) {37;;   C(b); // stack id 1638;; }39;;40;; void F() {41;;   E(false); // stack id 1742;; }43;;44;; void G() {45;;   E(false); // stack id 1846;; }47;;48;; void M() {49;;   C(true); // stack id 1950;; }51;;52;; int main() {53;;   D(); // stack id 20 (leads to not cold allocation)54;;   M(); // stack id 21 (leads to cold allocation)55;;   F(); // stack id 22 (leads to not cold allocation)56;;   G(); // stack id 23 (leads to cold allocation)57;; }58 59;; -stats requires asserts60; REQUIRES: asserts61 62; RUN: opt -passes=memprof-context-disambiguation -supports-hot-cold-new \63; RUN:	-memprof-verify-ccg -memprof-verify-nodes \64; RUN:  -stats -pass-remarks=memprof-context-disambiguation \65; RUN:	%s -S 2>&1 | FileCheck %s --check-prefix=IR \66; RUN:  --check-prefix=STATS --check-prefix=REMARKS67 68; REMARKS: created clone _Z1Ab.memprof.169; REMARKS: created clone _Z1Xb.memprof.170; REMARKS: created clone _Z1Xb.memprof.271; REMARKS: created clone _Z1Bb.memprof.172; REMARKS: created clone _Z1Bb.memprof.273; REMARKS: created clone _Z1Cb.memprof.174; REMARKS: created clone _Z1Eb.memprof.175; REMARKS: call in clone _Z1Gv assigned to call function clone _Z1Eb.memprof.176; REMARKS: call in clone _Z1Eb.memprof.1 assigned to call function clone _Z1Cb.memprof.177;; If we don't perform cloning for each allocation separately, we will miss78;; cloning _Z1Cb for the trimmed cold allocation context leading to the79;; allocation at stack id 10.80; REMARKS: call in clone _Z1Cb.memprof.1 assigned to call function clone _Z1Bb.memprof.181; REMARKS: call in clone _Z1Fv assigned to call function clone _Z1Eb82; REMARKS: call in clone _Z1Eb assigned to call function clone _Z1Cb83; REMARKS: call in clone _Z1Cb assigned to call function clone _Z1Bb.memprof.284; REMARKS: call in clone _Z1Bb.memprof.2 assigned to call function clone _Z1Xb.memprof.285; REMARKS: call in clone _Z1Xb.memprof.2 assigned to call function clone _Z1Ab.memprof.186; REMARKS: call in clone _Z1Ab.memprof.1 marked with memprof allocation attribute cold87; REMARKS: call in clone _Z1Bb.memprof.1 assigned to call function clone _Z1Xb.memprof.188; REMARKS: call in clone _Z1Xb.memprof.1 assigned to call function clone _Z1Ab89; REMARKS: call in clone _Z1Dv assigned to call function clone _Z1Bb90; REMARKS: call in clone _Z1Bb assigned to call function clone _Z1Xb91; REMARKS: call in clone _Z1Xb assigned to call function clone _Z1Ab92; REMARKS: call in clone _Z1Ab marked with memprof allocation attribute notcold93; REMARKS: call in clone _Z1Ab marked with memprof allocation attribute cold94; REMARKS: call in clone _Z1Ab.memprof.1 marked with memprof allocation attribute notcold95 96 97target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"98target triple = "x86_64-unknown-linux-gnu"99 100define dso_local void @_Z1Ab(i1 noundef zeroext %b) {101entry:102  br i1 %b, label %if.then, label %if.else103 104if.then:105  %call = call noalias noundef nonnull ptr @_Znam(i64 noundef 10) #7, !memprof !0, !callsite !10106  br label %if.end107 108if.else:109  %call2 = call noalias noundef nonnull ptr @_Znam(i64 noundef 10) #7, !memprof !5, !callsite !11110  br label %if.end111 112if.end:113  ret void114}115 116; Function Attrs: nobuiltin117declare ptr @_Znam(i64) #0118 119define dso_local void @_Z1Xb(i1 noundef zeroext %b) {120entry:121  tail call void @_Z1Ab(i1 noundef zeroext %b), !callsite !12122  ret void123}124 125define dso_local void @_Z1Bb(i1 noundef zeroext %b) {126entry:127  tail call void @_Z1Xb(i1 noundef zeroext %b), !callsite !13128  ret void129}130 131define dso_local void @_Z1Dv() {132entry:133  tail call void @_Z1Bb(i1 noundef zeroext true), !callsite !14134  ret void135}136 137define dso_local void @_Z1Cb(i1 noundef zeroext %b) {138entry:139  tail call void @_Z1Bb(i1 noundef zeroext %b), !callsite !15140  ret void141}142 143define dso_local void @_Z1Eb(i1 noundef zeroext %b) {144entry:145  tail call void @_Z1Cb(i1 noundef zeroext %b), !callsite !16146  ret void147}148 149define dso_local void @_Z1Fv() {150entry:151  tail call void @_Z1Eb(i1 noundef zeroext false), !callsite !17152  ret void153}154 155define dso_local void @_Z1Gv() {156entry:157  tail call void @_Z1Eb(i1 noundef zeroext false), !callsite !18158  ret void159}160 161define dso_local void @_Z1Mv() {162entry:163  tail call void @_Z1Cb(i1 noundef zeroext true), !callsite !19164  ret void165}166 167define dso_local noundef i32 @main() local_unnamed_addr {168entry:169  tail call void @_Z1Dv(), !callsite !20 ;; Not cold context170  tail call void @_Z1Mv(), !callsite !21 ;; Cold context171  tail call void @_Z1Fv(), !callsite !22 ;; Not cold context172  tail call void @_Z1Gv(), !callsite !23 ;; Cold context173  ret i32 0174}175 176attributes #0 = { nobuiltin }177attributes #7 = { builtin }178 179!0 = !{!1, !3}180;; Cold (trimmed) context via call to _Z1Dv in main181!1 = !{!2, !"cold"}182!2 = !{i64 10, i64 12, i64 13, i64 15}183;; Not cold (trimmed) context via call to _Z1Mv in main184!3 = !{!4, !"notcold"}185!4 = !{i64 10, i64 12, i64 13, i64 14}186!5 = !{!6, !8}187;; Not cold (trimmed) context via call to _Z1Fv in main188!6 = !{!7, !"notcold"}189!7 = !{i64 11, i64 12, i64 13, i64 15, i64 16, i64 17}190;; Cold (trimmed) context via call to _Z1Gv in main191!8 = !{!9, !"cold"}192!9 = !{i64 11, i64 12, i64 13, i64 15, i64 16, i64 18}193!10 = !{i64 10}194!11 = !{i64 11}195!12 = !{i64 12}196!13 = !{i64 13}197!14 = !{i64 14}198!15 = !{i64 15}199!16 = !{i64 16}200!17 = !{i64 17}201!18 = !{i64 18}202!19 = !{i64 19}203!20 = !{i64 20}204!21 = !{i64 21}205!22 = !{i64 22}206!23 = !{i64 23}207 208; IR: define {{.*}} @_Z1Cb(i1 noundef zeroext %b)209; IR-NEXT: entry:210; IR-NEXT:   call {{.*}} @_Z1Bb.memprof.2(i1 noundef zeroext %b)211 212; IR: define {{.*}} @_Z1Ab.memprof.1(i1 noundef zeroext %b)213; IR-NEXT: entry:214; IR-NEXT:   br i1 %b, label %if.then, label %if.else215; IR-EMPTY:216; IR-NEXT: if.then:217; IR-NEXT:   call {{.*}} @_Znam(i64 noundef 10) #[[COLD:[0-9]+]]218; IR-NEXT:   br label %if.end219; IR-EMPTY:220; IR-NEXT: if.else:221; IR-NEXT:   call {{.*}} @_Znam(i64 noundef 10) #[[NOTCOLD:[0-9]+]]222 223; IR: define {{.*}} @_Z1Xb.memprof.2(i1 noundef zeroext %b)224; IR-NEXT: entry:225; IR-NEXT:   call {{.*}} @_Z1Ab.memprof.1(i1 noundef zeroext %b)226 227; IR: define {{.*}} @_Z1Bb.memprof.2(i1 noundef zeroext %b)228; IR-NEXT: entry:229; IR-NEXT:   call {{.*}} @_Z1Xb.memprof.2(i1 noundef zeroext %b)230 231; IR: attributes #[[NOTCOLD]] = { builtin "memprof"="notcold" }232; IR: attributes #[[COLD]] = { builtin "memprof"="cold" }233 234; STATS: 2 memprof-context-disambiguation - Number of cold static allocations (possibly cloned)235; STATS: 2 memprof-context-disambiguation - Number of not cold static allocations (possibly cloned)236; STATS: 7 memprof-context-disambiguation - Number of function clones created during whole program analysis237; STATS: 2 memprof-context-disambiguation - Number of new nodes created during merging238