180 lines · plain
1; This test verifies whether we can outline a singleton instance (i.e., an instance that does not repeat)2; by running two codegen rounds.3; This test also verifies if caches for the two-round codegens are correctly working.4 5; REQUIRES: asserts6; RUN: rm -rf %t7; RUN: split-file %s %t8 9; 0. Base case without a cache.10; Verify each outlining instance is singleton with the global outlining for thinlto.11; They will be identical, which can be folded by the linker with ICF.12; RUN: opt -module-hash -module-summary %t/thin-one.ll -o %t/thin-one.bc13; RUN: opt -module-hash -module-summary %t/thin-two.ll -o %t/thin-two.bc14; RUN: llvm-lto2 run %t/thin-one.bc %t/thin-two.bc -o %t/thinlto \15; RUN: -r %t/thin-one.bc,_f3,px -r %t/thin-one.bc,_g,x \16; RUN: -r %t/thin-two.bc,_f1,px -r %t/thin-two.bc,_f2,px -r %t/thin-two.bc,_g,x \17; RUN: -codegen-data-thinlto-two-rounds18 19; thin-one.ll will have one outlining instance (matched in the global outlined hash tree)20; RUN: llvm-objdump -d %t/thinlto.1 | FileCheck %s --check-prefix=THINLTO-121; THINLTO-1: _OUTLINED_FUNCTION{{.*}}>:22; THINLTO-1-NEXT: mov23; THINLTO-1-NEXT: mov24; THINLTO-1-NEXT: b25 26; thin-two.ll will have two outlining instances (matched in the global outlined hash tree)27; RUN: llvm-objdump -d %t/thinlto.2 | FileCheck %s --check-prefix=THINLTO-228; THINLTO-2: _OUTLINED_FUNCTION{{.*}}>:29; THINLTO-2-NEXT: mov30; THINLTO-2-NEXT: mov31; THINLTO-2-NEXT: b32; THINLTO-2: _OUTLINED_FUNCTION{{.*}}>:33; THINLTO-2-NEXT: mov34; THINLTO-2-NEXT: mov35; THINLTO-2-NEXT: b36 37; 1. Run this with a cache for the first time.38; RUN: rm -rf %t.cache39; RUN: llvm-lto2 run %t/thin-one.bc %t/thin-two.bc -o %t/thinlto-cold \40; RUN: -r %t/thin-one.bc,_f3,px -r %t/thin-one.bc,_g,x \41; RUN: -r %t/thin-two.bc,_f1,px -r %t/thin-two.bc,_f2,px -r %t/thin-two.bc,_g,x \42; RUN: -codegen-data-thinlto-two-rounds -cache-dir %t.cache -debug-only=lto -thinlto-threads 1 > %t.log-cold.txt 2>&143; RUN: cat %t.log-cold.txt | FileCheck %s --check-prefix=COLD44; diff %t/thinlto.1 %t/thinlto-cold.145; diff %t/thinlto.2 %t/thinlto-cold.246 47; COLD: [FirstRound] Cache Miss for {{.*}}thin-one.bc48; COLD: [FirstRound] Cache Miss for {{.*}}thin-two.bc49; COLD: [SecondRound] Cache Miss for {{.*}}thin-one.bc50; COLD: [SecondRound] Cache Miss for {{.*}}thin-two.bc51 52; There are two input bitcode files and each one is operated with 3 caches:53; CG/IR caches for the first round and the second round CG cache.54; So the total number of files are 2 * 3 = 6.55; RUN: ls %t.cache | count 656 57; 2. Without any changes, simply re-running it will hit the cache.58; RUN: llvm-lto2 run %t/thin-one.bc %t/thin-two.bc -o %t/thinlto-warm \59; RUN: -r %t/thin-one.bc,_f3,px -r %t/thin-one.bc,_g,x \60; RUN: -r %t/thin-two.bc,_f1,px -r %t/thin-two.bc,_f2,px -r %t/thin-two.bc,_g,x \61; RUN: -codegen-data-thinlto-two-rounds -cache-dir %t.cache -debug-only=lto -thinlto-threads 1 > %t.log-warm.txt 2>&162; RUN: cat %t.log-warm.txt | FileCheck %s --check-prefix=WARM63; diff %t/thinlto.1 %t/thinlto-warm.164; diff %t/thinlto.2 %t/thinlto-warm.265 66; WARM-NOT: Cache Miss67 68; 3. Assume thin-one.ll has been modified to thin-one-modified.ll.69; The merged CG data remains unchanged as this modification does not affect the hash tree built from thin-two.bc.70; Therefore, both the first and second round runs update only this module.71; RUN: opt -module-hash -module-summary %t/thin-one-modified.ll -o %t/thin-one.bc72; RUN: llvm-lto2 run %t/thin-one.bc %t/thin-two.bc -o %t/thinlto-warm-modified \73; RUN: -r %t/thin-one.bc,_f3,px -r %t/thin-one.bc,_g,x \74; RUN: -r %t/thin-two.bc,_f1,px -r %t/thin-two.bc,_f2,px -r %t/thin-two.bc,_g,x \75; RUN: -codegen-data-thinlto-two-rounds -cache-dir %t.cache -debug-only=lto -thinlto-threads 1 > %t.log-warm-modified.txt 2>&176; RUN: cat %t.log-warm-modified.txt | FileCheck %s --check-prefix=WARM-MODIFIED77; diff %t/thinlto.1 %t/thinlto-warm-modified.178; diff %t/thinlto.2 %t/thinlto-warm-modified.279 80; WARM-MODIFIED: [FirstRound] Cache Miss for {{.*}}thin-one.bc81; WARM-MODIFIED-NOT: [FirstRound] Cache Miss for {{.*}}thin-two.bc82; WARM-MODIFIED: [SecondRound] Cache Miss for {{.*}}thin-one.bc83; WARM-MODIFIED-NOT: [SecondRound] Cache Miss for {{.*}}thin-two.bc84 85; 4. Additionally, thin-two.ll has been modified to thin-two-modified.ll.86; In this case, the merged CG data, which is global, is updated.87; Although the first round run updates only the thin-two.bc module,88; as the module thin-one.bc remains the same as in step 3 above,89; the second round run will update all modules, resulting in different binaries.90; RUN: opt -module-hash -module-summary %t/thin-one-modified.ll -o %t/thin-one.bc91; RUN: opt -module-hash -module-summary %t/thin-two-modified.ll -o %t/thin-two.bc92; RUN: llvm-lto2 run %t/thin-one.bc %t/thin-two.bc -o %t/thinlto-warm-modified-all \93; RUN: -r %t/thin-one.bc,_f3,px -r %t/thin-one.bc,_g,x \94; RUN: -r %t/thin-two.bc,_f1,px -r %t/thin-two.bc,_f2,px -r %t/thin-two.bc,_g,x \95; RUN: -codegen-data-thinlto-two-rounds -cache-dir %t.cache -debug-only=lto -thinlto-threads 1 > %t.log-warm-modified-all.txt 2>&196; RUN: cat %t.log-warm-modified-all.txt | FileCheck %s --check-prefix=WARM-MODIFIED-ALL97; RUN: not diff %t/thinlto.1 %t/thinlto-warm-modified-all.198; RUN: not diff %t/thinlto.2 %t/thinlto-warm-modified-all.299 100; WARM-MODIFIED-ALL-NOT: [FirstRound] Cache Miss for {{.*}}thin-one.bc101; WARM-MODIFIED-ALL: [FirstRound] Cache Miss for {{.*}}thin-two.bc102; WARM-MODIFIED-ALL: [SecondRound] Cache Miss for {{.*}}thin-one.bc103; WARM-MODIFIED-ALL: [SecondRound] Cache Miss for {{.*}}thin-two.bc104 105; thin-one-modified.ll won't be outlined.106; RUN: llvm-objdump -d %t/thinlto-warm-modified-all.1 | FileCheck %s --check-prefix=THINLTO-1-MODIFIED-ALL107; THINLTO-1-MODIFIED-ALL-NOT: _OUTLINED_FUNCTION{{.*}}>:108 109; thin-two-modified.ll will have two (longer) outlining instances (matched in the global outlined hash tree)110; RUN: llvm-objdump -d %t/thinlto-warm-modified-all.2| FileCheck %s --check-prefix=THINLTO-2-MODIFIED-ALL111; THINLTO-2-MODIFIED-ALL: _OUTLINED_FUNCTION{{.*}}>:112; THINLTO-2-MODIFIED-ALL: mov113; THINLTO-2-MODIFIED-ALL: mov114; THINLTO-2-MODIFIED-ALL: mov115; THINLTO-2-MODIFIED-ALL: b116; THINLTO-2-MODIFIED-ALL: _OUTLINED_FUNCTION{{.*}}>:117; THINLTO-2-MODIFIED-ALL: mov118; THINLTO-2-MODIFIED-ALL: mov119; THINLTO-2-MODIFIED-ALL: mov120; THINLTO-2-MODIFIED-ALL: b121 122; 5. Re-running it will hit the cache.123; RUN: llvm-lto2 run %t/thin-one.bc %t/thin-two.bc -o %t/thinlto-warm-again \124; RUN: -r %t/thin-one.bc,_f3,px -r %t/thin-one.bc,_g,x \125; RUN: -r %t/thin-two.bc,_f1,px -r %t/thin-two.bc,_f2,px -r %t/thin-two.bc,_g,x \126; RUN: -codegen-data-thinlto-two-rounds -cache-dir %t.cache -debug-only=lto -thinlto-threads 1 > %t.log-warm-again.txt 2>&1127; RUN: cat %t.log-warm-again.txt | FileCheck %s --check-prefix=WARM-AGAIN128; RUN: diff %t/thinlto-warm-modified-all.1 %t/thinlto-warm-again.1129; RUN: diff %t/thinlto-warm-modified-all.2 %t/thinlto-warm-again.2130 131; WARM-AGAIN-NOT: Cache Miss132 133;--- thin-one.ll134target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"135target triple = "arm64-apple-darwin"136 137declare i32 @g(i32, i32, i32)138define i32 @f3() minsize {139 %1 = call i32 @g(i32 30, i32 1, i32 2);140 ret i32 %1141}142 143;--- thin-one-modified.ll144target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"145target triple = "arm64-apple-darwin"146 147declare i32 @g(i32, i32, i32)148define i32 @f3() minsize {149 %1 = call i32 @g(i32 31, i32 1, i32 2);150 ret i32 %1151}152 153;--- thin-two.ll154target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"155target triple = "arm64-apple-darwin"156 157declare i32 @g(i32, i32, i32)158define i32 @f1() minsize {159 %1 = call i32 @g(i32 10, i32 1, i32 2);160 ret i32 %1161}162define i32 @f2() minsize {163 %1 = call i32 @g(i32 20, i32 1, i32 2);164 ret i32 %1165}166 167;--- thin-two-modified.ll168target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"169target triple = "arm64-apple-darwin"170 171declare i32 @g(i32, i32, i32)172define i32 @f1() minsize {173 %1 = call i32 @g(i32 10, i32 1, i32 2);174 ret i32 %1175}176define i32 @f2() minsize {177 %1 = call i32 @g(i32 10, i32 1, i32 2);178 ret i32 %1179}180