Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions cross-project-tests/dtlto/dtlto-cache.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
REQUIRES: x86-registered-target, ld.lld

# Show that the ThinLTO cache works with DTLTO.

RUN: rm -rf %t && split-file %s %t && cd %t

# Compile source files into bitcode files.
RUN: %clang -O2 --target=x86_64-linux-gnu -flto=thin -c foo.c main.c

# Execute the linker and check that the cache is populated.
RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
RUN: main.o foo.o -o populate1.elf \
RUN: -Wl,--thinlto-distributor=%python \
RUN: -Wl,--thinlto-distributor-arg=%llvm_src_root/utils/dtlto/local.py \
RUN: -Wl,--thinlto-remote-compiler=%clang \
RUN: -Wl,--thinlto-cache-dir=cache.dir \
RUN: -Wl,--save-temps

# Check that there are two backend compilation jobs occurred.
RUN: grep -wo args populate1.*.dist-file.json | wc -l | grep -qx 3
RUN: ls cache.dir/llvmcache.timestamp
RUN: ls cache.dir | count 3

# Execute the linker again and check that a fully populated cache is used correctly,
# i.e., no additional cache entries are created for cache hits.
RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
RUN: main.o foo.o -o populate2.elf \
RUN: -Wl,--thinlto-distributor=%python \
RUN: -Wl,--thinlto-distributor-arg=%llvm_src_root/utils/dtlto/local.py \
RUN: -Wl,--thinlto-remote-compiler=%clang \
RUN: -Wl,--thinlto-cache-dir=cache.dir \
RUN: -Wl,--save-temps

# Check that there are no backend compilation jobs occurred.
RUN: grep -wo args populate2.*.dist-file.json | wc -l | grep -qx 1
RUN: ls cache.dir | count 3

RUN: %clang -O0 --target=x86_64-linux-gnu -flto=thin -c foo.c -o foo.O0.o
RUN: %clang -O0 --target=x86_64-linux-gnu -flto=thin -c main.c -o main.O0.o

# Execute the linker again and check that the cache is populated correctly when there
# are no cache hits but there are existing cache entries.
# As a side effect, this also verifies that the optimization level is considered when
# evaluating the cache entry key.

RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
RUN: main.O0.o foo.O0.o -o populate3.elf \
RUN: -Wl,--thinlto-distributor=%python \
RUN: -Wl,--thinlto-distributor-arg=%llvm_src_root/utils/dtlto/local.py \
RUN: -Wl,--thinlto-remote-compiler=%clang \
RUN: -Wl,--thinlto-cache-dir=cache.dir \
RUN: -Wl,--save-temps

# Check that there are two new backend compilation jobs occurred.
RUN: grep -wo args populate3.*.dist-file.json | wc -l | grep -qx 3
RUN: ls cache.dir | count 5

RUN: %clang -O2 --target=x86_64-linux-gnu -flto=thin -c main-partial.c

# Execute the linker and check that everything works correctly with the partially populated cache;
# One more cache entry should be generated after this run.

RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
RUN: main-partial.o foo.o -o main-partial.elf \
RUN: -Wl,--thinlto-distributor=%python \
RUN: -Wl,--thinlto-distributor-arg=%llvm_src_root/utils/dtlto/local.py \
RUN: -Wl,--thinlto-remote-compiler=%clang \
RUN: -Wl,--thinlto-cache-dir=cache.dir \
RUN: -Wl,--save-temps

# Check that there is one new backend compilation jobs occurred.
RUN: grep -wo args main-partial.*.dist-file.json | wc -l | grep -qx 2
RUN: ls cache.dir | count 6

#--- foo.c
volatile int foo_int;
__attribute__((retain)) int foo(int x) { return x + foo_int; }

#--- main.c
extern int foo(int x);
__attribute__((retain)) int main(int argc, char** argv) {
return foo(argc);
}

#--- main-partial.c
extern int foo(int x);
__attribute__((retain)) int main(int argc, char** argv) {
return foo(argc+1);
}
70 changes: 70 additions & 0 deletions cross-project-tests/dtlto/dtlto-thinlto-cache.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
REQUIRES: x86-registered-target, ld.lld

# This test verifies that a cache populated by an in-process ThinLTO codegen is
# not reused by an out-of-process (DTLTO) codegen and vice versa.

RUN: rm -rf %t && split-file %s %t && cd %t

# Compile source files into bitcode files.
RUN: %clang -O2 --target=x86_64-linux-gnu -flto=thin -c foo.c main.c

# Execute the linker and check that in-process ThinLTO cache is populated.
RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
RUN: main.o foo.o -o main.elf \
RUN: -Wl,--thinlto-cache-dir=cache.dir \
RUN: -Wl,--save-temps

RUN: ls cache.dir/llvmcache.timestamp
RUN: ls cache.dir | count 3

# Execute the linker and check that out-of-process codegen (DTLTO) adds
# additional entries to the cache, implying that in-process and
# out-of-process codegens do not share cache entries.
RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
RUN: main.o foo.o -o populate1.elf \
RUN: -Wl,--thinlto-distributor=%python \
RUN: -Wl,--thinlto-distributor-arg=%llvm_src_root/utils/dtlto/local.py \
RUN: -Wl,--thinlto-remote-compiler=%clang \
RUN: -Wl,--thinlto-cache-dir=cache.dir \
RUN: -Wl,--save-temps

# Check that there are two backend compilation jobs occurred.
RUN: grep -wo args populate1.*.dist-file.json | wc -l | grep -qx 3
RUN: ls cache.dir | count 5

# Clean up cache directory.
RUN: rm -rf cache.dir

# Execute the linker and check that out-of-process (DTLTO) cache is populated.
RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
RUN: main.o foo.o -o populate2.elf \
RUN: -Wl,--thinlto-distributor=%python \
RUN: -Wl,--thinlto-distributor-arg=%llvm_src_root/utils/dtlto/local.py \
RUN: -Wl,--thinlto-remote-compiler=%clang \
RUN: -Wl,--thinlto-cache-dir=cache.dir \
RUN: -Wl,--save-temps

# Check that there are two backend compilation jobs occurred.
RUN: grep -wo args populate2.*.dist-file.json | wc -l | grep -qx 3
RUN: ls cache.dir/llvmcache.timestamp
RUN: ls cache.dir | count 3

# Execute the linker and check that in-process codegen adds additional entries
# to the cache, implying that in-process and out-of-process codegens do
# not share cache entries.
RUN: %clang -O2 --target=x86_64-linux-gnu -Werror -flto=thin -fuse-ld=lld -nostdlib -e main \
RUN: main.o foo.o -o main.elf \
RUN: -Wl,--thinlto-cache-dir=cache.dir \
RUN: -Wl,--save-temps

RUN: ls cache.dir | count 5

#--- foo.c
volatile int foo_int;
__attribute__((retain)) int foo(int x) { return x + foo_int; }

#--- main.c
extern int foo(int x);
__attribute__((retain)) int main(int argc, char** argv) {
return foo(argc);
}
5 changes: 5 additions & 0 deletions llvm/include/llvm/LTO/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ struct Config {
/// need to create copies, so it can set this field to false.
bool KeepSymbolNameCopies = true;

/// This flag is used as one of parameters to calculate cache entries and to
/// ensure that in-process cache and out-of-process (DTLTO) cache are
/// distinguished.
mutable bool Dtlto = 0;

/// Allows non-imported definitions to get the potentially more constraining
/// visibility from the prevailing definition. FromPrevailing is the default
/// because it works for many binary formats. ELF can use the more optimized
Expand Down
Loading
Loading