| REQUIRES: ld.lld |
| |
| # Show that DTLTO input file extraction interacts correctly with the |
| # ThinLTO cache. |
| # |
| # To handle bitcode inputs that are not in individual files on disk, such as |
| # members of non-thin archives, DTLTO extracts such input bitcode to a |
| # temporary individual file on disk. This extraction should only be |
| # performed if the backend compilation is required. A backend compilation is |
| # only required if there is a miss in the ThinLTO cache for that module, or a |
| # module is imported by a module that has missed in the ThinLTO cache. |
| # |
| # Test DTLTO input extraction across three cases: |
| # 1. None of the backend compilations hit in the ThinLTO cache. |
| # 2. All of the backend compilations hit in the ThinLTO cache. |
| # 3. Some backend compilations hit in the ThinLTO cache and some miss. |
| |
| RUN: rm -rf %t && split-file %s %t && cd %t |
| |
| RUN: %clang --target=x86_64-linux-gnu -O2 -flto=thin -c f1.c f2.c |
| RUN: llvm-ar rcs f1.a f1.o |
| RUN: llvm-ar rcs f2.a f2.o |
| |
| RUN: mkdir cache.dir |
| |
| DEFINE: %{link} = \ |
| DEFINE: %clang --target=x86_64-linux-gnu -fuse-ld=lld -shared -nostdlib \ |
| DEFINE: -O2 -flto=thin \ |
| DEFINE: -fthinlto-distributor=%python \ |
| DEFINE: -Xthinlto-distributor=%llvm_src_root/utils/dtlto/local.py \ |
| DEFINE: -Wl,--thinlto-cache-dir=cache.dir \ |
| DEFINE: -Wl,--save-temps |
| |
| # 1. None of the backend compilations hit in the ThinLTO cache. |
| # |
| # Both f1.o and f2.o require backend compilation, so both should be extracted. |
| # Each backend compilation should produce: |
| # * a thinlto.bc file |
| # * a temporary bitcode file (extracted archive member) |
| # Native objects are moved into the ThinLTO cache and should not remain here. |
| RUN: mkdir none |
| RUN: %{link} -Wl,--whole-archive f1.a f2.a -o none/out.elf |
| RUN: ls none | sort | FileCheck %s --check-prefix=NONE |
| NONE-NOT: {{^f[1-3]}} |
| NONE-NOT: {{^}}.*\.native\.o{{$}} |
| NONE: {{^}}f1.a(f1.o at [[#F1_OFFSET:]]).1.[[#%X,HEXPID:]].1.[[#PID:]].native.o.thinlto.bc{{$}} |
| NONE-NEXT: {{^}}f1.a(f1.o at [[#F1_OFFSET]]).1.[[#%X,HEXPID]].o{{$}} |
| NONE-NEXT: {{^}}f2.a(f2.o at [[#F2_OFFSET:]]).2.[[#%X,HEXPID]].2.[[#PID]].native.o.thinlto.bc{{$}} |
| NONE-NEXT: {{^}}f2.a(f2.o at [[#F2_OFFSET]]).2.[[#%X,HEXPID]].o{{$}} |
| NONE-NOT: {{^f[1-3]}} |
| |
| # 2. All of the backend compilations hit in the ThinLTO cache. |
| # |
| # Both f1.o and f2.o are satisfied from the ThinLTO cache. No backend |
| # compilation runs, so there should be no .native.o files, no .thinlto.bc files, |
| # and no extracted archive-member bitcode files. |
| RUN: mkdir all |
| RUN: %{link} -Wl,--whole-archive f1.a f2.a -o all/out.elf |
| RUN: ls all | sort | FileCheck %s --check-prefix=ALL |
| ALL-NOT: {{^f[1-3]}} |
| ALL-NOT: {{^}}.*\.native\.o{{$}} |
| |
| # 3. Some backend compilations hit in the ThinLTO cache and some miss. |
| # |
| # f1.o and f2.o are cached, but the new f3.o misses the cache and imports |
| # from f1.o: |
| # * f3.o must be compiled and extracted |
| # * cached f1.o must be extracted because f3.o imports from it. |
| # * cached f2.o should not be extracted or compiled. |
| RUN: %clang --target=x86_64-linux-gnu -O2 -flto=thin -c f3.c |
| RUN: llvm-ar rcs f3.a f3.o |
| RUN: mkdir some |
| RUN: %{link} -Wl,--whole-archive f1.a f2.a f3.a -o some/out.elf |
| RUN: ls some | sort | FileCheck %s --check-prefix=SOME |
| SOME-NOT: {{^f[1-3]}} |
| SOME-NOT: {{^}}.*\.native\.o{{$}} |
| SOME: {{^}}f1.a(f1.o at [[#F1_OFFSET:]]).1.[[#%X,HEXPID:]].o{{$}} |
| SOME-NEXT: {{^}}f3.a(f3.o at [[#F3_OFFSET:]]).3.[[#%X,HEXPID]].3.[[#PID:]].native.o.thinlto.bc{{$}} |
| SOME-NEXT: {{^}}f3.a(f3.o at [[#F3_OFFSET]]).3.[[#%X,HEXPID]].o{{$}} |
| SOME-NOT: {{^f[1-3]}} |
| |
| #--- f1.c |
| __attribute__((retain)) int f1(int x) { return x; } |
| |
| #--- f2.c |
| extern int f1(int); |
| __attribute__((retain)) int f2(int x) { return f1(x) + x; } |
| |
| #--- f3.c |
| extern int f1(int); |
| __attribute__((retain)) int f3(int x) { return f1(x) + x; } |