1; Test workload based importing via -thinlto-workload-def 2; 3; Set up 4; RUN: rm -rf %t 5; RUN: mkdir -p %t 6; RUN: split-file %s %t 7; 8; RUN: opt -module-summary %t/m1.ll -o %t/m1.bc 9; RUN: opt -module-summary %t/m2.ll -o %t/m2.bc 10; RUN: opt -module-summary %t/m3.ll -o %t/m3.bc 11; RUN: rm -rf %t_baseline 12; RUN: rm -rf %t_exp 13; RUN: mkdir -p %t_baseline 14; RUN: mkdir -p %t_exp 15; 16; Normal run. m1 shouldn't get m2_f1 because it's not referenced from there. 17; 18; RUN: llvm-lto2 run %t/m1.bc %t/m2.bc %t/m3.bc \ 19; RUN: -o %t_baseline/result.o -save-temps \ 20; RUN: -r %t/m1.bc,m1_f1,plx \ 21; RUN: -r %t/m1.bc,interposable_f,p \ 22; RUN: -r %t/m1.bc,noninterposable_f \ 23; RUN: -r %t/m1.bc,m1_variant \ 24; RUN: -r %t/m1.bc,m2_f1_alias \ 25; RUN: -r %t/m2.bc,m2_f1,plx \ 26; RUN: -r %t/m2.bc,m2_f1_alias,plx \ 27; RUN: -r %t/m2.bc,interposable_f \ 28; RUN: -r %t/m2.bc,noninterposable_f,p \ 29; RUN: -r %t/m2.bc,m2_variant \ 30; RUN: -r %t/m3.bc,m1_f1 \ 31; RUN: -r %t/m3.bc,m3_f1,plx 32; RUN: llvm-dis %t_baseline/result.o.1.3.import.bc -o - | FileCheck %s --check-prefix=NOPROF 33; 34; NOPROF-NOT: m2_f1() 35; 36; The run with workload definitions - same other options. 37; 38; RUN: echo '{ \ 39; RUN: "m1_f1": ["m1_f1", "m2_f1", "m2_f1_alias", "interposable_f", "noninterposable_f"], \ 40; RUN: "m2_f1": ["m1_f1", "m1_f2", "interposable_f"] \ 41; RUN: }' > %t_exp/workload_defs.json 42; 43; RUN: llvm-lto2 run %t/m1.bc %t/m2.bc %t/m3.bc \ 44; RUN: -o %t_exp/result.o -save-temps \ 45; RUN: -thinlto-workload-def=%t_exp/workload_defs.json \ 46; RUN: -r %t/m1.bc,m1_f1,plx \ 47; RUN: -r %t/m1.bc,interposable_f,p \ 48; RUN: -r %t/m1.bc,noninterposable_f \ 49; RUN: -r %t/m1.bc,m1_variant \ 50; RUN: -r %t/m1.bc,m2_f1_alias \ 51; RUN: -r %t/m2.bc,m2_f1,plx \ 52; RUN: -r %t/m2.bc,m2_f1_alias,plx \ 53; RUN: -r %t/m2.bc,interposable_f \ 54; RUN: -r %t/m2.bc,noninterposable_f,p \ 55; RUN: -r %t/m2.bc,m2_variant \ 56; RUN: -r %t/m3.bc,m1_f1 \ 57; RUN: -r %t/m3.bc,m3_f1,plx 58; RUN: llvm-dis %t_exp/result.o.1.3.import.bc -o - | FileCheck %s --check-prefix=FIRST 59; RUN: llvm-dis %t_exp/result.o.2.3.import.bc -o - | FileCheck %s --check-prefix=SECOND 60; RUN: llvm-dis %t_exp/result.o.3.3.import.bc -o - | FileCheck %s --check-prefix=THIRD 61; 62; The third module is bitwse-identical to the "normal" run, as the workload 63; defintion doesn't mention it. 64; 65; RUN: diff %t_baseline/result.o.3.3.import.bc %t_exp/result.o.3.3.import.bc 66; 67; This time, we expect m1 to have m2_f1 and the m2 variant of both interposable_f 68; and noninterposable_f 69; 70; FIRST-LABEL: @m1_f1 71; FIRST-LABEL: @m1_f2.llvm.0 72; 73; @interposable_f is prevailing in m1, so it won't be imported 74; FIRST-LABEL: define void @interposable_f 75; FIRST-NEXT: call void @m1_variant 76; 77; FIRST-LABEL: @m2_f1 78; 79; @noninterposable_f is prevailing in m2 so it will be imported from there. 80; FIRST-LABEL: define available_externally void @noninterposable_f 81; FIRST-NEXT: call void @m2_variant 82; 83; FIRST-LABEL: define available_externally void @m2_f1_alias 84; 85; For the second module we expect to get the functions imported from m1: m1_f1 86; and m1_f2. interposable_f will also come from m1 because that's where its 87; prevailing variant is. 88; SECOND-LABEL: @m2_f1 89; 90; SECOND-LABEL: define weak_odr void @noninterposable_f 91; SECOND-NEXT: call void @m2_variant() 92; SECOND-LABEL: @m1_f1 93; SECOND-LABEL: define available_externally hidden void @m1_f2.llvm.0 94; 95; we import @interposable_f from m1, the prevailing variant. 96; SECOND-LABEL: define available_externally void @interposable_f 97; SECOND-NEXT: call void @m1_variant 98; 99; The third module remains unchanged. The more robust test is the `diff` test 100; in the run lines above. 101; THIRD-LABEL: define available_externally void @m1_f1 102 103;--- m1.ll 104target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 105target triple = "x86_64-pc-linux-gnu" 106 107declare void @m1_variant() 108declare void @m2_f1_alias() 109 110define dso_local void @m1_f1() { 111 call void @m1_f2() 112 call void @noninterposable_f() 113 ret void 114} 115 116define internal void @m1_f2() { 117 call void @interposable_f() 118 ret void 119} 120 121define external void @interposable_f() { 122 call void @m1_variant() 123 ret void 124} 125 126define linkonce_odr void @noninterposable_f() { 127 call void @m1_variant() 128 ret void 129} 130;--- m2.ll 131target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 132target triple = "x86_64-pc-linux-gnu" 133 134declare void @m2_variant() 135 136define dso_local void @m2_f1() { 137 call void @interposable_f() 138 call void @noninterposable_f() 139 ret void 140} 141 142@m2_f1_alias = alias void (...), ptr @m2_f1 143 144define weak void @interposable_f() { 145 call void @m2_variant() 146 ret void 147} 148 149define linkonce_odr void @noninterposable_f() { 150 call void @m2_variant() 151 ret void 152} 153;--- m3.ll 154target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 155target triple = "x86_64-pc-linux-gnu" 156 157declare void @m1_f1() 158 159define dso_local void @m3_f1() { 160 call void @m1_f1() 161 ret void 162} 163