1;; Tests callsite context graph generation for call graph containing indirect 2;; calls. Currently this should result in conservative behavior, such that the 3;; indirect call receives a null call in its graph node, to prevent subsequent 4;; cloning. Also tests graph and IR cloning. 5;; 6;; Original code looks like: 7;; 8;; char *foo() { 9;; return new char[10]; 10;; } 11;; class A { 12;; public: 13;; virtual char *x() { return foo(); } 14;; }; 15;; class B : public A { 16;; public: 17;; char *x() final { return foo(); } 18;; }; 19;; char *bar(A *a) { 20;; return a->x(); 21;; } 22;; int main(int argc, char **argv) { 23;; char *x = foo(); 24;; char *y = foo(); 25;; B b; 26;; char *z = bar(&b); 27;; char *w = bar(&b); 28;; A a; 29;; char *r = bar(&a); 30;; char *s = bar(&a); 31;; memset(x, 0, 10); 32;; memset(y, 0, 10); 33;; memset(z, 0, 10); 34;; memset(w, 0, 10); 35;; memset(r, 0, 10); 36;; memset(s, 0, 10); 37;; delete[] x; 38;; delete[] w; 39;; delete[] r; 40;; sleep(10); 41;; delete[] y; 42;; delete[] z; 43;; delete[] s; 44;; return 0; 45;; } 46;; 47;; Code compiled with -mllvm -memprof-ave-lifetime-cold-threshold=5 so that the 48;; memory freed after sleep(10) results in cold lifetimes. 49;; 50;; Compiled without optimization to prevent inlining and devirtualization. 51;; 52;; The IR was then reduced using llvm-reduce with the expected FileCheck input. 53 54;; -stats requires asserts 55; REQUIRES: asserts 56 57; RUN: opt -passes=memprof-context-disambiguation -supports-hot-cold-new \ 58; RUN: -memprof-verify-ccg -memprof-verify-nodes -memprof-dump-ccg \ 59; RUN: -memprof-export-to-dot -memprof-dot-file-path-prefix=%t. \ 60; RUN: -stats -pass-remarks=memprof-context-disambiguation \ 61; RUN: %s -S 2>&1 | FileCheck %s --check-prefix=DUMP --check-prefix=IR \ 62; RUN: --check-prefix=STATS --check-prefix=REMARKS 63 64; RUN: cat %t.ccg.postbuild.dot | FileCheck %s --check-prefix=DOT 65;; We should only create a single clone of foo, for the direct call 66;; from main allocating cold memory. 67; RUN: cat %t.ccg.cloned.dot | FileCheck %s --check-prefix=DOTCLONED 68 69 70target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 71target triple = "x86_64-unknown-linux-gnu" 72 73declare ptr @_Z3barP1A(ptr) 74 75define i32 @main(ptr %b, ptr %a) #0 { 76entry: 77 %call = call noundef ptr @_Z3foov(), !callsite !0 78 %call1 = call noundef ptr @_Z3foov(), !callsite !1 79 %call2 = call noundef ptr @_Z3barP1A(ptr noundef %b), !callsite !2 80 %call3 = call noundef ptr @_Z3barP1A(ptr noundef %b), !callsite !3 81 %call4 = call noundef ptr @_Z3barP1A(ptr noundef %a), !callsite !4 82 %call5 = call noundef ptr @_Z3barP1A(ptr noundef %a), !callsite !5 83 ret i32 0 84} 85 86; Function Attrs: noinline 87declare void @_ZN1BC2Ev() #1 88 89; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write) 90declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #2 91 92; Function Attrs: nobuiltin 93declare void @_ZdaPv() #3 94 95define internal ptr @_ZN1A1xEv() #4 { 96entry: 97 %call = call noundef ptr @_Z3foov(), !callsite !6 98 ret ptr null 99} 100 101; Function Attrs: mustprogress uwtable 102define internal ptr @_ZN1B1xEv() #5 { 103entry: 104 %call = call noundef ptr @_Z3foov(), !callsite !7 105 ret ptr null 106} 107 108; Function Attrs: mustprogress uwtable 109define internal ptr @_Z3foov() #5 { 110entry: 111 %call = call noalias noundef nonnull ptr @_Znam(i64 noundef 10) #7, !memprof !8, !callsite !21 112 ret ptr null 113} 114 115declare ptr @_Znam(i64) #6 116 117; uselistorder directives 118uselistorder ptr @_Z3foov, { 3, 2, 1, 0 } 119 120attributes #0 = { "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" } 121attributes #1 = { noinline } 122attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: write) } 123attributes #3 = { nobuiltin } 124attributes #4 = { "tune-cpu"="generic" } 125attributes #5 = { mustprogress uwtable "disable-tail-calls"="true" "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } 126attributes #6 = { "disable-tail-calls"="true" } 127attributes #7 = { builtin } 128 129!0 = !{i64 8632435727821051414} 130!1 = !{i64 -3421689549917153178} 131!2 = !{i64 6792096022461663180} 132!3 = !{i64 -2709642582978494015} 133!4 = !{i64 748269490701775343} 134!5 = !{i64 -5747251260480066785} 135!6 = !{i64 8256774051149711748} 136!7 = !{i64 -4831879094954754638} 137!8 = !{!9, !11, !13, !15, !17, !19} 138!9 = !{!10, !"notcold"} 139!10 = !{i64 2732490490862098848, i64 8256774051149711748, i64 -4820244510750103755, i64 748269490701775343} 140!11 = !{!12, !"cold"} 141!12 = !{i64 2732490490862098848, i64 8256774051149711748, i64 -4820244510750103755, i64 -5747251260480066785} 142!13 = !{!14, !"notcold"} 143!14 = !{i64 2732490490862098848, i64 8632435727821051414} 144!15 = !{!16, !"cold"} 145!16 = !{i64 2732490490862098848, i64 -4831879094954754638, i64 -4820244510750103755, i64 6792096022461663180} 146!17 = !{!18, !"notcold"} 147!18 = !{i64 2732490490862098848, i64 -4831879094954754638, i64 -4820244510750103755, i64 -2709642582978494015} 148!19 = !{!20, !"cold"} 149!20 = !{i64 2732490490862098848, i64 -3421689549917153178} 150!21 = !{i64 2732490490862098848} 151 152 153; DUMP: CCG before cloning: 154; DUMP: Callsite Context Graph: 155; DUMP: Node [[FOO:0x[a-z0-9]+]] 156; DUMP: %call = call noalias noundef nonnull ptr @_Znam(i64 noundef 10) #7 (clone 0) 157; DUMP: AllocTypes: NotColdCold 158; DUMP: ContextIds: 1 2 3 4 5 6 159; DUMP: CalleeEdges: 160; DUMP: CallerEdges: 161; DUMP: Edge from Callee [[FOO]] to Caller: [[AX:0x[a-z0-9]+]] AllocTypes: NotColdCold ContextIds: 1 2 162; DUMP: Edge from Callee [[FOO]] to Caller: [[MAIN1:0x[a-z0-9]+]] AllocTypes: NotCold ContextIds: 3 163; DUMP: Edge from Callee [[FOO]] to Caller: [[BX:0x[a-z0-9]+]] AllocTypes: NotColdCold ContextIds: 4 5 164; DUMP: Edge from Callee [[FOO]] to Caller: [[MAIN2:0x[a-z0-9]+]] AllocTypes: Cold ContextIds: 6 165 166; DUMP: Node [[AX]] 167; DUMP: %call = call noundef ptr @_Z3foov() (clone 0) 168; DUMP: AllocTypes: NotColdCold 169; DUMP: ContextIds: 1 2 170; DUMP: CalleeEdges: 171; DUMP: Edge from Callee [[FOO]] to Caller: [[AX]] AllocTypes: NotColdCold ContextIds: 1 2 172; DUMP: CallerEdges: 173; DUMP: Edge from Callee [[AX]] to Caller: [[BAR:0x[a-z0-9]+]] AllocTypes: NotColdCold ContextIds: 1 2 174 175;; Bar contains an indirect call, with multiple targets. It's call should be null. 176; DUMP: Node [[BAR]] 177; DUMP: null Call 178; DUMP: AllocTypes: NotColdCold 179; DUMP: ContextIds: 1 2 4 5 180; DUMP: CalleeEdges: 181; DUMP: Edge from Callee [[AX]] to Caller: [[BAR]] AllocTypes: NotColdCold ContextIds: 1 2 182; DUMP: Edge from Callee [[BX]] to Caller: [[BAR]] AllocTypes: NotColdCold ContextIds: 4 5 183; DUMP: CallerEdges: 184; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN3:0x[a-z0-9]+]] AllocTypes: NotCold ContextIds: 1 185; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN4:0x[a-z0-9]+]] AllocTypes: Cold ContextIds: 2 186; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN5:0x[a-z0-9]+]] AllocTypes: Cold ContextIds: 4 187; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN6:0x[a-z0-9]+]] AllocTypes: NotCold ContextIds: 5 188 189; DUMP: Node [[MAIN3]] 190; DUMP: %call4 = call noundef ptr @_Z3barP1A(ptr noundef %a) (clone 0) 191; DUMP: AllocTypes: NotCold 192; DUMP: ContextIds: 1 193; DUMP: CalleeEdges: 194; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN3]] AllocTypes: NotCold ContextIds: 1 195; DUMP: CallerEdges: 196 197; DUMP: Node [[MAIN4]] 198; DUMP: %call5 = call noundef ptr @_Z3barP1A(ptr noundef %a) (clone 0) 199; DUMP: AllocTypes: Cold 200; DUMP: ContextIds: 2 201; DUMP: CalleeEdges: 202; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN4]] AllocTypes: Cold ContextIds: 2 203; DUMP: CallerEdges: 204 205; DUMP: Node [[MAIN1]] 206; DUMP: %call = call noundef ptr @_Z3foov() (clone 0) 207; DUMP: AllocTypes: NotCold 208; DUMP: ContextIds: 3 209; DUMP: CalleeEdges: 210; DUMP: Edge from Callee [[FOO]] to Caller: [[MAIN1]] AllocTypes: NotCold ContextIds: 3 211; DUMP: CallerEdges: 212 213; DUMP: Node [[BX]] 214; DUMP: %call = call noundef ptr @_Z3foov() (clone 0) 215; DUMP: AllocTypes: NotColdCold 216; DUMP: ContextIds: 4 5 217; DUMP: CalleeEdges: 218; DUMP: Edge from Callee [[FOO]] to Caller: [[BX]] AllocTypes: NotColdCold ContextIds: 4 5 219; DUMP: CallerEdges: 220; DUMP: Edge from Callee [[BX]] to Caller: [[BAR]] AllocTypes: NotColdCold ContextIds: 4 5 221 222; DUMP: Node [[MAIN5]] 223; DUMP: %call2 = call noundef ptr @_Z3barP1A(ptr noundef %b) (clone 0) 224; DUMP: AllocTypes: Cold 225; DUMP: ContextIds: 4 226; DUMP: CalleeEdges: 227; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN5]] AllocTypes: Cold ContextIds: 4 228; DUMP: CallerEdges: 229 230; DUMP: Node [[MAIN6]] 231; DUMP: %call3 = call noundef ptr @_Z3barP1A(ptr noundef %b) (clone 0) 232; DUMP: AllocTypes: NotCold 233; DUMP: ContextIds: 5 234; DUMP: CalleeEdges: 235; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN6]] AllocTypes: NotCold ContextIds: 5 236; DUMP: CallerEdges: 237 238; DUMP: Node [[MAIN2]] 239; DUMP: %call1 = call noundef ptr @_Z3foov() (clone 0) 240; DUMP: AllocTypes: Cold 241; DUMP: ContextIds: 6 242; DUMP: CalleeEdges: 243; DUMP: Edge from Callee [[FOO]] to Caller: [[MAIN2]] AllocTypes: Cold ContextIds: 6 244; DUMP: CallerEdges: 245 246; DUMP: CCG after cloning: 247; DUMP: Callsite Context Graph: 248; DUMP: Node [[FOO]] 249; DUMP: %call = call noalias noundef nonnull ptr @_Znam(i64 noundef 10) #7 (clone 0) 250; DUMP: AllocTypes: NotColdCold 251; DUMP: ContextIds: 1 2 3 4 5 252; DUMP: CalleeEdges: 253; DUMP: CallerEdges: 254; DUMP: Edge from Callee [[FOO]] to Caller: [[AX]] AllocTypes: NotColdCold ContextIds: 1 2 255; DUMP: Edge from Callee [[FOO]] to Caller: [[BX]] AllocTypes: NotColdCold ContextIds: 4 5 256; DUMP: Edge from Callee [[FOO]] to Caller: [[MAIN1]] AllocTypes: NotCold ContextIds: 3 257; DUMP: Clones: [[FOO2:0x[a-z0-9]+]] 258 259; DUMP: Node [[AX]] 260; DUMP: %call = call noundef ptr @_Z3foov() (clone 0) 261; DUMP: AllocTypes: NotColdCold 262; DUMP: ContextIds: 1 2 263; DUMP: CalleeEdges: 264; DUMP: Edge from Callee [[FOO]] to Caller: [[AX]] AllocTypes: NotColdCold ContextIds: 1 2 265; DUMP: CallerEdges: 266; DUMP: Edge from Callee [[AX]] to Caller: [[BAR]] AllocTypes: NotColdCold ContextIds: 1 2 267 268; DUMP: Node [[BAR]] 269; DUMP: null Call 270; DUMP: AllocTypes: NotColdCold 271; DUMP: ContextIds: 1 2 4 5 272; DUMP: CalleeEdges: 273; DUMP: Edge from Callee [[AX]] to Caller: [[BAR]] AllocTypes: NotColdCold ContextIds: 1 2 274; DUMP: Edge from Callee [[BX]] to Caller: [[BAR]] AllocTypes: NotColdCold ContextIds: 4 5 275; DUMP: CallerEdges: 276; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN3]] AllocTypes: NotCold ContextIds: 1 277; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN4]] AllocTypes: Cold ContextIds: 2 278; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN5]] AllocTypes: Cold ContextIds: 4 279; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN6]] AllocTypes: NotCold ContextIds: 5 280 281; DUMP: Node [[MAIN3]] 282; DUMP: %call4 = call noundef ptr @_Z3barP1A(ptr noundef %a) (clone 0) 283; DUMP: AllocTypes: NotCold 284; DUMP: ContextIds: 1 285; DUMP: CalleeEdges: 286; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN3]] AllocTypes: NotCold ContextIds: 1 287; DUMP: CallerEdges: 288 289; DUMP: Node [[MAIN4]] 290; DUMP: %call5 = call noundef ptr @_Z3barP1A(ptr noundef %a) (clone 0) 291; DUMP: AllocTypes: Cold 292; DUMP: ContextIds: 2 293; DUMP: CalleeEdges: 294; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN4]] AllocTypes: Cold ContextIds: 2 295; DUMP: CallerEdges: 296 297; DUMP: Node [[MAIN1]] 298; DUMP: %call = call noundef ptr @_Z3foov() (clone 0) 299; DUMP: AllocTypes: NotCold 300; DUMP: ContextIds: 3 301; DUMP: CalleeEdges: 302; DUMP: Edge from Callee [[FOO]] to Caller: [[MAIN1]] AllocTypes: NotCold ContextIds: 3 303; DUMP: CallerEdges: 304 305; DUMP: Node [[BX]] 306; DUMP: %call = call noundef ptr @_Z3foov() (clone 0) 307; DUMP: AllocTypes: NotColdCold 308; DUMP: ContextIds: 4 5 309; DUMP: CalleeEdges: 310; DUMP: Edge from Callee [[FOO]] to Caller: [[BX]] AllocTypes: NotColdCold ContextIds: 4 5 311; DUMP: CallerEdges: 312; DUMP: Edge from Callee [[BX]] to Caller: [[BAR]] AllocTypes: NotColdCold ContextIds: 4 5 313 314; DUMP: Node [[MAIN5]] 315; DUMP: %call2 = call noundef ptr @_Z3barP1A(ptr noundef %b) (clone 0) 316; DUMP: AllocTypes: Cold 317; DUMP: ContextIds: 4 318; DUMP: CalleeEdges: 319; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN5]] AllocTypes: Cold ContextIds: 4 320; DUMP: CallerEdges: 321 322; DUMP: Node [[MAIN6]] 323; DUMP: %call3 = call noundef ptr @_Z3barP1A(ptr noundef %b) (clone 0) 324; DUMP: AllocTypes: NotCold 325; DUMP: ContextIds: 5 326; DUMP: CalleeEdges: 327; DUMP: Edge from Callee [[BAR]] to Caller: [[MAIN6]] AllocTypes: NotCold ContextIds: 5 328; DUMP: CallerEdges: 329 330; DUMP: Node [[MAIN2]] 331; DUMP: %call1 = call noundef ptr @_Z3foov() (clone 0) 332; DUMP: AllocTypes: Cold 333; DUMP: ContextIds: 6 334; DUMP: CalleeEdges: 335; DUMP: Edge from Callee [[FOO2]] to Caller: [[MAIN2]] AllocTypes: Cold ContextIds: 6 336; DUMP: CallerEdges: 337 338; DUMP: Node [[FOO2]] 339; DUMP: %call = call noalias noundef nonnull ptr @_Znam(i64 noundef 10) #7 (clone 0) 340; DUMP: AllocTypes: Cold 341; DUMP: ContextIds: 6 342; DUMP: CalleeEdges: 343; DUMP: CallerEdges: 344; DUMP: Edge from Callee [[FOO2]] to Caller: [[MAIN2]] AllocTypes: Cold ContextIds: 6 345; DUMP: Clone of [[FOO]] 346 347 348; REMARKS: created clone _Z3foov.memprof.1 349; REMARKS: call in clone main assigned to call function clone _Z3foov.memprof.1 350; REMARKS: call in clone _Z3foov.memprof.1 marked with memprof allocation attribute cold 351; REMARKS: call in clone _ZN1A1xEv assigned to call function clone _Z3foov 352; REMARKS: call in clone _ZN1B1xEv assigned to call function clone _Z3foov 353; REMARKS: call in clone main assigned to call function clone _Z3foov 354; REMARKS: call in clone _Z3foov marked with memprof allocation attribute notcold 355 356 357; IR: define {{.*}} @main( 358; IR: call {{.*}} @_Z3foov() 359;; Only the second call to foo, which allocates cold memory via direct calls, 360;; is replaced with a call to a clone that calls a cold allocation. 361; IR: call {{.*}} @_Z3foov.memprof.1() 362; IR: call {{.*}} @_Z3barP1A( 363; IR: call {{.*}} @_Z3barP1A( 364; IR: call {{.*}} @_Z3barP1A( 365; IR: call {{.*}} @_Z3barP1A( 366; IR: define internal {{.*}} @_ZN1A1xEv( 367; IR: call {{.*}} @_Z3foov() 368; IR: define internal {{.*}} @_ZN1B1xEv( 369; IR: call {{.*}} @_Z3foov() 370; IR: define internal {{.*}} @_Z3foov() 371; IR: call {{.*}} @_Znam(i64 noundef 10) #[[NOTCOLD:[0-9]+]] 372; IR: define internal {{.*}} @_Z3foov.memprof.1() 373; IR: call {{.*}} @_Znam(i64 noundef 10) #[[COLD:[0-9]+]] 374; IR: attributes #[[NOTCOLD]] = { builtin "memprof"="notcold" } 375; IR: attributes #[[COLD]] = { builtin "memprof"="cold" } 376 377 378; STATS: 1 memprof-context-disambiguation - Number of cold static allocations (possibly cloned) 379; STATS: 1 memprof-context-disambiguation - Number of not cold static allocations (possibly cloned) 380; STATS: 1 memprof-context-disambiguation - Number of function clones created during whole program analysis 381 382 383; DOT: digraph "postbuild" { 384; DOT: label="postbuild"; 385; DOT: Node[[FOO:0x[a-z0-9]+]] [shape=record,tooltip="N[[FOO]] ContextIds: 1 2 3 4 5 6",fillcolor="mediumorchid1",style="filled",style="filled",label="{OrigId: Alloc0\n_Z3foov -\> _Znam}"]; 386; DOT: Node[[AX:0x[a-z0-9]+]] [shape=record,tooltip="N[[AX]] ContextIds: 1 2",fillcolor="mediumorchid1",style="filled",style="filled",label="{OrigId: 8256774051149711748\n_ZN1A1xEv -\> _Z3foov}"]; 387; DOT: Node[[AX]] -> Node[[FOO]][tooltip="ContextIds: 1 2",fillcolor="mediumorchid1"]; 388; DOT: Node[[BAR:0x[a-z0-9]+]] [shape=record,tooltip="N[[BAR]] ContextIds: 1 2 4 5",fillcolor="mediumorchid1",style="filled",style="filled",label="{OrigId: 13626499562959447861\nnull call (external)}"]; 389; DOT: Node[[BAR]] -> Node[[AX]][tooltip="ContextIds: 1 2",fillcolor="mediumorchid1"]; 390; DOT: Node[[BAR]] -> Node[[BX:0x[a-z0-9]+]][tooltip="ContextIds: 4 5",fillcolor="mediumorchid1"]; 391; DOT: Node[[MAIN1:0x[a-z0-9]+]] [shape=record,tooltip="N[[MAIN1]] ContextIds: 1",fillcolor="brown1",style="filled",style="filled",label="{OrigId: 748269490701775343\nmain -\> _Z3barP1A}"]; 392; DOT: Node[[MAIN1]] -> Node[[BAR]][tooltip="ContextIds: 1",fillcolor="brown1"]; 393; DOT: Node[[MAIN2:0x[a-z0-9]+]] [shape=record,tooltip="N[[MAIN2]] ContextIds: 2",fillcolor="cyan",style="filled",style="filled",label="{OrigId: 12699492813229484831\nmain -\> _Z3barP1A}"]; 394; DOT: Node[[MAIN2]] -> Node[[BAR]][tooltip="ContextIds: 2",fillcolor="cyan"]; 395; DOT: Node[[MAIN3:0x[a-z0-9]+]] [shape=record,tooltip="N[[MAIN3]] ContextIds: 3",fillcolor="brown1",style="filled",style="filled",label="{OrigId: 8632435727821051414\nmain -\> _Z3foov}"]; 396; DOT: Node[[MAIN3]] -> Node[[FOO]][tooltip="ContextIds: 3",fillcolor="brown1"]; 397; DOT: Node[[BX]] [shape=record,tooltip="N[[BX]] ContextIds: 4 5",fillcolor="mediumorchid1",style="filled",style="filled",label="{OrigId: 13614864978754796978\n_ZN1B1xEv -\> _Z3foov}"]; 398; DOT: Node[[BX]] -> Node[[FOO]][tooltip="ContextIds: 4 5",fillcolor="mediumorchid1"]; 399; DOT: Node[[MAIN4:0x[a-z0-9]+]] [shape=record,tooltip="N[[MAIN4]] ContextIds: 4",fillcolor="cyan",style="filled",style="filled",label="{OrigId: 6792096022461663180\nmain -\> _Z3barP1A}"]; 400; DOT: Node[[MAIN4]] -> Node[[BAR]][tooltip="ContextIds: 4",fillcolor="cyan"]; 401; DOT: Node[[MAIN5:0x[a-z0-9]+]] [shape=record,tooltip="N[[MAIN5]] ContextIds: 5",fillcolor="brown1",style="filled",style="filled",label="{OrigId: 15737101490731057601\nmain -\> _Z3barP1A}"]; 402; DOT: Node[[MAIN5]] -> Node[[BAR]][tooltip="ContextIds: 5",fillcolor="brown1"]; 403; DOT: Node[[MAIN6:0x[a-z0-9]+]] [shape=record,tooltip="N[[MAIN6]] ContextIds: 6",fillcolor="cyan",style="filled",style="filled",label="{OrigId: 15025054523792398438\nmain -\> _Z3foov}"]; 404; DOT: Node[[MAIN6]] -> Node[[FOO]][tooltip="ContextIds: 6",fillcolor="cyan"]; 405; DOT: } 406 407 408; DOTCLONED: digraph "cloned" { 409; DOTCLONED: label="cloned"; 410; DOTCLONED: Node[[FOO2:0x[a-z0-9]+]] [shape=record,tooltip="N[[FOO2]] ContextIds: 1 2 3 4 5",fillcolor="mediumorchid1",style="filled",style="filled",label="{OrigId: Alloc0\n_Z3foov -\> _Znam}"]; 411; DOTCLONED: Node[[AX:0x[a-z0-9]+]] [shape=record,tooltip="N[[AX]] ContextIds: 1 2",fillcolor="mediumorchid1",style="filled",style="filled",label="{OrigId: 8256774051149711748\n_ZN1A1xEv -\> _Z3foov}"]; 412; DOTCLONED: Node[[AX]] -> Node[[FOO2]][tooltip="ContextIds: 1 2",fillcolor="mediumorchid1"]; 413; DOTCLONED: Node[[BAR:0x[a-z0-9]+]] [shape=record,tooltip="N[[BAR]] ContextIds: 1 2 4 5",fillcolor="mediumorchid1",style="filled",style="filled",label="{OrigId: 13626499562959447861\nnull call (external)}"]; 414; DOTCLONED: Node[[BAR]] -> Node[[AX]][tooltip="ContextIds: 1 2",fillcolor="mediumorchid1"]; 415; DOTCLONED: Node[[BAR]] -> Node[[BX:0x[a-z0-9]+]][tooltip="ContextIds: 4 5",fillcolor="mediumorchid1"]; 416; DOTCLONED: Node[[MAIN1:0x[a-z0-9]+]] [shape=record,tooltip="N[[MAIN1]] ContextIds: 1",fillcolor="brown1",style="filled",style="filled",label="{OrigId: 748269490701775343\nmain -\> _Z3barP1A}"]; 417; DOTCLONED: Node[[MAIN1]] -> Node[[BAR]][tooltip="ContextIds: 1",fillcolor="brown1"]; 418; DOTCLONED: Node[[MAIN2:0x[a-z0-9]+]] [shape=record,tooltip="N[[MAIN2]] ContextIds: 2",fillcolor="cyan",style="filled",style="filled",label="{OrigId: 12699492813229484831\nmain -\> _Z3barP1A}"]; 419; DOTCLONED: Node[[MAIN2]] -> Node[[BAR]][tooltip="ContextIds: 2",fillcolor="cyan"]; 420; DOTCLONED: Node[[MAIN3:0x[a-z0-9]+]] [shape=record,tooltip="N[[MAIN3]] ContextIds: 3",fillcolor="brown1",style="filled",style="filled",label="{OrigId: 8632435727821051414\nmain -\> _Z3foov}"]; 421; DOTCLONED: Node[[MAIN3]] -> Node[[FOO2]][tooltip="ContextIds: 3",fillcolor="brown1"]; 422; DOTCLONED: Node[[BX]] [shape=record,tooltip="N[[BX]] ContextIds: 4 5",fillcolor="mediumorchid1",style="filled",style="filled",label="{OrigId: 13614864978754796978\n_ZN1B1xEv -\> _Z3foov}"]; 423; DOTCLONED: Node[[BX]] -> Node[[FOO2]][tooltip="ContextIds: 4 5",fillcolor="mediumorchid1"]; 424; DOTCLONED: Node[[MAIN4:0x[a-z0-9]+]] [shape=record,tooltip="N[[MAIN4]] ContextIds: 4",fillcolor="cyan",style="filled",style="filled",label="{OrigId: 6792096022461663180\nmain -\> _Z3barP1A}"]; 425; DOTCLONED: Node[[MAIN4]] -> Node[[BAR]][tooltip="ContextIds: 4",fillcolor="cyan"]; 426; DOTCLONED: Node[[MAIN5:0x[a-z0-9]+]] [shape=record,tooltip="N[[MAIN5]] ContextIds: 5",fillcolor="brown1",style="filled",style="filled",label="{OrigId: 15737101490731057601\nmain -\> _Z3barP1A}"]; 427; DOTCLONED: Node[[MAIN5]] -> Node[[BAR]][tooltip="ContextIds: 5",fillcolor="brown1"]; 428; DOTCLONED: Node[[MAIN6:0x[a-z0-9]+]] [shape=record,tooltip="N[[MAIN6]] ContextIds: 6",fillcolor="cyan",style="filled",style="filled",label="{OrigId: 15025054523792398438\nmain -\> _Z3foov}"]; 429; DOTCLONED: Node[[MAIN6]] -> Node[[FOO2:0x[a-z0-9]+]][tooltip="ContextIds: 6",fillcolor="cyan"]; 430; DOTCLONED: Node[[FOO2]] [shape=record,tooltip="N[[FOO2]] ContextIds: 6",fillcolor="cyan",style="filled",color="blue",style="filled,bold,dashed",label="{OrigId: Alloc0\n_Z3foov -\> _Znam}"]; 431; DOTCLONED: } 432