blob: fc1f212ca9eb5157d4088196f5e5b47b895adf29 [file] [log] [blame]
Nadav Rotemc4efbb82012-12-19 07:22:24 +00001==========================
2Auto-Vectorization in LLVM
3==========================
4
5LLVM has two vectorizers: The *Loop Vectorizer*, which operates on Loops,
6and the *Basic Block Vectorizer*, which optimizes straight-line code. These
7vectorizers focus on different optimization opportunities and use different
8techniques. The BB vectorizer merges multiple scalars that are found in the
9code into vectors while the Loop Vectorizer widens instructions in the
10original loop to operate on multiple consecutive loop iterations.
11
12The Loop Vectorizer
13===================
14
Nadav Rotem0328f5e2012-12-19 18:04:44 +000015Usage
Sean Silva08fd0882012-12-20 02:40:45 +000016-----
Nadav Rotem0328f5e2012-12-19 18:04:44 +000017
Sean Silva13ed79c2012-12-20 02:23:25 +000018LLVM's Loop Vectorizer is now available and will be useful for many people.
Nadav Rotemc4efbb82012-12-19 07:22:24 +000019It is not enabled by default, but can be enabled through clang using the
20command line flag:
21
22.. code-block:: console
23
Nadav Rotem8f4a6cc2012-12-19 18:02:36 +000024 $ clang -fvectorize -O3 file.c
25
26If the ``-fvectorize`` flag is used then the loop vectorizer will be enabled
27when running with ``-O3``, ``-O2``. When ``-Os`` is used, the loop vectorizer
28will only vectorize loops that do not require a major increase in code size.
Nadav Rotemc4efbb82012-12-19 07:22:24 +000029
30We plan to enable the Loop Vectorizer by default as part of the LLVM 3.3 release.
31
32Features
Sean Silva08fd0882012-12-20 02:40:45 +000033--------
Nadav Rotemc4efbb82012-12-19 07:22:24 +000034
35The LLVM Loop Vectorizer has a number of features that allow it to vectorize
36complex loops.
37
38Loops with unknown trip count
Sean Silva08fd0882012-12-20 02:40:45 +000039^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Nadav Rotemc4efbb82012-12-19 07:22:24 +000040
41The Loop Vectorizer supports loops with an unknown trip count.
42In the loop below, the iteration ``start`` and ``finish`` points are unknown,
43and the Loop Vectorizer has a mechanism to vectorize loops that do not start
Sean Silva13ed79c2012-12-20 02:23:25 +000044at zero. In this example, 'n' may not be a multiple of the vector width, and
Nadav Rotemc4efbb82012-12-19 07:22:24 +000045the vectorizer has to execute the last few iterations as scalar code. Keeping
46a scalar copy of the loop increases the code size.
47
48.. code-block:: c++
49
50 void bar(float *A, float* B, float K, int start, int end) {
51 for (int i = start; i < end; ++i)
52 A[i] *= B[i] + K;
53 }
54
55Runtime Checks of Pointers
Sean Silva08fd0882012-12-20 02:40:45 +000056^^^^^^^^^^^^^^^^^^^^^^^^^^
Nadav Rotemc4efbb82012-12-19 07:22:24 +000057
58In the example below, if the pointers A and B point to consecutive addresses,
59then it is illegal to vectorize the code because some elements of A will be
60written before they are read from array B.
61
62Some programmers use the 'restrict' keyword to notify the compiler that the
63pointers are disjointed, but in our example, the Loop Vectorizer has no way of
64knowing that the pointers A and B are unique. The Loop Vectorizer handles this
65loop by placing code that checks, at runtime, if the arrays A and B point to
66disjointed memory locations. If arrays A and B overlap, then the scalar version
67of the loop is executed.
68
69.. code-block:: c++
70
71 void bar(float *A, float* B, float K, int n) {
72 for (int i = 0; i < n; ++i)
73 A[i] *= B[i] + K;
74 }
75
76
77Reductions
Sean Silva08fd0882012-12-20 02:40:45 +000078^^^^^^^^^^
Nadav Rotemc4efbb82012-12-19 07:22:24 +000079
80In this example the ``sum`` variable is used by consecutive iterations of
81the loop. Normally, this would prevent vectorization, but the vectorizer can
Sean Silva13ed79c2012-12-20 02:23:25 +000082detect that 'sum' is a reduction variable. The variable 'sum' becomes a vector
Nadav Rotemc4efbb82012-12-19 07:22:24 +000083of integers, and at the end of the loop the elements of the array are added
84together to create the correct result. We support a number of different
85reduction operations, such as addition, multiplication, XOR, AND and OR.
86
87.. code-block:: c++
88
89 int foo(int *A, int *B, int n) {
90 unsigned sum = 0;
91 for (int i = 0; i < n; ++i)
92 sum += A[i] + 5;
93 return sum;
94 }
95
96Inductions
Sean Silva08fd0882012-12-20 02:40:45 +000097^^^^^^^^^^
Nadav Rotemc4efbb82012-12-19 07:22:24 +000098
99In this example the value of the induction variable ``i`` is saved into an
100array. The Loop Vectorizer knows to vectorize induction variables.
101
102.. code-block:: c++
103
104 void bar(float *A, float* B, float K, int n) {
105 for (int i = 0; i < n; ++i)
106 A[i] = i;
107 }
108
109If Conversion
Sean Silva08fd0882012-12-20 02:40:45 +0000110^^^^^^^^^^^^^
Nadav Rotemc4efbb82012-12-19 07:22:24 +0000111
112The Loop Vectorizer is able to "flatten" the IF statement in the code and
113generate a single stream of instructions. The Loop Vectorizer supports any
114control flow in the innermost loop. The innermost loop may contain complex
115nesting of IFs, ELSEs and even GOTOs.
116
117.. code-block:: c++
118
119 int foo(int *A, int *B, int n) {
120 unsigned sum = 0;
121 for (int i = 0; i < n; ++i)
122 if (A[i] > B[i])
123 sum += A[i] + 5;
124 return sum;
125 }
126
127Pointer Induction Variables
Sean Silva08fd0882012-12-20 02:40:45 +0000128^^^^^^^^^^^^^^^^^^^^^^^^^^^
Nadav Rotemc4efbb82012-12-19 07:22:24 +0000129
130This example uses the "accumulate" function of the standard c++ library. This
131loop uses C++ iterators, which are pointers, and not integer indices.
132The Loop Vectorizer detects pointer induction variables and can vectorize
133this loop. This feature is important because many C++ programs use iterators.
134
135.. code-block:: c++
136
137 int baz(int *A, int n) {
138 return std::accumulate(A, A + n, 0);
139 }
140
141Reverse Iterators
Sean Silva08fd0882012-12-20 02:40:45 +0000142^^^^^^^^^^^^^^^^^
Nadav Rotemc4efbb82012-12-19 07:22:24 +0000143
144The Loop Vectorizer can vectorize loops that count backwards.
145
146.. code-block:: c++
147
148 int foo(int *A, int *B, int n) {
149 for (int i = n; i > 0; --i)
150 A[i] +=1;
151 }
152
153Scatter / Gather
Sean Silva08fd0882012-12-20 02:40:45 +0000154^^^^^^^^^^^^^^^^
Nadav Rotemc4efbb82012-12-19 07:22:24 +0000155
Nadav Rotemaf14a3f2012-12-19 07:36:35 +0000156The Loop Vectorizer can vectorize code that becomes scatter/gather
157memory accesses.
Nadav Rotemc4efbb82012-12-19 07:22:24 +0000158
159.. code-block:: c++
160
161 int foo(int *A, int *B, int n, int k) {
162 for (int i = 0; i < n; ++i)
163 A[i*7] += B[i*k];
164 }
165
Nadav Rotemaf14a3f2012-12-19 07:36:35 +0000166Vectorization of Mixed Types
Sean Silva08fd0882012-12-20 02:40:45 +0000167^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Nadav Rotemc4efbb82012-12-19 07:22:24 +0000168
169The Loop Vectorizer can vectorize programs with mixed types. The Vectorizer
170cost model can estimate the cost of the type conversion and decide if
171vectorization is profitable.
172
173.. code-block:: c++
174
175 int foo(int *A, char *B, int n, int k) {
176 for (int i = 0; i < n; ++i)
177 A[i] += 4 * B[i];
178 }
179
180Vectorization of function calls
Sean Silva08fd0882012-12-20 02:40:45 +0000181^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Nadav Rotemc4efbb82012-12-19 07:22:24 +0000182
183The Loop Vectorize can vectorize intrinsic math functions.
184See the table below for a list of these functions.
185
186+-----+-----+---------+
187| pow | exp | exp2 |
188+-----+-----+---------+
189| sin | cos | sqrt |
190+-----+-----+---------+
191| log |log2 | log10 |
192+-----+-----+---------+
193|fabs |floor| ceil |
194+-----+-----+---------+
195|fma |trunc|nearbyint|
196+-----+-----+---------+
197
Nadav Rotem15bdbbe2012-12-19 08:28:24 +0000198Performance
Sean Silva08fd0882012-12-20 02:40:45 +0000199-----------
Nadav Rotem15bdbbe2012-12-19 08:28:24 +0000200
201This section shows the the execution time of Clang on a simple benchmark:
Nadav Rotem90c8b4b2012-12-19 08:43:05 +0000202`gcc-loops <http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/Vectorizer/>`_.
Nadav Rotem15bdbbe2012-12-19 08:28:24 +0000203This benchmarks is a collection of loops from the GCC autovectorization
Nadav Rotem8f4a6cc2012-12-19 18:02:36 +0000204`page <http://gcc.gnu.org/projects/tree-ssa/vectorization.html>`_ by Dorit Nuzman.
Nadav Rotem15bdbbe2012-12-19 08:28:24 +0000205
Nadav Rotem12da3962012-12-20 00:03:36 +0000206The chart below compares GCC-4.7, ICC-13, and Clang-SVN with and without loop vectorization at -O3, tuned for "corei7-avx", running on a Sandybridge iMac.
207The Y-axis shows the time in msec. Lower is better. The last column shows the geomean of all the kernels.
Nadav Rotem15bdbbe2012-12-19 08:28:24 +0000208
209.. image:: gcc-loops.png
Sean Silvafd706f72012-12-20 22:24:37 +0000210 :width: 100%
Nadav Rotem15bdbbe2012-12-19 08:28:24 +0000211
Nadav Rotemc4efbb82012-12-19 07:22:24 +0000212The Basic Block Vectorizer
213==========================
214
Nadav Rotem0328f5e2012-12-19 18:04:44 +0000215Usage
Sean Silva08fd0882012-12-20 02:40:45 +0000216------
Nadav Rotem0328f5e2012-12-19 18:04:44 +0000217
Nadav Rotemc4efbb82012-12-19 07:22:24 +0000218The Basic Block Vectorizer is not enabled by default, but it can be enabled
219through clang using the command line flag:
220
221.. code-block:: console
222
223 $ clang -fslp-vectorize file.c
224
Nadav Rotem0328f5e2012-12-19 18:04:44 +0000225Details
Sean Silva08fd0882012-12-20 02:40:45 +0000226-------
Nadav Rotem0328f5e2012-12-19 18:04:44 +0000227
Nadav Rotemc4efbb82012-12-19 07:22:24 +0000228The goal of basic-block vectorization (a.k.a. superword-level parallelism) is
229to combine similar independent instructions within simple control-flow regions
230into vector instructions. Memory accesses, arithemetic operations, comparison
231operations and some math functions can all be vectorized using this technique
232(subject to the capabilities of the target architecture).
233
234For example, the following function performs very similar operations on its
235inputs (a1, b1) and (a2, b2). The basic-block vectorizer may combine these
236into vector operations.
237
238.. code-block:: c++
239
240 int foo(int a1, int a2, int b1, int b2) {
241 int r1 = a1*(a1 + b1)/b1 + 50*b1/a1;
242 int r2 = a2*(a2 + b2)/b2 + 50*b2/a2;
243 return r1 + r2;
244 }
245
246