CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
238 lines
7.5 KiB
LLVM
238 lines
7.5 KiB
LLVM
;; This test ensures that the logic which assigns calls to stack nodes
|
|
;; correctly handles cloning of a callsite for a trimmed cold context
|
|
;; that partially overlaps with a longer context for a different allocation.
|
|
|
|
;; The profile data and call stacks were all manually added, but the code
|
|
;; would be structured something like the following (fairly contrived to
|
|
;; result in the type of control flow needed to test):
|
|
|
|
;; void A(bool b) {
|
|
;; if (b)
|
|
;; // cold: stack ids 10, 12, 13, 15 (trimmed ids 19, 20)
|
|
;; // not cold: stack ids 10, 12, 13, 14 (trimmed id 21)
|
|
;; new char[10]; // stack id 10
|
|
;; else
|
|
;; // not cold: stack ids 11, 12, 13, 15, 16, 17 (trimmed id 22)
|
|
;; // cold: stack ids 11, 12, 13, 15, 16, 18 (trimmed id 23)
|
|
;; new char[10]; // stack id 11
|
|
;; }
|
|
;;
|
|
;; void X(bool b) {
|
|
;; A(b); // stack ids 12
|
|
;; }
|
|
;;
|
|
;; void B(bool b) {
|
|
;; X(b); // stack id 13
|
|
;; }
|
|
;;
|
|
;; void D() {
|
|
;; B(true); // stack id 14
|
|
;; }
|
|
;;
|
|
;; void C(bool b) {
|
|
;; B(b); // stack id 15
|
|
;; }
|
|
;;
|
|
;; void E(bool b) {
|
|
;; C(b); // stack id 16
|
|
;; }
|
|
;;
|
|
;; void F() {
|
|
;; E(false); // stack id 17
|
|
;; }
|
|
;;
|
|
;; void G() {
|
|
;; E(false); // stack id 18
|
|
;; }
|
|
;;
|
|
;; void M() {
|
|
;; C(true); // stack id 19
|
|
;; }
|
|
;;
|
|
;; int main() {
|
|
;; D(); // stack id 20 (leads to not cold allocation)
|
|
;; M(); // stack id 21 (leads to cold allocation)
|
|
;; F(); // stack id 22 (leads to not cold allocation)
|
|
;; G(); // stack id 23 (leads to cold allocation)
|
|
;; }
|
|
|
|
;; -stats requires asserts
|
|
; REQUIRES: asserts
|
|
|
|
; RUN: opt -passes=memprof-context-disambiguation -supports-hot-cold-new \
|
|
; RUN: -memprof-verify-ccg -memprof-verify-nodes \
|
|
; RUN: -stats -pass-remarks=memprof-context-disambiguation \
|
|
; RUN: %s -S 2>&1 | FileCheck %s --check-prefix=IR \
|
|
; RUN: --check-prefix=STATS --check-prefix=REMARKS
|
|
|
|
; REMARKS: created clone _Z1Ab.memprof.1
|
|
; REMARKS: created clone _Z1Xb.memprof.1
|
|
; REMARKS: created clone _Z1Xb.memprof.2
|
|
; REMARKS: created clone _Z1Bb.memprof.1
|
|
; REMARKS: created clone _Z1Bb.memprof.2
|
|
; REMARKS: created clone _Z1Cb.memprof.1
|
|
; REMARKS: created clone _Z1Eb.memprof.1
|
|
; REMARKS: call in clone _Z1Gv assigned to call function clone _Z1Eb.memprof.1
|
|
; REMARKS: call in clone _Z1Eb.memprof.1 assigned to call function clone _Z1Cb.memprof.1
|
|
;; If we don't perform cloning for each allocation separately, we will miss
|
|
;; cloning _Z1Cb for the trimmed cold allocation context leading to the
|
|
;; allocation at stack id 10.
|
|
; REMARKS: call in clone _Z1Cb.memprof.1 assigned to call function clone _Z1Bb.memprof.1
|
|
; REMARKS: call in clone _Z1Fv assigned to call function clone _Z1Eb
|
|
; REMARKS: call in clone _Z1Eb assigned to call function clone _Z1Cb
|
|
; REMARKS: call in clone _Z1Cb assigned to call function clone _Z1Bb.memprof.2
|
|
; REMARKS: call in clone _Z1Bb.memprof.2 assigned to call function clone _Z1Xb.memprof.2
|
|
; REMARKS: call in clone _Z1Xb.memprof.2 assigned to call function clone _Z1Ab.memprof.1
|
|
; REMARKS: call in clone _Z1Ab.memprof.1 marked with memprof allocation attribute cold
|
|
; REMARKS: call in clone _Z1Bb.memprof.1 assigned to call function clone _Z1Xb.memprof.1
|
|
; REMARKS: call in clone _Z1Xb.memprof.1 assigned to call function clone _Z1Ab
|
|
; REMARKS: call in clone _Z1Dv assigned to call function clone _Z1Bb
|
|
; REMARKS: call in clone _Z1Bb assigned to call function clone _Z1Xb
|
|
; REMARKS: call in clone _Z1Xb assigned to call function clone _Z1Ab
|
|
; REMARKS: call in clone _Z1Ab marked with memprof allocation attribute notcold
|
|
; REMARKS: call in clone _Z1Ab marked with memprof allocation attribute cold
|
|
; REMARKS: call in clone _Z1Ab.memprof.1 marked with memprof allocation attribute notcold
|
|
|
|
|
|
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-unknown-linux-gnu"
|
|
|
|
define dso_local void @_Z1Ab(i1 noundef zeroext %b) {
|
|
entry:
|
|
br i1 %b, label %if.then, label %if.else
|
|
|
|
if.then:
|
|
%call = call noalias noundef nonnull ptr @_Znam(i64 noundef 10) #7, !memprof !0, !callsite !10
|
|
br label %if.end
|
|
|
|
if.else:
|
|
%call2 = call noalias noundef nonnull ptr @_Znam(i64 noundef 10) #7, !memprof !5, !callsite !11
|
|
br label %if.end
|
|
|
|
if.end:
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: nobuiltin
|
|
declare ptr @_Znam(i64) #0
|
|
|
|
define dso_local void @_Z1Xb(i1 noundef zeroext %b) {
|
|
entry:
|
|
tail call void @_Z1Ab(i1 noundef zeroext %b), !callsite !12
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @_Z1Bb(i1 noundef zeroext %b) {
|
|
entry:
|
|
tail call void @_Z1Xb(i1 noundef zeroext %b), !callsite !13
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @_Z1Dv() {
|
|
entry:
|
|
tail call void @_Z1Bb(i1 noundef zeroext true), !callsite !14
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @_Z1Cb(i1 noundef zeroext %b) {
|
|
entry:
|
|
tail call void @_Z1Bb(i1 noundef zeroext %b), !callsite !15
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @_Z1Eb(i1 noundef zeroext %b) {
|
|
entry:
|
|
tail call void @_Z1Cb(i1 noundef zeroext %b), !callsite !16
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @_Z1Fv() {
|
|
entry:
|
|
tail call void @_Z1Eb(i1 noundef zeroext false), !callsite !17
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @_Z1Gv() {
|
|
entry:
|
|
tail call void @_Z1Eb(i1 noundef zeroext false), !callsite !18
|
|
ret void
|
|
}
|
|
|
|
define dso_local void @_Z1Mv() {
|
|
entry:
|
|
tail call void @_Z1Cb(i1 noundef zeroext true), !callsite !19
|
|
ret void
|
|
}
|
|
|
|
define dso_local noundef i32 @main() local_unnamed_addr {
|
|
entry:
|
|
tail call void @_Z1Dv(), !callsite !20 ;; Not cold context
|
|
tail call void @_Z1Mv(), !callsite !21 ;; Cold context
|
|
tail call void @_Z1Fv(), !callsite !22 ;; Not cold context
|
|
tail call void @_Z1Gv(), !callsite !23 ;; Cold context
|
|
ret i32 0
|
|
}
|
|
|
|
attributes #0 = { nobuiltin }
|
|
attributes #7 = { builtin }
|
|
|
|
!0 = !{!1, !3}
|
|
;; Cold (trimmed) context via call to _Z1Dv in main
|
|
!1 = !{!2, !"cold"}
|
|
!2 = !{i64 10, i64 12, i64 13, i64 15}
|
|
;; Not cold (trimmed) context via call to _Z1Mv in main
|
|
!3 = !{!4, !"notcold"}
|
|
!4 = !{i64 10, i64 12, i64 13, i64 14}
|
|
!5 = !{!6, !8}
|
|
;; Not cold (trimmed) context via call to _Z1Fv in main
|
|
!6 = !{!7, !"notcold"}
|
|
!7 = !{i64 11, i64 12, i64 13, i64 15, i64 16, i64 17}
|
|
;; Cold (trimmed) context via call to _Z1Gv in main
|
|
!8 = !{!9, !"cold"}
|
|
!9 = !{i64 11, i64 12, i64 13, i64 15, i64 16, i64 18}
|
|
!10 = !{i64 10}
|
|
!11 = !{i64 11}
|
|
!12 = !{i64 12}
|
|
!13 = !{i64 13}
|
|
!14 = !{i64 14}
|
|
!15 = !{i64 15}
|
|
!16 = !{i64 16}
|
|
!17 = !{i64 17}
|
|
!18 = !{i64 18}
|
|
!19 = !{i64 19}
|
|
!20 = !{i64 20}
|
|
!21 = !{i64 21}
|
|
!22 = !{i64 22}
|
|
!23 = !{i64 23}
|
|
|
|
; IR: define {{.*}} @_Z1Cb(i1 noundef zeroext %b)
|
|
; IR-NEXT: entry:
|
|
; IR-NEXT: call {{.*}} @_Z1Bb.memprof.2(i1 noundef zeroext %b)
|
|
|
|
; IR: define {{.*}} @_Z1Ab.memprof.1(i1 noundef zeroext %b)
|
|
; IR-NEXT: entry:
|
|
; IR-NEXT: br i1 %b, label %if.then, label %if.else
|
|
; IR-EMPTY:
|
|
; IR-NEXT: if.then:
|
|
; IR-NEXT: call {{.*}} @_Znam(i64 noundef 10) #[[COLD:[0-9]+]]
|
|
; IR-NEXT: br label %if.end
|
|
; IR-EMPTY:
|
|
; IR-NEXT: if.else:
|
|
; IR-NEXT: call {{.*}} @_Znam(i64 noundef 10) #[[NOTCOLD:[0-9]+]]
|
|
|
|
; IR: define {{.*}} @_Z1Xb.memprof.2(i1 noundef zeroext %b)
|
|
; IR-NEXT: entry:
|
|
; IR-NEXT: call {{.*}} @_Z1Ab.memprof.1(i1 noundef zeroext %b)
|
|
|
|
; IR: define {{.*}} @_Z1Bb.memprof.2(i1 noundef zeroext %b)
|
|
; IR-NEXT: entry:
|
|
; IR-NEXT: call {{.*}} @_Z1Xb.memprof.2(i1 noundef zeroext %b)
|
|
|
|
; IR: attributes #[[NOTCOLD]] = { builtin "memprof"="notcold" }
|
|
; IR: attributes #[[COLD]] = { builtin "memprof"="cold" }
|
|
|
|
; STATS: 2 memprof-context-disambiguation - Number of cold static allocations (possibly cloned)
|
|
; STATS: 2 memprof-context-disambiguation - Number of not cold static allocations (possibly cloned)
|
|
; STATS: 7 memprof-context-disambiguation - Number of function clones created during whole program analysis
|
|
; STATS: 2 memprof-context-disambiguation - Number of new nodes created during merging
|