Go to file
Amara Emerson 93b0ff20c9 [GlobalOpt] Improve common case efficiency of static global initializer evaluation
For very, very large global initializers which can be statically evaluated, the
code would create vectors of temporary Constants, modifying them in place,
before committing the resulting Constant aggregate to the global's initializer
value. This had effectively O(n^2) complexity in the size of the global
initializer and would cause memory and non-termination issues compiling some
workloads.

This change performs the static initializer evaluation and creation in batches,
once for each global in the evaluated IR memory. The existing code is maintained
as a last resort when the initializers are more complex than simple values in a
large aggregate. This should theoretically by NFC, no test as the example case
is massive. The existing test cases pass with this, as well as the llvm test
suite.

To give an example, consider the following C++ code adapted from the clang
regression tests:
struct S {
 int n = 10;
 int m = 2 * n;
 S(int a) : n(a) {}
};

template<typename T>
struct U {
 T *r = &q;
 T q = 42;
 U *p = this;
};

U<S> e;

The global static constructor for 'e' will need to initialize 'r' and 'p' of
the outer struct, while also initializing the inner 'q' structs 'n' and 'm'
members. This batch algorithm will simply use general CommitValueTo() method
to handle the complex nested S struct initialization of 'q', before
processing the outermost members in a single batch. Using CommitValueTo() to
handle member in the outer struct is inefficient when the struct/array is
very large as we end up creating and destroy constant arrays for each
initialization.
For the above case, we expect the following IR to be generated:

%struct.U = type { %struct.S*, %struct.S, %struct.U* }
%struct.S = type { i32, i32 }
@e = global %struct.U { %struct.S* gep inbounds (%struct.U, %struct.U* @e,
                                                 i64 0, i32 1),
                        %struct.S { i32 42, i32 84 }, %struct.U* @e }
The %struct.S { i32 42, i32 84 } inner initializer is treated as a complex
constant expression, while the other two elements of @e are "simple".

Differential Revision: https://reviews.llvm.org/D42612

llvm-svn: 323933
2018-01-31 23:56:07 +00:00
clang [PR32482] Fix bitfield layout for -mms-bitfield and pragma pack 2018-01-31 21:59:02 +00:00
clang-tools-extra [clang-tidy] New argument --language to add_new_check.py 2018-01-31 21:52:39 +00:00
compiler-rt [sanitizer] Move readlinkat.c test from Linux to Posix 2018-01-31 00:04:10 +00:00
debuginfo-tests [debuginfo-tests] Support moving debuginfo-tests to llvm/projects 2017-12-12 16:54:20 +00:00
libclc math.h: Use logical operations instead of bit operations for readability 2018-01-31 21:53:42 +00:00
libcxx Implement LWG2870: Default value of parameter theta of polar should be dependent 2018-01-31 21:42:39 +00:00
libcxxabi [demangler] Improve variadic template support 2018-01-31 20:17:06 +00:00
libunwind [cmake] [libunwind] LLVM_FOUND isn't always set, so just test if 2018-01-27 19:31:44 +00:00
lld [WebAssembly] Write minimal types section 2018-01-31 23:48:14 +00:00
lldb replace os.mkdirs with lldbutil.mkdir_p (NFC) 2018-01-31 21:39:00 +00:00
llgo
llvm [GlobalOpt] Improve common case efficiency of static global initializer evaluation 2018-01-31 23:56:07 +00:00
openmp [libomptarget] Check for library with CUDA Driver API 2018-01-30 16:49:13 +00:00
parallel-libs
polly Change memcpy/memove/memset to have dest and source alignment attributes. 2018-01-28 18:13:57 +00:00
README.md Add an svn project to contain the files that appear at the root of the 2017-10-19 21:09:49 +00:00

README.md

Low Level Virtual Machine (LLVM)

This directory and its subdirectories contain source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and runtime environments.