Mercurial > octave-nkf
annotate libinterp/corefcn/jit-typeinfo.cc @ 18561:7a6da3d7e3f9 draft
Fully uint8 type support
author | LYH <lyh.kernel@gmail.com> |
---|---|
date | Fri, 27 Sep 2013 05:44:07 +0800 |
parents | fd138c51ca25 |
children | 2204a9a252c0 |
rev | line source |
---|---|
18553 | 1 #pragma GCC diagnostic push |
2 #pragma GCC diagnostic error "-Werror" | |
15016 | 3 /* |
4 | |
17744
d63878346099
maint: Update copyright notices for release.
John W. Eaton <jwe@octave.org>
parents:
17164
diff
changeset
|
5 Copyright (C) 2012-2013 Max Brister |
15016 | 6 |
7 This file is part of Octave. | |
8 | |
9 Octave is free software; you can redistribute it and/or modify it | |
10 under the terms of the GNU General Public License as published by the | |
11 Free Software Foundation; either version 3 of the License, or (at your | |
12 option) any later version. | |
13 | |
14 Octave is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
20 along with Octave; see the file COPYING. If not, see | |
21 <http://www.gnu.org/licenses/>. | |
22 | |
23 */ | |
24 | |
16768 | 25 // Author: Max Brister <max@2bass.com> |
26 | |
15016 | 27 // defines required by llvm |
28 #define __STDC_LIMIT_MACROS | |
29 #define __STDC_CONSTANT_MACROS | |
30 | |
31 #ifdef HAVE_CONFIG_H | |
32 #include <config.h> | |
33 #endif | |
34 | |
35 #ifdef HAVE_LLVM | |
36 | |
37 #include "jit-typeinfo.h" | |
38 | |
39 #include <llvm/Analysis/Verifier.h> | |
17164 | 40 #include <llvm/ExecutionEngine/ExecutionEngine.h> |
41 | |
42 #ifdef HAVE_LLVM_IR_FUNCTION_H | |
43 #include <llvm/IR/GlobalVariable.h> | |
44 #include <llvm/IR/LLVMContext.h> | |
45 #include <llvm/IR/Function.h> | |
46 #include <llvm/IR/Instructions.h> | |
47 #include <llvm/IR/Intrinsics.h> | |
48 #else | |
15016 | 49 #include <llvm/GlobalVariable.h> |
50 #include <llvm/LLVMContext.h> | |
51 #include <llvm/Function.h> | |
52 #include <llvm/Instructions.h> | |
53 #include <llvm/Intrinsics.h> | |
17164 | 54 #endif |
55 | |
56 #ifdef HAVE_LLVM_SUPPORT_IRBUILDER_H | |
15016 | 57 #include <llvm/Support/IRBuilder.h> |
17164 | 58 #elif defined(HAVE_LLVM_IR_IRBUILDER_H) |
59 #include <llvm/IR/IRBuilder.h> | |
17031
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
60 #else |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
61 #include <llvm/IRBuilder.h> |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
62 #endif |
17164 | 63 |
15016 | 64 #include <llvm/Support/raw_os_ostream.h> |
65 | |
66 #include "jit-ir.h" | |
67 #include "ov.h" | |
68 #include "ov-builtin.h" | |
69 #include "ov-complex.h" | |
70 #include "ov-scalar.h" | |
18554 | 71 #include "ov-float.h" |
18557 | 72 #include "ov-int8.h" |
18559 | 73 #include "ov-int16.h" |
18560 | 74 #include "ov-int32.h" |
18558
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
75 #include "ov-int64.h" |
18561 | 76 #include "ov-uint8.h" |
18555 | 77 #include "ov-uint16.h" |
15016 | 78 #include "pager.h" |
79 | |
80 static llvm::LLVMContext& context = llvm::getGlobalContext (); | |
81 | |
82 jit_typeinfo *jit_typeinfo::instance = 0; | |
83 | |
84 std::ostream& jit_print (std::ostream& os, jit_type *atype) | |
85 { | |
86 if (! atype) | |
87 return os << "null"; | |
88 return os << atype->name (); | |
89 } | |
90 | |
91 // function that jit code calls | |
92 extern "C" void | |
93 octave_jit_print_any (const char *name, octave_base_value *obv) | |
94 { | |
95 obv->print_with_name (octave_stdout, name, true); | |
96 } | |
97 | |
98 extern "C" void | |
15019
ae3670d4df29
Update the execution engine's global mapping for external functions
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
99 octave_jit_print_scalar (const char *name, double value) |
15016 | 100 { |
101 // FIXME: We should avoid allocating a new octave_scalar each time | |
102 octave_value ov (value); | |
103 ov.print_with_name (octave_stdout, name); | |
104 } | |
105 | |
106 extern "C" octave_base_value* | |
107 octave_jit_binary_any_any (octave_value::binary_op op, octave_base_value *lhs, | |
108 octave_base_value *rhs) | |
109 { | |
110 octave_value olhs (lhs, true); | |
111 octave_value orhs (rhs, true); | |
112 octave_value result = do_binary_op (op, olhs, orhs); | |
113 octave_base_value *rep = result.internal_rep (); | |
114 rep->grab (); | |
115 return rep; | |
116 } | |
117 | |
118 extern "C" octave_idx_type | |
119 octave_jit_compute_nelem (double base, double limit, double inc) | |
120 { | |
121 Range rng = Range (base, limit, inc); | |
122 return rng.nelem (); | |
123 } | |
124 | |
125 extern "C" void | |
126 octave_jit_release_any (octave_base_value *obv) | |
127 { | |
128 obv->release (); | |
129 } | |
130 | |
131 extern "C" void | |
132 octave_jit_release_matrix (jit_matrix *m) | |
133 { | |
134 delete m->array; | |
135 } | |
136 | |
137 extern "C" octave_base_value * | |
138 octave_jit_grab_any (octave_base_value *obv) | |
139 { | |
140 obv->grab (); | |
141 return obv; | |
142 } | |
143 | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
144 extern "C" jit_matrix |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
145 octave_jit_grab_matrix (jit_matrix *m) |
15016 | 146 { |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
147 return *m->array; |
15016 | 148 } |
149 | |
150 extern "C" octave_base_value * | |
151 octave_jit_cast_any_matrix (jit_matrix *m) | |
152 { | |
153 octave_value ret (*m->array); | |
154 octave_base_value *rep = ret.internal_rep (); | |
155 rep->grab (); | |
156 delete m->array; | |
157 | |
158 return rep; | |
159 } | |
160 | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
161 extern "C" jit_matrix |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
162 octave_jit_cast_matrix_any (octave_base_value *obv) |
15016 | 163 { |
164 NDArray m = obv->array_value (); | |
165 obv->release (); | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
166 return m; |
15016 | 167 } |
168 | |
15027
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
169 extern "C" octave_base_value * |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
170 octave_jit_cast_any_range (jit_range *rng) |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
171 { |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
172 Range temp (*rng); |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
173 octave_value ret (temp); |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
174 octave_base_value *rep = ret.internal_rep (); |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
175 rep->grab (); |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
176 |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
177 return rep; |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
178 } |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
179 extern "C" jit_range |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
180 octave_jit_cast_range_any (octave_base_value *obv) |
15027
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
181 { |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
182 |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
183 jit_range r (obv->range_value ()); |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
184 obv->release (); |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
185 return r; |
15027
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
186 } |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
187 |
15016 | 188 extern "C" double |
189 octave_jit_cast_scalar_any (octave_base_value *obv) | |
190 { | |
191 double ret = obv->double_value (); | |
192 obv->release (); | |
193 return ret; | |
194 } | |
195 | |
196 extern "C" octave_base_value * | |
197 octave_jit_cast_any_scalar (double value) | |
198 { | |
199 return new octave_scalar (value); | |
200 } | |
201 | |
18554 | 202 extern "C" float |
203 octave_jit_cast_single_any (octave_base_value *obv) | |
204 { | |
205 float ret = obv->float_value (); | |
206 obv->release (); | |
207 return ret; | |
208 } | |
209 | |
210 extern "C" octave_base_value * | |
211 octave_jit_cast_any_single (float value) | |
212 { | |
213 return new octave_float_scalar (value); | |
214 } | |
215 | |
18557 | 216 extern "C" int8_t |
217 octave_jit_cast_int8_any (octave_base_value *obv) | |
218 { | |
219 int8_t ret = obv->int8_scalar_value (); | |
220 obv->release (); | |
221 return ret; | |
222 } | |
223 | |
224 extern "C" octave_base_value * | |
225 octave_jit_cast_any_int8 (int8_t value) | |
226 { | |
227 return new octave_int8_scalar (value); | |
228 } | |
229 | |
18559 | 230 extern "C" int16_t |
231 octave_jit_cast_int16_any (octave_base_value *obv) | |
232 { | |
233 int16_t ret = obv->int16_scalar_value (); | |
234 obv->release (); | |
235 return ret; | |
236 } | |
237 | |
238 extern "C" octave_base_value * | |
239 octave_jit_cast_any_int16 (int16_t value) | |
240 { | |
241 return new octave_int16_scalar (value); | |
242 } | |
243 | |
18560 | 244 extern "C" int32_t |
245 octave_jit_cast_int32_any (octave_base_value *obv) | |
246 { | |
247 int32_t ret = obv->int32_scalar_value (); | |
248 obv->release (); | |
249 return ret; | |
250 } | |
251 | |
252 extern "C" octave_base_value * | |
253 octave_jit_cast_any_int32 (int32_t value) | |
254 { | |
255 return new octave_int32_scalar (value); | |
256 } | |
257 | |
18558
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
258 extern "C" int64_t |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
259 octave_jit_cast_int64_any (octave_base_value *obv) |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
260 { |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
261 int64_t ret = obv->int64_scalar_value (); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
262 obv->release (); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
263 return ret; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
264 } |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
265 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
266 extern "C" octave_base_value * |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
267 octave_jit_cast_any_int64 (int64_t value) |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
268 { |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
269 return new octave_int64_scalar (value); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
270 } |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
271 |
18561 | 272 extern "C" uint8_t |
273 octave_jit_cast_uint8_any (octave_base_value *obv) | |
274 { | |
275 uint8_t ret = obv->uint8_scalar_value (); | |
276 obv->release (); | |
277 return ret; | |
278 } | |
279 | |
280 extern "C" octave_base_value * | |
281 octave_jit_cast_any_uint8 (uint8_t value) | |
282 { | |
283 return new octave_uint8_scalar (value); | |
284 } | |
285 | |
18555 | 286 extern "C" uint16_t |
287 octave_jit_cast_uint16_any (octave_base_value *obv) | |
288 { | |
289 uint16_t ret = obv->uint16_scalar_value (); | |
290 obv->release (); | |
291 return ret; | |
292 } | |
293 | |
294 extern "C" octave_base_value * | |
295 octave_jit_cast_any_uint16 (uint16_t value) | |
296 { | |
297 return new octave_uint16_scalar (value); | |
298 } | |
299 | |
15016 | 300 extern "C" Complex |
301 octave_jit_cast_complex_any (octave_base_value *obv) | |
302 { | |
303 Complex ret = obv->complex_value (); | |
304 obv->release (); | |
305 return ret; | |
306 } | |
307 | |
308 extern "C" octave_base_value * | |
309 octave_jit_cast_any_complex (Complex c) | |
310 { | |
311 if (c.imag () == 0) | |
312 return new octave_scalar (c.real ()); | |
313 else | |
314 return new octave_complex (c); | |
315 } | |
316 | |
317 extern "C" void | |
318 octave_jit_gripe_nan_to_logical_conversion (void) | |
319 { | |
320 try | |
321 { | |
322 gripe_nan_to_logical_conversion (); | |
323 } | |
324 catch (const octave_execution_exception&) | |
325 { | |
326 gripe_library_execution_error (); | |
327 } | |
328 } | |
329 | |
330 extern "C" void | |
331 octave_jit_ginvalid_index (void) | |
332 { | |
333 try | |
334 { | |
335 gripe_invalid_index (); | |
336 } | |
337 catch (const octave_execution_exception&) | |
338 { | |
339 gripe_library_execution_error (); | |
340 } | |
341 } | |
342 | |
343 extern "C" void | |
344 octave_jit_gindex_range (int nd, int dim, octave_idx_type iext, | |
345 octave_idx_type ext) | |
346 { | |
347 try | |
348 { | |
349 gripe_index_out_of_range (nd, dim, iext, ext); | |
350 } | |
351 catch (const octave_execution_exception&) | |
352 { | |
353 gripe_library_execution_error (); | |
354 } | |
355 } | |
356 | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
357 extern "C" jit_matrix |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
358 octave_jit_paren_subsasgn_impl (jit_matrix *mat, octave_idx_type index, |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
359 double value) |
15016 | 360 { |
361 NDArray *array = mat->array; | |
362 if (array->nelem () < index) | |
363 array->resize1 (index); | |
364 | |
365 double *data = array->fortran_vec (); | |
366 data[index - 1] = value; | |
367 | |
368 mat->update (); | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
369 return *mat; |
15016 | 370 } |
371 | |
15068
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
372 static void |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
373 make_indices (double *indices, octave_idx_type idx_count, |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
374 Array<idx_vector>& result) |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
375 { |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
376 result.resize (dim_vector (1, idx_count)); |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
377 for (octave_idx_type i = 0; i < idx_count; ++i) |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
378 result(i) = idx_vector (indices[i]); |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
379 } |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
380 |
15067 | 381 extern "C" double |
382 octave_jit_paren_scalar (jit_matrix *mat, double *indicies, | |
383 octave_idx_type idx_count) | |
384 { | |
385 // FIXME: Replace this with a more optimal version | |
386 try | |
387 { | |
15068
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
388 Array<idx_vector> idx; |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
389 make_indices (indicies, idx_count, idx); |
15067 | 390 |
391 Array<double> ret = mat->array->index (idx); | |
392 return ret.xelem (0); | |
393 } | |
394 catch (const octave_execution_exception&) | |
395 { | |
396 gripe_library_execution_error (); | |
397 return 0; | |
398 } | |
399 } | |
400 | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
401 extern "C" jit_matrix |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
402 octave_jit_paren_scalar_subsasgn (jit_matrix *mat, double *indices, |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
403 octave_idx_type idx_count, double value) |
15068
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
404 { |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
405 // FIXME: Replace this with a more optimal version |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
406 jit_matrix ret; |
15068
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
407 try |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
408 { |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
409 Array<idx_vector> idx; |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
410 make_indices (indices, idx_count, idx); |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
411 |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
412 Matrix temp (1, 1); |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
413 temp.xelem(0) = value; |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
414 mat->array->assign (idx, temp); |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
415 ret.update (mat->array); |
15068
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
416 } |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
417 catch (const octave_execution_exception&) |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
418 { |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
419 gripe_library_execution_error (); |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
420 } |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
421 |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
422 return ret; |
15068
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
423 } |
f57d7578c1a6
Support ND matrix indexing with scalar assignment in JIT.
Max Brister <max@2bass.com>
parents:
15067
diff
changeset
|
424 |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
425 extern "C" jit_matrix |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
426 octave_jit_paren_subsasgn_matrix_range (jit_matrix *mat, jit_range *index, |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
427 double value) |
15016 | 428 { |
429 NDArray *array = mat->array; | |
430 bool done = false; | |
431 | |
432 // optimize for the simple case (no resizing and no errors) | |
433 if (*array->jit_ref_count () == 1 | |
434 && index->all_elements_are_ints ()) | |
435 { | |
436 // this code is similar to idx_vector::fill, but we avoid allocating an | |
437 // idx_vector and its associated rep | |
438 octave_idx_type start = static_cast<octave_idx_type> (index->base) - 1; | |
439 octave_idx_type step = static_cast<octave_idx_type> (index->inc); | |
440 octave_idx_type nelem = index->nelem; | |
441 octave_idx_type final = start + nelem * step; | |
442 if (step < 0) | |
443 { | |
444 step = -step; | |
445 std::swap (final, start); | |
446 } | |
447 | |
448 if (start >= 0 && final < mat->slice_len) | |
449 { | |
450 done = true; | |
451 | |
452 double *data = array->jit_slice_data (); | |
453 if (step == 1) | |
454 std::fill (data + start, data + start + nelem, value); | |
455 else | |
456 { | |
457 for (octave_idx_type i = start; i < final; i += step) | |
458 data[i] = value; | |
459 } | |
460 } | |
461 } | |
462 | |
463 if (! done) | |
464 { | |
465 idx_vector idx (*index); | |
466 NDArray avalue (dim_vector (1, 1)); | |
467 avalue.xelem (0) = value; | |
468 array->assign (idx, avalue); | |
469 } | |
470 | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
471 jit_matrix ret; |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
472 ret.update (array); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
473 return ret; |
15016 | 474 } |
475 | |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
476 extern "C" double |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
477 octave_jit_end_matrix (jit_matrix *mat, octave_idx_type idx, |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
478 octave_idx_type count) |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
479 { |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
480 octave_idx_type ndim = mat->dimensions[-1]; |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
481 if (ndim == count) |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
482 return mat->dimensions[idx]; |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
483 else if (ndim > count) |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
484 { |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
485 if (idx == count - 1) |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
486 { |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
487 double ret = mat->dimensions[idx]; |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
488 for (octave_idx_type i = idx + 1; i < ndim; ++i) |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
489 ret *= mat->dimensions[idx]; |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
490 return ret; |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
491 } |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
492 |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
493 return mat->dimensions[idx]; |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
494 } |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
495 else // ndim < count |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
496 return idx < ndim ? mat->dimensions[idx] : 1; |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
497 } |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
498 |
15337
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
499 extern "C" octave_base_value * |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
500 octave_jit_create_undef (void) |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
501 { |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
502 octave_value undef; |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
503 octave_base_value *ret = undef.internal_rep (); |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
504 ret->grab (); |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
505 |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
506 return ret; |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
507 } |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
508 |
15016 | 509 extern "C" Complex |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
510 octave_jit_complex_mul (Complex lhs, Complex rhs) |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
511 { |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
512 if (lhs.imag () == 0 && rhs.imag() == 0) |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
513 return Complex (lhs.real () * rhs.real (), 0); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
514 |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
515 return lhs * rhs; |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
516 } |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
517 |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
518 extern "C" Complex |
15016 | 519 octave_jit_complex_div (Complex lhs, Complex rhs) |
520 { | |
521 // see src/OPERATORS/op-cs-cs.cc | |
522 if (rhs == 0.0) | |
523 gripe_divide_by_zero (); | |
524 | |
525 return lhs / rhs; | |
526 } | |
527 | |
528 // FIXME: CP form src/xpow.cc | |
529 static inline int | |
530 xisint (double x) | |
531 { | |
532 return (D_NINT (x) == x | |
15215
9020dddc925a
use std::numeric_limits for integer max and min values
John W. Eaton <jwe@octave.org>
parents:
15195
diff
changeset
|
533 && ((x >= 0 && x < std::numeric_limits<int>::max ()) |
15219
aeba1adfd76b
Correct small typo in jit-typeinfo.cc
Melvin Robinson <melvin.robinson@mavs.uta.edu>
parents:
15215
diff
changeset
|
534 || (x <= 0 && x > std::numeric_limits<int>::min ()))); |
15016 | 535 } |
536 | |
537 extern "C" Complex | |
538 octave_jit_pow_scalar_scalar (double lhs, double rhs) | |
539 { | |
540 // FIXME: almost CP from src/xpow.cc | |
541 if (lhs < 0.0 && ! xisint (rhs)) | |
542 return std::pow (Complex (lhs), rhs); | |
543 return std::pow (lhs, rhs); | |
544 } | |
545 | |
546 extern "C" Complex | |
547 octave_jit_pow_complex_complex (Complex lhs, Complex rhs) | |
548 { | |
549 if (lhs.imag () == 0 && rhs.imag () == 0) | |
550 return octave_jit_pow_scalar_scalar (lhs.real (), rhs.real ()); | |
551 return std::pow (lhs, rhs); | |
552 } | |
553 | |
18554 | 554 // FIXME: should handle FloatComplex |
555 extern "C" Complex | |
556 octave_jit_pow_single_single (float lhs, float rhs) | |
557 { | |
558 // FIXME: almost CP from libinterp/corefcn/xpow.cc | |
559 float retval; | |
560 | |
561 if (lhs < 0.0 && ! xisint (rhs)) | |
562 { | |
563 FloatComplex lhstmp (lhs); | |
564 | |
565 return std::pow (lhstmp, rhs); | |
566 } | |
567 else | |
568 retval = std::pow (lhs, rhs); | |
569 | |
570 return retval; | |
571 } | |
572 | |
15016 | 573 extern "C" Complex |
574 octave_jit_pow_complex_scalar (Complex lhs, double rhs) | |
575 { | |
576 if (lhs.imag () == 0) | |
577 return octave_jit_pow_scalar_scalar (lhs.real (), rhs); | |
578 return std::pow (lhs, rhs); | |
579 } | |
580 | |
581 extern "C" Complex | |
582 octave_jit_pow_scalar_complex (double lhs, Complex rhs) | |
583 { | |
584 if (rhs.imag () == 0) | |
585 return octave_jit_pow_scalar_scalar (lhs, rhs.real ()); | |
586 return std::pow (lhs, rhs); | |
587 } | |
588 | |
18555 | 589 /************************************************************ |
590 * | |
18557 | 591 * int8 related external helper function |
592 * | |
593 ************************************************************/ | |
594 | |
595 extern "C" int8_t | |
596 octave_jit_add_int8_int8 (int8_t lhs, int8_t rhs) | |
597 { | |
598 uint8_t ulhs = lhs; | |
599 uint8_t urhs = rhs; | |
600 uint8_t res = ulhs + urhs; | |
601 | |
602 /* Calculate overflowed result. (Don't change the sign bit of ux) */ | |
603 ulhs = (ulhs >> 7) + SCHAR_MAX; | |
604 | |
605 /* Force compiler to use cmovns instruction */ | |
606 if ((int8_t) ((ulhs ^ urhs) | ~(urhs ^ res)) >= 0) | |
607 { | |
608 res = ulhs; | |
609 } | |
610 | |
611 return res; | |
612 } | |
613 | |
614 extern "C" int8_t | |
615 octave_jit_sub_int8_int8 (int8_t lhs, int8_t rhs) | |
616 { | |
617 uint8_t ulhs = lhs; | |
618 uint8_t urhs = rhs; | |
619 uint8_t res = ulhs - urhs; | |
620 | |
621 ulhs = (ulhs >> 7) + SCHAR_MAX; | |
622 | |
623 /* Force compiler to use cmovns instruction */ | |
624 if ((int8_t)((ulhs ^ urhs) & (ulhs ^ res)) < 0) | |
625 { | |
626 res = ulhs; | |
627 } | |
628 | |
629 return res; | |
630 } | |
631 | |
632 extern "C" int8_t | |
633 octave_jit_mul_int8_int8 (int8_t lhs, int8_t rhs) | |
634 { | |
635 int16_t res = (int16_t) lhs * (int16_t) rhs; | |
636 uint8_t res2 = ((uint8_t) (lhs ^ rhs) >> 7) + SCHAR_MAX; | |
637 | |
638 int8_t hi = (res >> 8); | |
639 int8_t lo = res; | |
640 | |
641 if (hi != (lo >> 7)) res = res2; | |
642 | |
643 return res; | |
644 } | |
645 | |
646 extern "C" int8_t | |
647 octave_jit_incr_int8 (int8_t val) | |
648 { | |
649 return octave_jit_add_int8_int8 (val, 1); | |
650 } | |
651 | |
652 extern "C" int8_t | |
653 octave_jit_decr_int8 (int8_t val) | |
654 { | |
655 return octave_jit_sub_int8_int8 (val, 1); | |
656 } | |
657 | |
658 /************************************************************ | |
659 * | |
18559 | 660 * int16 related external helper function |
661 * | |
662 ************************************************************/ | |
663 | |
664 extern "C" int16_t | |
665 octave_jit_add_int16_int16 (int16_t lhs, int16_t rhs) | |
666 { | |
667 uint16_t ulhs = lhs; | |
668 uint16_t urhs = rhs; | |
669 uint16_t res = ulhs + urhs; | |
670 | |
671 /* Calculate overflowed result. (Don't change the sign bit of ux) */ | |
672 ulhs = (ulhs >> 15) + SHRT_MAX; | |
673 | |
674 /* Force compiler to use cmovns instruction */ | |
675 if ((int16_t) ((ulhs ^ urhs) | ~(urhs ^ res)) >= 0) | |
676 { | |
677 res = ulhs; | |
678 } | |
679 | |
680 return res; | |
681 } | |
682 | |
683 extern "C" int16_t | |
684 octave_jit_sub_int16_int16 (int16_t lhs, int16_t rhs) | |
685 { | |
686 uint16_t ulhs = lhs; | |
687 uint16_t urhs = rhs; | |
688 uint16_t res = ulhs - urhs; | |
689 | |
690 ulhs = (ulhs >> 15) + SHRT_MAX; | |
691 | |
692 /* Force compiler to use cmovns instruction */ | |
693 if ((int16_t)((ulhs ^ urhs) & (ulhs ^ res)) < 0) | |
694 { | |
695 res = ulhs; | |
696 } | |
697 | |
698 return res; | |
699 } | |
700 | |
701 extern "C" int16_t | |
702 octave_jit_mul_int16_int16 (int16_t lhs, int16_t rhs) | |
703 { | |
704 int32_t res = (int32_t) lhs * (int32_t) rhs; | |
705 uint16_t res2 = ((uint16_t) (lhs ^ rhs) >> 15) + SHRT_MAX; | |
706 | |
707 int16_t hi = (res >> 16); | |
708 int16_t lo = res; | |
709 | |
710 if (hi != (lo >> 15)) res = res2; | |
711 | |
712 return res; | |
713 } | |
714 | |
715 extern "C" int16_t | |
716 octave_jit_incr_int16 (int16_t val) | |
717 { | |
718 return octave_jit_add_int16_int16 (val, 1); | |
719 } | |
720 | |
721 extern "C" int16_t | |
722 octave_jit_decr_int16 (int16_t val) | |
723 { | |
724 return octave_jit_sub_int16_int16 (val, 1); | |
725 } | |
726 | |
727 /************************************************************ | |
728 * | |
18560 | 729 * int32 related external helper function |
730 * | |
731 ************************************************************/ | |
732 | |
733 extern "C" int32_t | |
734 octave_jit_add_int32_int32 (int32_t lhs, int32_t rhs) | |
735 { | |
736 uint32_t ulhs = lhs; | |
737 uint32_t urhs = rhs; | |
738 uint32_t res = ulhs + urhs; | |
739 | |
740 /* Calculate overflowed result. (Don't change the sign bit of ux) */ | |
741 ulhs = (ulhs >> 31) + INT_MAX; | |
742 | |
743 /* Force compiler to use cmovns instruction */ | |
744 if ((int32_t) ((ulhs ^ urhs) | ~(urhs ^ res)) >= 0) | |
745 { | |
746 res = ulhs; | |
747 } | |
748 | |
749 return res; | |
750 } | |
751 | |
752 extern "C" int32_t | |
753 octave_jit_sub_int32_int32 (int32_t lhs, int32_t rhs) | |
754 { | |
755 uint32_t ulhs = lhs; | |
756 uint32_t urhs = rhs; | |
757 uint32_t res = ulhs - urhs; | |
758 | |
759 ulhs = (ulhs >> 31) + INT_MAX; | |
760 | |
761 /* Force compiler to use cmovns instruction */ | |
762 if ((int32_t)((ulhs ^ urhs) & (ulhs ^ res)) < 0) | |
763 { | |
764 res = ulhs; | |
765 } | |
766 | |
767 return res; | |
768 } | |
769 | |
770 extern "C" int32_t | |
771 octave_jit_mul_int32_int32 (int32_t lhs, int32_t rhs) | |
772 { | |
773 int64_t res = (int64_t) lhs * (int64_t) rhs; | |
774 uint32_t res2 = ((uint32_t) (lhs ^ rhs) >> 31) + INT_MAX; | |
775 | |
776 int32_t hi = (res >> 32); | |
777 int32_t lo = res; | |
778 | |
779 if (hi != (lo >> 31)) res = res2; | |
780 | |
781 return res; | |
782 } | |
783 | |
784 extern "C" int32_t | |
785 octave_jit_incr_int32 (int32_t val) | |
786 { | |
787 return octave_jit_add_int32_int32 (val, 1); | |
788 } | |
789 | |
790 extern "C" int32_t | |
791 octave_jit_decr_int32 (int32_t val) | |
792 { | |
793 return octave_jit_sub_int32_int32 (val, 1); | |
794 } | |
795 | |
796 /************************************************************ | |
797 * | |
18558
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
798 * int64 related external helper function |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
799 * |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
800 ************************************************************/ |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
801 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
802 extern "C" int64_t |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
803 octave_jit_add_int64_int64 (int64_t lhs, int64_t rhs) |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
804 { |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
805 uint64_t ulhs = lhs; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
806 uint64_t urhs = rhs; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
807 uint64_t res = ulhs + urhs; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
808 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
809 /* Calculate overflowed result. (Don't change the sign bit of ux) */ |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
810 ulhs = (ulhs >> 63) + LONG_MAX; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
811 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
812 /* Force compiler to use cmovns instruction */ |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
813 if ((int64_t) ((ulhs ^ urhs) | ~(urhs ^ res)) >= 0) |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
814 { |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
815 res = ulhs; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
816 } |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
817 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
818 return res; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
819 } |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
820 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
821 extern "C" int64_t |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
822 octave_jit_sub_int64_int64 (int64_t lhs, int64_t rhs) |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
823 { |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
824 uint64_t ulhs = lhs; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
825 uint64_t urhs = rhs; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
826 uint64_t res = ulhs - urhs; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
827 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
828 ulhs = (ulhs >> 63) + LONG_MAX; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
829 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
830 /* Force compiler to use cmovns instruction */ |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
831 if ((int64_t)((ulhs ^ urhs) & (ulhs ^ res)) < 0) |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
832 { |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
833 res = ulhs; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
834 } |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
835 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
836 return res; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
837 } |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
838 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
839 extern "C" int64_t |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
840 octave_jit_mul_int64_int64 (int64_t lhs, int64_t rhs) |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
841 { |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
842 #ifdef OCTAVE_INT_USE_LONG_DOUBLE |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
843 long double p = static_cast<long double> (lhs) * static_cast<long double> (rhs); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
844 if (p > static_cast<long double> (std::numeric_limits<int64_t>::max ())) |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
845 { |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
846 return std::numeric_limits<int64_t>::max (); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
847 } |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
848 else if (p < static_cast<long double> (std::numeric_limits<int64_t>::min ())) |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
849 { |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
850 return std::numeric_limits<int64_t>::min (); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
851 } |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
852 else |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
853 return static_cast<int64_t> (p); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
854 #else |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
855 __int128_t res = (__int128_t) lhs * (__int128_t) rhs; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
856 uint64_t res2 = ((uint64_t) (lhs ^ rhs) >> 63) + LONG_MAX; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
857 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
858 int64_t hi = (res >> 64); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
859 int64_t lo = res; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
860 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
861 if (hi != (lo >> 63)) res = res2; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
862 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
863 return res; |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
864 #endif |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
865 } |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
866 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
867 extern "C" int64_t |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
868 octave_jit_incr_int64 (int64_t val) |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
869 { |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
870 return octave_jit_add_int64_int64 (val, 1); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
871 } |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
872 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
873 extern "C" int64_t |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
874 octave_jit_decr_int64 (int64_t val) |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
875 { |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
876 return octave_jit_sub_int64_int64 (val, 1); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
877 } |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
878 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
879 /************************************************************ |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
880 * |
18561 | 881 * uint8 related external helper function |
882 * | |
883 ************************************************************/ | |
884 | |
885 extern "C" uint8_t | |
886 octave_jit_add_uint8_uint8 (uint8_t lhs, uint8_t rhs) | |
887 { | |
888 uint8_t res = lhs + rhs; | |
889 res |= -(res < lhs); | |
890 | |
891 return res; | |
892 } | |
893 | |
894 extern "C" uint8_t | |
895 octave_jit_sub_uint8_uint8 (uint8_t lhs, uint8_t rhs) | |
896 { | |
897 uint8_t res = lhs - rhs; | |
898 res &= -(res <= lhs); | |
899 | |
900 return res; | |
901 } | |
902 | |
903 extern "C" uint8_t | |
904 octave_jit_mul_uint8_uint8 (uint8_t lhs, uint8_t rhs) | |
905 { | |
906 uint16_t res = (uint16_t) lhs * (uint16_t) rhs; | |
907 | |
908 uint8_t hi = res >> 8; | |
909 uint8_t lo = res; | |
910 | |
911 return lo | -!!hi; | |
912 } | |
913 | |
914 extern "C" uint8_t | |
915 octave_jit_incr_uint8 (uint8_t val) | |
916 { | |
917 return octave_jit_add_uint8_uint8 (val, 1); | |
918 } | |
919 | |
920 extern "C" uint8_t | |
921 octave_jit_decr_uint8 (uint8_t val) | |
922 { | |
923 return octave_jit_sub_uint8_uint8 (val, 1); | |
924 } | |
925 | |
926 /************************************************************ | |
927 * | |
18555 | 928 * uint16 related external helper function |
929 * | |
930 ************************************************************/ | |
931 | |
932 extern "C" uint16_t | |
933 octave_jit_add_uint16_uint16 (uint16_t lhs, uint16_t rhs) | |
934 { | |
935 uint16_t res = lhs + rhs; | |
936 res |= -(res < lhs); | |
937 | |
938 return res; | |
939 } | |
940 | |
941 extern "C" uint16_t | |
942 octave_jit_sub_uint16_uint16 (uint16_t lhs, uint16_t rhs) | |
943 { | |
944 uint16_t res = lhs - rhs; | |
945 res &= -(res <= lhs); | |
946 | |
947 return res; | |
948 } | |
949 | |
950 extern "C" uint16_t | |
951 octave_jit_mul_uint16_uint16 (uint16_t lhs, uint16_t rhs) | |
952 { | |
953 uint32_t res = (uint32_t) lhs * (uint32_t) rhs; | |
954 | |
955 uint16_t hi = res >> 16; | |
956 uint16_t lo = res; | |
957 | |
958 return lo | -!!hi; | |
959 } | |
960 | |
961 extern "C" uint16_t | |
962 octave_jit_incr_uint16 (uint16_t val) | |
963 { | |
964 return octave_jit_add_uint16_uint16 (val, 1); | |
965 } | |
966 | |
967 extern "C" uint16_t | |
968 octave_jit_decr_uint16 (uint16_t val) | |
969 { | |
970 return octave_jit_sub_uint16_uint16 (val, 1); | |
971 } | |
972 | |
15016 | 973 extern "C" void |
974 octave_jit_print_matrix (jit_matrix *m) | |
975 { | |
976 std::cout << *m << std::endl; | |
977 } | |
978 | |
979 static void | |
980 gripe_bad_result (void) | |
981 { | |
982 error ("incorrect type information given to the JIT compiler"); | |
983 } | |
984 | |
985 // FIXME: Add support for multiple outputs | |
986 extern "C" octave_base_value * | |
987 octave_jit_call (octave_builtin::fcn fn, size_t nargin, | |
988 octave_base_value **argin, jit_type *result_type) | |
989 { | |
990 octave_value_list ovl (nargin); | |
991 for (size_t i = 0; i < nargin; ++i) | |
992 ovl.xelem (i) = octave_value (argin[i]); | |
993 | |
994 ovl = fn (ovl, 1); | |
995 | |
15169
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
996 // FIXME: Check result_type somehow |
15016 | 997 if (result_type) |
998 { | |
15169
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
999 if (ovl.length () < 1) |
15016 | 1000 { |
1001 gripe_bad_result (); | |
1002 return 0; | |
1003 } | |
1004 | |
15169
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
1005 octave_value result = ovl.xelem(0); |
15016 | 1006 octave_base_value *ret = result.internal_rep (); |
1007 ret->grab (); | |
1008 return ret; | |
1009 } | |
1010 | |
1011 if (! (ovl.length () == 0 | |
1012 || (ovl.length () == 1 && ovl.xelem (0).is_undefined ()))) | |
1013 gripe_bad_result (); | |
1014 | |
1015 return 0; | |
1016 } | |
1017 | |
1018 // -------------------- jit_range -------------------- | |
1019 bool | |
1020 jit_range::all_elements_are_ints () const | |
1021 { | |
1022 Range r (*this); | |
1023 return r.all_elements_are_ints (); | |
1024 } | |
1025 | |
1026 std::ostream& | |
1027 operator<< (std::ostream& os, const jit_range& rng) | |
1028 { | |
1029 return os << "Range[" << rng.base << ", " << rng.limit << ", " << rng.inc | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1030 << ", " << rng.nelem << "]"; |
15016 | 1031 } |
1032 | |
1033 // -------------------- jit_matrix -------------------- | |
1034 | |
1035 std::ostream& | |
1036 operator<< (std::ostream& os, const jit_matrix& mat) | |
1037 { | |
1038 return os << "Matrix[" << mat.ref_count << ", " << mat.slice_data << ", " | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1039 << mat.slice_len << ", " << mat.dimensions << ", " |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1040 << mat.array << "]"; |
15016 | 1041 } |
1042 | |
1043 // -------------------- jit_type -------------------- | |
1044 jit_type::jit_type (const std::string& aname, jit_type *aparent, | |
15124
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
1045 llvm::Type *allvm_type, bool askip_paren, int aid) : |
15016 | 1046 mname (aname), mparent (aparent), llvm_type (allvm_type), mid (aid), |
15124
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
1047 mdepth (aparent ? aparent->mdepth + 1 : 0), mskip_paren (askip_paren) |
15016 | 1048 { |
1049 std::memset (msret, 0, sizeof (msret)); | |
1050 std::memset (mpointer_arg, 0, sizeof (mpointer_arg)); | |
1051 std::memset (mpack, 0, sizeof (mpack)); | |
1052 std::memset (munpack, 0, sizeof (munpack)); | |
1053 | |
1054 for (size_t i = 0; i < jit_convention::length; ++i) | |
1055 mpacked_type[i] = llvm_type; | |
1056 } | |
1057 | |
1058 llvm::Type * | |
1059 jit_type::to_llvm_arg (void) const | |
1060 { | |
1061 return llvm_type ? llvm_type->getPointerTo () : 0; | |
1062 } | |
1063 | |
1064 // -------------------- jit_function -------------------- | |
1065 jit_function::jit_function () : module (0), llvm_function (0), mresult (0), | |
1066 call_conv (jit_convention::length), | |
1067 mcan_error (false) | |
1068 {} | |
1069 | |
1070 jit_function::jit_function (llvm::Module *amodule, | |
1071 jit_convention::type acall_conv, | |
1072 const llvm::Twine& aname, jit_type *aresult, | |
1073 const std::vector<jit_type *>& aargs) | |
1074 : module (amodule), mresult (aresult), args (aargs), call_conv (acall_conv), | |
1075 mcan_error (false) | |
1076 { | |
1077 llvm::SmallVector<llvm::Type *, 15> llvm_args; | |
1078 | |
1079 llvm::Type *rtype = llvm::Type::getVoidTy (context); | |
1080 if (mresult) | |
1081 { | |
1082 rtype = mresult->packed_type (call_conv); | |
1083 if (sret ()) | |
1084 { | |
1085 llvm_args.push_back (rtype->getPointerTo ()); | |
1086 rtype = llvm::Type::getVoidTy (context); | |
1087 } | |
1088 } | |
1089 | |
1090 for (std::vector<jit_type *>::const_iterator iter = args.begin (); | |
1091 iter != args.end (); ++iter) | |
1092 { | |
1093 jit_type *ty = *iter; | |
1094 assert (ty); | |
1095 llvm::Type *argty = ty->packed_type (call_conv); | |
1096 if (ty->pointer_arg (call_conv)) | |
1097 argty = argty->getPointerTo (); | |
1098 | |
1099 llvm_args.push_back (argty); | |
1100 } | |
1101 | |
1102 // we mark all functinos as external linkage because this prevents llvm | |
1103 // from getting rid of always inline functions | |
1104 llvm::FunctionType *ft = llvm::FunctionType::get (rtype, llvm_args, false); | |
1105 llvm_function = llvm::Function::Create (ft, llvm::Function::ExternalLinkage, | |
1106 aname, module); | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1107 |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1108 if (sret ()) |
17031
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1109 { |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1110 #ifdef FUNCTION_ADDATTRIBUTE_ARG_IS_ATTRIBUTES |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1111 llvm::AttrBuilder attr_builder; |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1112 attr_builder.addAttribute (llvm::Attributes::StructRet); |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1113 llvm::Attributes attrs = llvm::Attributes::get(context, attr_builder); |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1114 llvm_function->addAttribute (1, attrs); |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1115 #else |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1116 llvm_function->addAttribute (1, llvm::Attribute::StructRet); |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1117 #endif |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1118 } |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1119 |
15016 | 1120 if (call_conv == jit_convention::internal) |
17031
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1121 #ifdef FUNCTION_ADDFNATTR_ARG_IS_ATTRIBUTES |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1122 llvm_function->addFnAttr (llvm::Attributes::AlwaysInline); |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1123 #else |
15016 | 1124 llvm_function->addFnAttr (llvm::Attribute::AlwaysInline); |
17031
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1125 #endif |
15016 | 1126 } |
1127 | |
1128 jit_function::jit_function (const jit_function& fn, jit_type *aresult, | |
1129 const std::vector<jit_type *>& aargs) | |
1130 : module (fn.module), llvm_function (fn.llvm_function), mresult (aresult), | |
1131 args (aargs), call_conv (fn.call_conv), mcan_error (fn.mcan_error) | |
1132 { | |
1133 } | |
1134 | |
1135 jit_function::jit_function (const jit_function& fn) | |
1136 : module (fn.module), llvm_function (fn.llvm_function), mresult (fn.mresult), | |
1137 args (fn.args), call_conv (fn.call_conv), mcan_error (fn.mcan_error) | |
1138 {} | |
1139 | |
15385
8ccb187b24e9
Erase partially created functions on JIT compilation failure (bug #37308)
Max Brister <max@2bass.com>
parents:
15370
diff
changeset
|
1140 void |
8ccb187b24e9
Erase partially created functions on JIT compilation failure (bug #37308)
Max Brister <max@2bass.com>
parents:
15370
diff
changeset
|
1141 jit_function::erase (void) |
8ccb187b24e9
Erase partially created functions on JIT compilation failure (bug #37308)
Max Brister <max@2bass.com>
parents:
15370
diff
changeset
|
1142 { |
8ccb187b24e9
Erase partially created functions on JIT compilation failure (bug #37308)
Max Brister <max@2bass.com>
parents:
15370
diff
changeset
|
1143 if (! llvm_function) |
8ccb187b24e9
Erase partially created functions on JIT compilation failure (bug #37308)
Max Brister <max@2bass.com>
parents:
15370
diff
changeset
|
1144 return; |
8ccb187b24e9
Erase partially created functions on JIT compilation failure (bug #37308)
Max Brister <max@2bass.com>
parents:
15370
diff
changeset
|
1145 |
8ccb187b24e9
Erase partially created functions on JIT compilation failure (bug #37308)
Max Brister <max@2bass.com>
parents:
15370
diff
changeset
|
1146 llvm_function->eraseFromParent (); |
8ccb187b24e9
Erase partially created functions on JIT compilation failure (bug #37308)
Max Brister <max@2bass.com>
parents:
15370
diff
changeset
|
1147 llvm_function = 0; |
8ccb187b24e9
Erase partially created functions on JIT compilation failure (bug #37308)
Max Brister <max@2bass.com>
parents:
15370
diff
changeset
|
1148 } |
8ccb187b24e9
Erase partially created functions on JIT compilation failure (bug #37308)
Max Brister <max@2bass.com>
parents:
15370
diff
changeset
|
1149 |
15016 | 1150 std::string |
1151 jit_function::name (void) const | |
1152 { | |
1153 return llvm_function->getName (); | |
1154 } | |
1155 | |
1156 llvm::BasicBlock * | |
1157 jit_function::new_block (const std::string& aname, | |
1158 llvm::BasicBlock *insert_before) | |
1159 { | |
1160 return llvm::BasicBlock::Create (context, aname, llvm_function, | |
1161 insert_before); | |
1162 } | |
1163 | |
1164 llvm::Value * | |
1165 jit_function::call (llvm::IRBuilderD& builder, | |
1166 const std::vector<jit_value *>& in_args) const | |
1167 { | |
18556
4d285a169b29
add comment for function support
LYH <lyh.kernel@gmail.com>
parents:
18555
diff
changeset
|
1168 // FIXME: Unhandled case: |
4d285a169b29
add comment for function support
LYH <lyh.kernel@gmail.com>
parents:
18555
diff
changeset
|
1169 // function ret = lt(x, y) |
4d285a169b29
add comment for function support
LYH <lyh.kernel@gmail.com>
parents:
18555
diff
changeset
|
1170 // ret = x < y; |
4d285a169b29
add comment for function support
LYH <lyh.kernel@gmail.com>
parents:
18555
diff
changeset
|
1171 // endfunction |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
1172 if (! valid ()) |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
1173 throw jit_fail_exception ("Call not implemented"); |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
1174 |
15016 | 1175 assert (in_args.size () == args.size ()); |
1176 std::vector<llvm::Value *> llvm_args (args.size ()); | |
1177 for (size_t i = 0; i < in_args.size (); ++i) | |
1178 llvm_args[i] = in_args[i]->to_llvm (); | |
1179 | |
1180 return call (builder, llvm_args); | |
1181 } | |
1182 | |
1183 llvm::Value * | |
1184 jit_function::call (llvm::IRBuilderD& builder, | |
1185 const std::vector<llvm::Value *>& in_args) const | |
1186 { | |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
1187 if (! valid ()) |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
1188 throw jit_fail_exception ("Call not implemented"); |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
1189 |
15016 | 1190 assert (in_args.size () == args.size ()); |
1191 llvm::SmallVector<llvm::Value *, 10> llvm_args; | |
1192 llvm_args.reserve (in_args.size () + sret ()); | |
1193 | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1194 llvm::BasicBlock *insert_block = builder.GetInsertBlock (); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1195 llvm::Function *parent = insert_block->getParent (); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1196 assert (parent); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1197 |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1198 // we insert allocas inside the prelude block to prevent stack overflows |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1199 llvm::BasicBlock& prelude = parent->getEntryBlock (); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1200 llvm::IRBuilder<> pre_builder (&prelude, prelude.begin ()); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1201 |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1202 llvm::AllocaInst *sret_mem = 0; |
15016 | 1203 if (sret ()) |
1204 { | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1205 sret_mem = pre_builder.CreateAlloca (mresult->packed_type (call_conv)); |
15016 | 1206 llvm_args.push_back (sret_mem); |
1207 } | |
1208 | |
1209 for (size_t i = 0; i < in_args.size (); ++i) | |
1210 { | |
1211 llvm::Value *arg = in_args[i]; | |
1212 jit_type::convert_fn convert = args[i]->pack (call_conv); | |
1213 if (convert) | |
1214 arg = convert (builder, arg); | |
1215 | |
1216 if (args[i]->pointer_arg (call_conv)) | |
1217 { | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1218 llvm::Type *ty = args[i]->packed_type (call_conv); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1219 llvm::Value *alloca = pre_builder.CreateAlloca (ty); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1220 builder.CreateStore (arg, alloca); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1221 arg = alloca; |
15016 | 1222 } |
1223 | |
1224 llvm_args.push_back (arg); | |
1225 } | |
1226 | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1227 llvm::CallInst *callinst = builder.CreateCall (llvm_function, llvm_args); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1228 llvm::Value *ret = callinst; |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1229 |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1230 if (sret ()) |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1231 { |
17031
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1232 #ifdef CALLINST_ADDATTRIBUTE_ARG_IS_ATTRIBUTES |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1233 llvm::AttrBuilder attr_builder; |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1234 attr_builder.addAttribute(llvm::Attributes::StructRet); |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1235 llvm::Attributes attrs = llvm::Attributes::get(context, attr_builder); |
17031
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1236 callinst->addAttribute (1, attrs); |
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1237 #else |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1238 callinst->addAttribute (1, llvm::Attribute::StructRet); |
17031
38bcfd413db0
Handle LLVM API incoherence. Octave now works with LLVM 3.0, 3.1, and 3.2
LYH <lyh.kernel@gmail.com>
parents:
16892
diff
changeset
|
1239 #endif |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1240 ret = builder.CreateLoad (sret_mem); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1241 } |
15016 | 1242 |
1243 if (mresult) | |
1244 { | |
1245 jit_type::convert_fn unpack = mresult->unpack (call_conv); | |
1246 if (unpack) | |
1247 ret = unpack (builder, ret); | |
1248 } | |
1249 | |
1250 return ret; | |
1251 } | |
1252 | |
1253 llvm::Value * | |
1254 jit_function::argument (llvm::IRBuilderD& builder, size_t idx) const | |
1255 { | |
1256 assert (idx < args.size ()); | |
1257 | |
1258 // FIXME: We should be treating arguments like a list, not a vector. Shouldn't | |
1259 // matter much for now, as the number of arguments shouldn't be much bigger | |
1260 // than 4 | |
1261 llvm::Function::arg_iterator iter = llvm_function->arg_begin (); | |
1262 if (sret ()) | |
1263 ++iter; | |
1264 | |
1265 for (size_t i = 0; i < idx; ++i, ++iter); | |
1266 | |
1267 if (args[idx]->pointer_arg (call_conv)) | |
1268 return builder.CreateLoad (iter); | |
1269 | |
1270 return iter; | |
1271 } | |
1272 | |
1273 void | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1274 jit_function::do_return (llvm::IRBuilderD& builder, llvm::Value *rval, |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1275 bool verify) |
15016 | 1276 { |
1277 assert (! rval == ! mresult); | |
1278 | |
1279 if (rval) | |
1280 { | |
1281 jit_type::convert_fn convert = mresult->pack (call_conv); | |
1282 if (convert) | |
1283 rval = convert (builder, rval); | |
1284 | |
1285 if (sret ()) | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1286 { |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1287 builder.CreateStore (rval, llvm_function->arg_begin ()); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1288 builder.CreateRetVoid (); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1289 } |
15016 | 1290 else |
1291 builder.CreateRet (rval); | |
1292 } | |
1293 else | |
1294 builder.CreateRetVoid (); | |
1295 | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1296 if (verify) |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1297 llvm::verifyFunction (*llvm_function); |
15016 | 1298 } |
1299 | |
15019
ae3670d4df29
Update the execution engine's global mapping for external functions
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1300 void |
ae3670d4df29
Update the execution engine's global mapping for external functions
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1301 jit_function::do_add_mapping (llvm::ExecutionEngine *engine, void *fn) |
ae3670d4df29
Update the execution engine's global mapping for external functions
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1302 { |
ae3670d4df29
Update the execution engine's global mapping for external functions
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1303 assert (valid ()); |
ae3670d4df29
Update the execution engine's global mapping for external functions
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1304 engine->addGlobalMapping (llvm_function, fn); |
ae3670d4df29
Update the execution engine's global mapping for external functions
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1305 } |
ae3670d4df29
Update the execution engine's global mapping for external functions
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
1306 |
15016 | 1307 std::ostream& |
1308 operator<< (std::ostream& os, const jit_function& fn) | |
1309 { | |
1310 llvm::Function *lfn = fn.to_llvm (); | |
1311 os << "jit_function: cc=" << fn.call_conv; | |
1312 llvm::raw_os_ostream llvm_out (os); | |
1313 lfn->print (llvm_out); | |
1314 llvm_out.flush (); | |
1315 return os; | |
1316 } | |
1317 | |
1318 // -------------------- jit_operation -------------------- | |
15078
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1319 jit_operation::~jit_operation (void) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1320 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1321 for (generated_map::iterator iter = generated.begin (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1322 iter != generated.end (); ++iter) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1323 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1324 delete iter->first; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1325 delete iter->second; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1326 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1327 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1328 |
15016 | 1329 void |
1330 jit_operation::add_overload (const jit_function& func, | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
1331 const std::vector<jit_type*>& args) |
15016 | 1332 { |
1333 if (args.size () >= overloads.size ()) | |
1334 overloads.resize (args.size () + 1); | |
1335 | |
1336 Array<jit_function>& over = overloads[args.size ()]; | |
1337 dim_vector dv (over.dims ()); | |
1338 Array<octave_idx_type> idx = to_idx (args); | |
1339 bool must_resize = false; | |
1340 | |
1341 if (dv.length () != idx.numel ()) | |
1342 { | |
1343 dv.resize (idx.numel ()); | |
1344 must_resize = true; | |
1345 } | |
1346 | |
1347 for (octave_idx_type i = 0; i < dv.length (); ++i) | |
1348 if (dv(i) <= idx(i)) | |
1349 { | |
1350 must_resize = true; | |
1351 dv(i) = idx(i) + 1; | |
1352 } | |
1353 | |
1354 if (must_resize) | |
1355 over.resize (dv); | |
1356 | |
1357 over(idx) = func; | |
1358 } | |
1359 | |
1360 const jit_function& | |
1361 jit_operation::overload (const std::vector<jit_type*>& types) const | |
1362 { | |
1363 static jit_function null_overload; | |
1364 for (size_t i =0; i < types.size (); ++i) | |
1365 if (! types[i]) | |
1366 return null_overload; | |
1367 | |
15078
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1368 if (types.size () >= overloads.size ()) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1369 return do_generate (types); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1370 |
15016 | 1371 const Array<jit_function>& over = overloads[types.size ()]; |
1372 dim_vector dv (over.dims ()); | |
1373 Array<octave_idx_type> idx = to_idx (types); | |
1374 for (octave_idx_type i = 0; i < dv.length (); ++i) | |
1375 if (idx(i) >= dv(i)) | |
15078
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1376 return do_generate (types); |
15016 | 1377 |
15078
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1378 const jit_function& ret = over(idx); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1379 if (! ret.valid ()) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1380 return do_generate (types); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1381 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1382 return ret; |
15016 | 1383 } |
1384 | |
1385 Array<octave_idx_type> | |
1386 jit_operation::to_idx (const std::vector<jit_type*>& types) const | |
1387 { | |
1388 octave_idx_type numel = types.size (); | |
18277
cc1c19863ae3
jit-typeinfo.cc: Fix C++ function ambiguity (bug #41145).
Lasse Schuirmann <lasse@schuirmann.net>
parents:
18274
diff
changeset
|
1389 numel = std::max (numel, static_cast<octave_idx_type>(2)); |
15016 | 1390 |
1391 Array<octave_idx_type> idx (dim_vector (1, numel)); | |
1392 for (octave_idx_type i = 0; i < static_cast<octave_idx_type> (types.size ()); | |
1393 ++i) | |
1394 idx(i) = types[i]->type_id (); | |
1395 | |
15337
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
1396 if (types.size () == 0) |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
1397 idx(0) = idx(1) = 0; |
15016 | 1398 if (types.size () == 1) |
1399 { | |
1400 idx(1) = idx(0); | |
1401 idx(0) = 0; | |
1402 } | |
1403 | |
1404 return idx; | |
1405 } | |
1406 | |
15078
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1407 const jit_function& |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1408 jit_operation::do_generate (const signature_vec& types) const |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1409 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1410 static jit_function null_overload; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1411 generated_map::const_iterator find = generated.find (&types); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1412 if (find != generated.end ()) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1413 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1414 if (find->second) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1415 return *find->second; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1416 else |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1417 return null_overload; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1418 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1419 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1420 jit_function *ret = generate (types); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1421 generated[new signature_vec (types)] = ret; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1422 return ret ? *ret : null_overload; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1423 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1424 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1425 jit_function * |
15135
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
1426 jit_operation::generate (const signature_vec&) const |
15078
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1427 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1428 return 0; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1429 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1430 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1431 bool |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1432 jit_operation::signature_cmp |
18222
4d90e104bf35
Allow jit-typeinfo.h to compile with clang on OS X (bug #41114)
Michael C. Grant <mcg@cvxr.com>
parents:
17787
diff
changeset
|
1433 ::operator() (const signature_vec *lhs, const signature_vec *rhs) const |
15078
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1434 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1435 const signature_vec& l = *lhs; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1436 const signature_vec& r = *rhs; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1437 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1438 if (l.size () < r.size ()) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1439 return true; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1440 else if (l.size () > r.size ()) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1441 return false; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1442 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1443 for (size_t i = 0; i < l.size (); ++i) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1444 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1445 if (l[i]->type_id () < r[i]->type_id ()) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1446 return true; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1447 else if (l[i]->type_id () > r[i]->type_id ()) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1448 return false; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1449 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1450 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1451 return false; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1452 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1453 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1454 // -------------------- jit_index_operation -------------------- |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1455 jit_function * |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1456 jit_index_operation::generate (const signature_vec& types) const |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1457 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1458 if (types.size () > 2 && types[0] == jit_typeinfo::get_matrix ()) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1459 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1460 // indexing a matrix with scalars |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1461 jit_type *scalar = jit_typeinfo::get_scalar (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1462 for (size_t i = 1; i < types.size (); ++i) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1463 if (types[i] != scalar) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1464 return 0; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1465 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1466 return generate_matrix (types); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1467 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1468 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1469 return 0; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1470 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1471 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1472 llvm::Value * |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1473 jit_index_operation::create_arg_array (llvm::IRBuilderD& builder, |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1474 const jit_function &fn, size_t start_idx, |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1475 size_t end_idx) const |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1476 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1477 size_t n = end_idx - start_idx; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1478 llvm::Type *scalar_t = jit_typeinfo::get_scalar_llvm (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1479 llvm::ArrayType *array_t = llvm::ArrayType::get (scalar_t, n); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1480 llvm::Value *array = llvm::UndefValue::get (array_t); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1481 for (size_t i = start_idx; i < end_idx; ++i) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1482 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1483 llvm::Value *idx = fn.argument (builder, i); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1484 array = builder.CreateInsertValue (array, idx, i - start_idx); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1485 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1486 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1487 llvm::Value *array_mem = builder.CreateAlloca (array_t); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1488 builder.CreateStore (array, array_mem); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1489 return builder.CreateBitCast (array_mem, scalar_t->getPointerTo ()); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1490 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1491 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1492 // -------------------- jit_paren_subsref -------------------- |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1493 jit_function * |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1494 jit_paren_subsref::generate_matrix (const signature_vec& types) const |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1495 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1496 std::stringstream ss; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1497 ss << "jit_paren_subsref_matrix_scalar" << (types.size () - 1); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1498 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1499 jit_type *scalar = jit_typeinfo::get_scalar (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1500 jit_function *fn = new jit_function (module, jit_convention::internal, |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1501 ss.str (), scalar, types); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1502 fn->mark_can_error (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1503 llvm::BasicBlock *body = fn->new_block (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1504 llvm::IRBuilder<> builder (body); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1505 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1506 llvm::Value *array = create_arg_array (builder, *fn, 1, types.size ()); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1507 jit_type *index = jit_typeinfo::get_index (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1508 llvm::Value *nelem = llvm::ConstantInt::get (index->to_llvm (), |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1509 types.size () - 1); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1510 llvm::Value *mat = fn->argument (builder, 0); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1511 llvm::Value *ret = paren_scalar.call (builder, mat, array, nelem); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1512 fn->do_return (builder, ret); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1513 return fn; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1514 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1515 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1516 void |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1517 jit_paren_subsref::do_initialize (void) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1518 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1519 std::vector<jit_type *> types (3); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1520 types[0] = jit_typeinfo::get_matrix (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1521 types[1] = jit_typeinfo::get_scalar_ptr (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1522 types[2] = jit_typeinfo::get_index (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1523 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1524 jit_type *scalar = jit_typeinfo::get_scalar (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1525 paren_scalar = jit_function (module, jit_convention::external, |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1526 "octave_jit_paren_scalar", scalar, types); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1527 paren_scalar.add_mapping (engine, &octave_jit_paren_scalar); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1528 paren_scalar.mark_can_error (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1529 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1530 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1531 // -------------------- jit_paren_subsasgn -------------------- |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1532 jit_function * |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1533 jit_paren_subsasgn::generate_matrix (const signature_vec& types) const |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1534 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1535 std::stringstream ss; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1536 ss << "jit_paren_subsasgn_matrix_scalar" << (types.size () - 2); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1537 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1538 jit_type *matrix = jit_typeinfo::get_matrix (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1539 jit_function *fn = new jit_function (module, jit_convention::internal, |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1540 ss.str (), matrix, types); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1541 fn->mark_can_error (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1542 llvm::BasicBlock *body = fn->new_block (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1543 llvm::IRBuilder<> builder (body); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1544 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1545 llvm::Value *array = create_arg_array (builder, *fn, 1, types.size () - 1); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1546 jit_type *index = jit_typeinfo::get_index (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1547 llvm::Value *nelem = llvm::ConstantInt::get (index->to_llvm (), |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1548 types.size () - 2); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1549 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1550 llvm::Value *mat = fn->argument (builder, 0); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1551 llvm::Value *value = fn->argument (builder, types.size () - 1); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1552 llvm::Value *ret = paren_scalar.call (builder, mat, array, nelem, value); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1553 fn->do_return (builder, ret); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1554 return fn; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1555 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1556 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1557 void |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1558 jit_paren_subsasgn::do_initialize (void) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1559 { |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1560 if (paren_scalar.valid ()) |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1561 return; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1562 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1563 jit_type *matrix = jit_typeinfo::get_matrix (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1564 std::vector<jit_type *> types (4); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1565 types[0] = matrix; |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1566 types[1] = jit_typeinfo::get_scalar_ptr (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1567 types[2] = jit_typeinfo::get_index (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1568 types[3] = jit_typeinfo::get_scalar (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1569 |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1570 paren_scalar = jit_function (module, jit_convention::external, |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1571 "octave_jit_paren_scalar", matrix, types); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1572 paren_scalar.add_mapping (engine, &octave_jit_paren_scalar_subsasgn); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1573 paren_scalar.mark_can_error (); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1574 } |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1575 |
15016 | 1576 // -------------------- jit_typeinfo -------------------- |
1577 void | |
1578 jit_typeinfo::initialize (llvm::Module *m, llvm::ExecutionEngine *e) | |
1579 { | |
1580 new jit_typeinfo (m, e); | |
1581 } | |
1582 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1583 // wrap function names to simplify jit_typeinfo::create_external |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1584 #define JIT_FN(fn) engine, &fn, #fn |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1585 |
15016 | 1586 jit_typeinfo::jit_typeinfo (llvm::Module *m, llvm::ExecutionEngine *e) |
1587 : module (m), engine (e), next_id (0), | |
1588 builder (*new llvm::IRBuilderD (context)) | |
1589 { | |
1590 instance = this; | |
1591 | |
1592 // FIXME: We should be registering types like in octave_value_typeinfo | |
1593 llvm::Type *any_t = llvm::StructType::create (context, "octave_base_value"); | |
1594 any_t = any_t->getPointerTo (); | |
1595 | |
1596 llvm::Type *scalar_t = llvm::Type::getDoubleTy (context); | |
18554 | 1597 llvm::Type *single_t = llvm::Type::getFloatTy (context); |
18557 | 1598 llvm::Type *int8__t = llvm::Type::getIntNTy (context, 8); |
18559 | 1599 llvm::Type *int16__t = llvm::Type::getIntNTy (context, 16); |
18560 | 1600 llvm::Type *int32__t = llvm::Type::getIntNTy (context, 32); |
18558
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
1601 llvm::Type *int64__t = llvm::Type::getIntNTy (context, 64); |
18561 | 1602 llvm::Type *uint8__t = llvm::Type::getIntNTy (context, 8); |
18555 | 1603 llvm::Type *uint16__t = llvm::Type::getIntNTy (context, 16); |
15016 | 1604 llvm::Type *bool_t = llvm::Type::getInt1Ty (context); |
1605 llvm::Type *string_t = llvm::Type::getInt8Ty (context); | |
1606 string_t = string_t->getPointerTo (); | |
1607 llvm::Type *index_t = llvm::Type::getIntNTy (context, | |
1608 sizeof(octave_idx_type) * 8); | |
1609 | |
1610 llvm::StructType *range_t = llvm::StructType::create (context, "range"); | |
1611 std::vector<llvm::Type *> range_contents (4, scalar_t); | |
1612 range_contents[3] = index_t; | |
1613 range_t->setBody (range_contents); | |
1614 | |
1615 llvm::Type *refcount_t = llvm::Type::getIntNTy (context, sizeof(int) * 8); | |
1616 | |
1617 llvm::StructType *matrix_t = llvm::StructType::create (context, "matrix"); | |
1618 llvm::Type *matrix_contents[5]; | |
1619 matrix_contents[0] = refcount_t->getPointerTo (); | |
1620 matrix_contents[1] = scalar_t->getPointerTo (); | |
1621 matrix_contents[2] = index_t; | |
1622 matrix_contents[3] = index_t->getPointerTo (); | |
1623 matrix_contents[4] = string_t; | |
1624 matrix_t->setBody (llvm::makeArrayRef (matrix_contents, 5)); | |
1625 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1626 llvm::Type *complex_t = llvm::ArrayType::get (scalar_t, 2); |
15016 | 1627 |
1628 // complex_ret is what is passed to C functions in order to get calling | |
1629 // convention right | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1630 llvm::Type *cmplx_inner_cont[] = {scalar_t, scalar_t}; |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1631 llvm::StructType *cmplx_inner = llvm::StructType::create (cmplx_inner_cont); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1632 |
15016 | 1633 complex_ret = llvm::StructType::create (context, "complex_ret"); |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1634 { |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1635 llvm::Type *contents[] = {cmplx_inner}; |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1636 complex_ret->setBody (contents); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1637 } |
15016 | 1638 |
1639 // create types | |
1640 any = new_type ("any", 0, any_t); | |
1641 matrix = new_type ("matrix", any, matrix_t); | |
1642 complex = new_type ("complex", any, complex_t); | |
1643 scalar = new_type ("scalar", complex, scalar_t); | |
18554 | 1644 single = new_type ("single", any, single_t); |
15078
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1645 scalar_ptr = new_type ("scalar_ptr", 0, scalar_t->getPointerTo ()); |
15135
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
1646 any_ptr = new_type ("any_ptr", 0, any_t->getPointerTo ()); |
15016 | 1647 range = new_type ("range", any, range_t); |
1648 string = new_type ("string", any, string_t); | |
1649 boolean = new_type ("bool", any, bool_t); | |
1650 index = new_type ("index", any, index_t); | |
1651 | |
1652 create_int (8); | |
1653 create_int (16); | |
1654 create_int (32); | |
1655 create_int (64); | |
1656 | |
18561 | 1657 create_uint (8); |
18555 | 1658 create_uint (16); |
1659 | |
15016 | 1660 casts.resize (next_id + 1); |
1661 identities.resize (next_id + 1); | |
1662 | |
1663 // specify calling conventions | |
1664 // FIXME: We should detect architecture and do something sane based on that | |
1665 // here we assume x86 or x86_64 | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1666 matrix->mark_sret (jit_convention::external); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1667 matrix->mark_pointer_arg (jit_convention::external); |
15016 | 1668 |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1669 range->mark_sret (jit_convention::external); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1670 range->mark_pointer_arg (jit_convention::external); |
15016 | 1671 |
1672 complex->set_pack (jit_convention::external, &jit_typeinfo::pack_complex); | |
1673 complex->set_unpack (jit_convention::external, &jit_typeinfo::unpack_complex); | |
1674 complex->set_packed_type (jit_convention::external, complex_ret); | |
1675 | |
1676 if (sizeof (void *) == 4) | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
1677 complex->mark_sret (jit_convention::external); |
15016 | 1678 |
15078
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1679 paren_subsref_fn.initialize (module, engine); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1680 paren_subsasgn_fn.initialize (module, engine); |
fe4752f772e2
Generate ND indexing functions on demand in JIT.
Max Brister <max@2bass.com>
parents:
15068
diff
changeset
|
1681 |
15016 | 1682 // bind global variables |
1683 lerror_state = new llvm::GlobalVariable (*module, bool_t, false, | |
1684 llvm::GlobalValue::ExternalLinkage, | |
1685 0, "error_state"); | |
1686 engine->addGlobalMapping (lerror_state, | |
1687 reinterpret_cast<void *> (&error_state)); | |
1688 | |
15603 | 1689 // sig_atomic_type is going to be some sort of integer |
1690 sig_atomic_type = llvm::Type::getIntNTy (context, sizeof(sig_atomic_t) * 8); | |
1691 loctave_interrupt_state | |
1692 = new llvm::GlobalVariable (*module, sig_atomic_type, false, | |
1693 llvm::GlobalValue::ExternalLinkage, 0, | |
1694 "octave_interrupt_state"); | |
1695 engine->addGlobalMapping (loctave_interrupt_state, | |
1696 reinterpret_cast<void *> (&octave_interrupt_state)); | |
1697 | |
15135
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
1698 // generic call function |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
1699 { |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
1700 jit_type *int_t = intN (sizeof (octave_builtin::fcn) * 8); |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1701 any_call = create_external (JIT_FN (octave_jit_call), any, int_t, int_t, |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1702 any_ptr, int_t); |
15135
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
1703 } |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
1704 |
15016 | 1705 // any with anything is an any op |
1706 jit_function fn; | |
1707 jit_type *binary_op_type = intN (sizeof (octave_value::binary_op) * 8); | |
1708 llvm::Type *llvm_bo_type = binary_op_type->to_llvm (); | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1709 jit_function any_binary = create_external (JIT_FN (octave_jit_binary_any_any), |
15016 | 1710 any, binary_op_type, any, any); |
1711 any_binary.mark_can_error (); | |
1712 binary_ops.resize (octave_value::num_binary_ops); | |
1713 for (size_t i = 0; i < octave_value::num_binary_ops; ++i) | |
1714 { | |
1715 octave_value::binary_op op = static_cast<octave_value::binary_op> (i); | |
1716 std::string op_name = octave_value::binary_op_as_string (op); | |
1717 binary_ops[i].stash_name ("binary" + op_name); | |
1718 } | |
1719 | |
15146
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1720 unary_ops.resize (octave_value::num_unary_ops); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1721 for (size_t i = 0; i < octave_value::num_unary_ops; ++i) |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1722 { |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1723 octave_value::unary_op op = static_cast<octave_value::unary_op> (i); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1724 std::string op_name = octave_value::unary_op_as_string (op); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1725 unary_ops[i].stash_name ("unary" + op_name); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1726 } |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1727 |
15016 | 1728 for (int op = 0; op < octave_value::num_binary_ops; ++op) |
1729 { | |
1730 llvm::Twine fn_name ("octave_jit_binary_any_any_"); | |
1731 fn_name = fn_name + llvm::Twine (op); | |
1732 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1733 fn = create_internal (fn_name, any, any, any); |
15016 | 1734 fn.mark_can_error (); |
1735 llvm::BasicBlock *block = fn.new_block (); | |
1736 builder.SetInsertPoint (block); | |
1737 llvm::APInt op_int(sizeof (octave_value::binary_op) * 8, op, | |
1738 std::numeric_limits<octave_value::binary_op>::is_signed); | |
1739 llvm::Value *op_as_llvm = llvm::ConstantInt::get (llvm_bo_type, op_int); | |
1740 llvm::Value *ret = any_binary.call (builder, op_as_llvm, | |
1741 fn.argument (builder, 0), | |
1742 fn.argument (builder, 1)); | |
1743 fn.do_return (builder, ret); | |
1744 binary_ops[op].add_overload (fn); | |
1745 } | |
1746 | |
1747 // grab matrix | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1748 fn = create_external (JIT_FN (octave_jit_grab_matrix), matrix, matrix); |
15016 | 1749 grab_fn.add_overload (fn); |
1750 | |
15334
8125773322d4
Error on undefined an unused variables in JIT
Max Brister <max@2bass.com>
parents:
15311
diff
changeset
|
1751 grab_fn.add_overload (create_identity (scalar)); |
18554 | 1752 grab_fn.add_overload (create_identity (single)); |
18557 | 1753 grab_fn.add_overload (create_identity (intN (8))); |
18559 | 1754 grab_fn.add_overload (create_identity (intN (16))); |
18560 | 1755 grab_fn.add_overload (create_identity (intN (32))); |
18558
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
1756 grab_fn.add_overload (create_identity (intN (64))); |
18561 | 1757 grab_fn.add_overload (create_identity (uintN (8))); |
18555 | 1758 grab_fn.add_overload (create_identity (uintN (16))); |
15334
8125773322d4
Error on undefined an unused variables in JIT
Max Brister <max@2bass.com>
parents:
15311
diff
changeset
|
1759 grab_fn.add_overload (create_identity (scalar_ptr)); |
8125773322d4
Error on undefined an unused variables in JIT
Max Brister <max@2bass.com>
parents:
15311
diff
changeset
|
1760 grab_fn.add_overload (create_identity (any_ptr)); |
8125773322d4
Error on undefined an unused variables in JIT
Max Brister <max@2bass.com>
parents:
15311
diff
changeset
|
1761 grab_fn.add_overload (create_identity (boolean)); |
8125773322d4
Error on undefined an unused variables in JIT
Max Brister <max@2bass.com>
parents:
15311
diff
changeset
|
1762 grab_fn.add_overload (create_identity (complex)); |
8125773322d4
Error on undefined an unused variables in JIT
Max Brister <max@2bass.com>
parents:
15311
diff
changeset
|
1763 grab_fn.add_overload (create_identity (index)); |
8125773322d4
Error on undefined an unused variables in JIT
Max Brister <max@2bass.com>
parents:
15311
diff
changeset
|
1764 |
15016 | 1765 // release any |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1766 fn = create_external (JIT_FN (octave_jit_release_any), 0, any); |
15016 | 1767 release_fn.add_overload (fn); |
1768 release_fn.stash_name ("release"); | |
1769 | |
1770 // release matrix | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1771 fn = create_external (JIT_FN (octave_jit_release_matrix), 0, matrix); |
15016 | 1772 release_fn.add_overload (fn); |
1773 | |
15337
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
1774 // destroy |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
1775 destroy_fn = release_fn; |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
1776 destroy_fn.stash_name ("destroy"); |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
1777 destroy_fn.add_overload (create_identity(scalar)); |
18554 | 1778 destroy_fn.add_overload (create_identity(single)); |
18557 | 1779 destroy_fn.add_overload (create_identity(intN (8))); |
18559 | 1780 destroy_fn.add_overload (create_identity(intN (16))); |
18560 | 1781 destroy_fn.add_overload (create_identity(intN (32))); |
18558
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
1782 destroy_fn.add_overload (create_identity(intN (64))); |
18561 | 1783 destroy_fn.add_overload (create_identity(uintN (8))); |
18555 | 1784 destroy_fn.add_overload (create_identity(uintN (16))); |
15337
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
1785 destroy_fn.add_overload (create_identity(boolean)); |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
1786 destroy_fn.add_overload (create_identity(index)); |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
1787 destroy_fn.add_overload (create_identity(complex)); |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
1788 |
18323
0122fad27435
jit compiler: Fix uminus op support with scalar type
LYH <lyh.kernel@gmail.com>
parents:
18279
diff
changeset
|
1789 // -------------------- scalar related operations -------------------- |
0122fad27435
jit compiler: Fix uminus op support with scalar type
LYH <lyh.kernel@gmail.com>
parents:
18279
diff
changeset
|
1790 |
15016 | 1791 // now for binary scalar operations |
1792 add_binary_op (scalar, octave_value::op_add, llvm::Instruction::FAdd); | |
1793 add_binary_op (scalar, octave_value::op_sub, llvm::Instruction::FSub); | |
1794 add_binary_op (scalar, octave_value::op_mul, llvm::Instruction::FMul); | |
1795 add_binary_op (scalar, octave_value::op_el_mul, llvm::Instruction::FMul); | |
1796 | |
1797 add_binary_fcmp (scalar, octave_value::op_lt, llvm::CmpInst::FCMP_ULT); | |
1798 add_binary_fcmp (scalar, octave_value::op_le, llvm::CmpInst::FCMP_ULE); | |
1799 add_binary_fcmp (scalar, octave_value::op_eq, llvm::CmpInst::FCMP_UEQ); | |
1800 add_binary_fcmp (scalar, octave_value::op_ge, llvm::CmpInst::FCMP_UGE); | |
1801 add_binary_fcmp (scalar, octave_value::op_gt, llvm::CmpInst::FCMP_UGT); | |
1802 add_binary_fcmp (scalar, octave_value::op_ne, llvm::CmpInst::FCMP_UNE); | |
1803 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1804 jit_function gripe_div0 = create_external (JIT_FN (gripe_divide_by_zero), 0); |
15016 | 1805 gripe_div0.mark_can_error (); |
1806 | |
1807 // divide is annoying because it might error | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1808 fn = create_internal ("octave_jit_div_scalar_scalar", scalar, scalar, scalar); |
15016 | 1809 fn.mark_can_error (); |
1810 | |
1811 llvm::BasicBlock *body = fn.new_block (); | |
1812 builder.SetInsertPoint (body); | |
1813 { | |
1814 llvm::BasicBlock *warn_block = fn.new_block ("warn"); | |
1815 llvm::BasicBlock *normal_block = fn.new_block ("normal"); | |
1816 | |
1817 llvm::Value *zero = llvm::ConstantFP::get (scalar_t, 0); | |
15095
9df70a18aa27
Correct division by zero check in JIT
Max Brister <max@2bass.com>
parents:
15078
diff
changeset
|
1818 llvm::Value *check = builder.CreateFCmpUEQ (zero, fn.argument (builder, 1)); |
15016 | 1819 builder.CreateCondBr (check, warn_block, normal_block); |
1820 | |
1821 builder.SetInsertPoint (warn_block); | |
1822 gripe_div0.call (builder); | |
1823 builder.CreateBr (normal_block); | |
1824 | |
1825 builder.SetInsertPoint (normal_block); | |
1826 llvm::Value *ret = builder.CreateFDiv (fn.argument (builder, 0), | |
1827 fn.argument (builder, 1)); | |
1828 fn.do_return (builder, ret); | |
1829 } | |
1830 binary_ops[octave_value::op_div].add_overload (fn); | |
1831 binary_ops[octave_value::op_el_div].add_overload (fn); | |
1832 | |
1833 // ldiv is the same as div with the operators reversed | |
1834 fn = mirror_binary (fn); | |
1835 binary_ops[octave_value::op_ldiv].add_overload (fn); | |
1836 binary_ops[octave_value::op_el_ldiv].add_overload (fn); | |
1837 | |
1838 // In general, the result of scalar ^ scalar is a complex number. We might be | |
1839 // able to improve on this if we keep track of the range of values varaibles | |
1840 // can take on. | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1841 fn = create_external (JIT_FN (octave_jit_pow_scalar_scalar), complex, scalar, |
15016 | 1842 scalar); |
1843 binary_ops[octave_value::op_pow].add_overload (fn); | |
1844 binary_ops[octave_value::op_el_pow].add_overload (fn); | |
1845 | |
15146
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1846 // now for unary scalar operations |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1847 // FIXME: Impelment not |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1848 fn = create_internal ("octave_jit_++", scalar, scalar); |
15146
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1849 body = fn.new_block (); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1850 builder.SetInsertPoint (body); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1851 { |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1852 llvm::Value *one = llvm::ConstantFP::get (scalar_t, 1); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1853 llvm::Value *val = fn.argument (builder, 0); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1854 val = builder.CreateFAdd (val, one); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1855 fn.do_return (builder, val); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1856 } |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1857 unary_ops[octave_value::op_incr].add_overload (fn); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1858 |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1859 fn = create_internal ("octave_jit_--", scalar, scalar); |
15146
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1860 body = fn.new_block (); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1861 builder.SetInsertPoint (body); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1862 { |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1863 llvm::Value *one = llvm::ConstantFP::get (scalar_t, 1); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1864 llvm::Value *val = fn.argument (builder, 0); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1865 val = builder.CreateFSub (val, one); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1866 fn.do_return (builder, val); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1867 } |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1868 unary_ops[octave_value::op_decr].add_overload (fn); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1869 |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1870 fn = create_internal ("octave_jit_uminus", scalar, scalar); |
15146
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1871 body = fn.new_block (); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1872 builder.SetInsertPoint (body); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1873 { |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1874 llvm::Value *mone = llvm::ConstantFP::get (scalar_t, -1); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1875 llvm::Value *val = fn.argument (builder, 0); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1876 val = builder.CreateFMul (val, mone); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1877 fn.do_return (builder, val); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1878 } |
18323
0122fad27435
jit compiler: Fix uminus op support with scalar type
LYH <lyh.kernel@gmail.com>
parents:
18279
diff
changeset
|
1879 unary_ops[octave_value::op_uminus].add_overload (fn); |
15146
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1880 |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1881 fn = create_identity (scalar); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1882 unary_ops[octave_value::op_uplus].add_overload (fn); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1883 unary_ops[octave_value::op_transpose].add_overload (fn); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1884 unary_ops[octave_value::op_hermitian].add_overload (fn); |
709e8928e68c
Scalar unary operation support in JIT
Max Brister <max@2bass.com>
parents:
15136
diff
changeset
|
1885 |
18554 | 1886 /************************************************************ |
1887 * | |
1888 * complex related operations | |
1889 * | |
1890 ************************************************************/ | |
1891 | |
15016 | 1892 // now for binary complex operations |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1893 fn = create_internal ("octave_jit_+_complex_complex", complex, complex, |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1894 complex); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1895 body = fn.new_block (); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1896 builder.SetInsertPoint (body); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1897 { |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1898 llvm::Value *lhs = fn.argument (builder, 0); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1899 llvm::Value *rhs = fn.argument (builder, 1); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1900 llvm::Value *real = builder.CreateFAdd (complex_real (lhs), |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1901 complex_real (rhs)); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1902 llvm::Value *imag = builder.CreateFAdd (complex_imag (lhs), |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1903 complex_imag (rhs)); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1904 fn.do_return (builder, complex_new (real, imag)); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1905 } |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1906 binary_ops[octave_value::op_add].add_overload (fn); |
15016 | 1907 |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1908 fn = create_internal ("octave_jit_-_complex_complex", complex, complex, |
15016 | 1909 complex); |
1910 body = fn.new_block (); | |
1911 builder.SetInsertPoint (body); | |
1912 { | |
1913 llvm::Value *lhs = fn.argument (builder, 0); | |
1914 llvm::Value *rhs = fn.argument (builder, 1); | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1915 llvm::Value *real = builder.CreateFSub (complex_real (lhs), |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1916 complex_real (rhs)); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1917 llvm::Value *imag = builder.CreateFSub (complex_imag (lhs), |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1918 complex_imag (rhs)); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1919 fn.do_return (builder, complex_new (real, imag)); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1920 } |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1921 binary_ops[octave_value::op_sub].add_overload (fn); |
15016 | 1922 |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1923 fn = create_external (JIT_FN (octave_jit_complex_mul), |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1924 complex, complex, complex); |
15016 | 1925 binary_ops[octave_value::op_mul].add_overload (fn); |
1926 binary_ops[octave_value::op_el_mul].add_overload (fn); | |
1927 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1928 jit_function complex_div = create_external (JIT_FN (octave_jit_complex_div), |
15016 | 1929 complex, complex, complex); |
1930 complex_div.mark_can_error (); | |
1931 binary_ops[octave_value::op_div].add_overload (fn); | |
1932 binary_ops[octave_value::op_ldiv].add_overload (fn); | |
1933 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1934 fn = create_external (JIT_FN (octave_jit_pow_complex_complex), complex, |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
1935 complex, complex); |
15016 | 1936 binary_ops[octave_value::op_pow].add_overload (fn); |
1937 binary_ops[octave_value::op_el_pow].add_overload (fn); | |
1938 | |
18554 | 1939 /************************************************************ |
1940 * | |
1941 * single related operations | |
1942 * | |
1943 ************************************************************/ | |
1944 | |
1945 // now for binary single operations | |
1946 add_binary_op (single, octave_value::op_add, llvm::Instruction::FAdd); | |
1947 add_binary_op (single, octave_value::op_sub, llvm::Instruction::FSub); | |
1948 add_binary_op (single, octave_value::op_mul, llvm::Instruction::FMul); | |
1949 add_binary_op (single, octave_value::op_el_mul, llvm::Instruction::FMul); | |
1950 | |
1951 add_binary_fcmp (single, octave_value::op_lt, llvm::CmpInst::FCMP_ULT); | |
1952 add_binary_fcmp (single, octave_value::op_le, llvm::CmpInst::FCMP_ULE); | |
1953 add_binary_fcmp (single, octave_value::op_eq, llvm::CmpInst::FCMP_UEQ); | |
1954 add_binary_fcmp (single, octave_value::op_ge, llvm::CmpInst::FCMP_UGE); | |
1955 add_binary_fcmp (single, octave_value::op_gt, llvm::CmpInst::FCMP_UGT); | |
1956 add_binary_fcmp (single, octave_value::op_ne, llvm::CmpInst::FCMP_UNE); | |
1957 | |
1958 // divide is annoying because it might error | |
1959 fn = create_internal ("octave_jit_div_single_single", single, single, single); | |
1960 fn.mark_can_error (); | |
1961 | |
1962 body = fn.new_block (); | |
1963 builder.SetInsertPoint (body); | |
1964 { | |
1965 llvm::BasicBlock *warn_block = fn.new_block ("warn"); | |
1966 llvm::BasicBlock *normal_block = fn.new_block ("normal"); | |
1967 | |
1968 llvm::Value *zero = llvm::ConstantFP::get (single_t, 0); | |
1969 llvm::Value *check = builder.CreateFCmpUEQ (zero, fn.argument (builder, 1)); | |
1970 builder.CreateCondBr (check, warn_block, normal_block); | |
1971 | |
1972 builder.SetInsertPoint (warn_block); | |
1973 gripe_div0.call (builder); | |
1974 builder.CreateBr (normal_block); | |
1975 | |
1976 builder.SetInsertPoint (normal_block); | |
1977 llvm::Value *ret = builder.CreateFDiv (fn.argument (builder, 0), | |
1978 fn.argument (builder, 1)); | |
1979 fn.do_return (builder, ret); | |
1980 } | |
1981 binary_ops[octave_value::op_div].add_overload (fn); | |
1982 binary_ops[octave_value::op_el_div].add_overload (fn); | |
1983 | |
1984 // ldiv is the same as div with the operators reversed | |
1985 fn = mirror_binary (fn); | |
1986 binary_ops[octave_value::op_ldiv].add_overload (fn); | |
1987 binary_ops[octave_value::op_el_ldiv].add_overload (fn); | |
1988 | |
1989 // In general, the result of scalar ^ scalar is a complex number. We might be | |
1990 // able to improve on this if we keep track of the range of values varaibles | |
1991 // can take on. | |
1992 fn = create_external (JIT_FN (octave_jit_pow_single_single), complex, single, | |
1993 single); | |
1994 binary_ops[octave_value::op_pow].add_overload (fn); | |
1995 binary_ops[octave_value::op_el_pow].add_overload (fn); | |
1996 | |
1997 // now for unary single operations | |
1998 // FIXME: Impelment not | |
1999 fn = create_internal ("octave_jit_++", single, single); | |
2000 body = fn.new_block (); | |
2001 builder.SetInsertPoint (body); | |
2002 { | |
2003 llvm::Value *one = llvm::ConstantFP::get (single_t, 1); | |
2004 llvm::Value *val = fn.argument (builder, 0); | |
2005 val = builder.CreateFAdd (val, one); | |
2006 fn.do_return (builder, val); | |
2007 } | |
2008 unary_ops[octave_value::op_incr].add_overload (fn); | |
2009 | |
2010 fn = create_internal ("octave_jit_--", single, single); | |
2011 body = fn.new_block (); | |
2012 builder.SetInsertPoint (body); | |
2013 { | |
2014 llvm::Value *one = llvm::ConstantFP::get (single_t, 1); | |
2015 llvm::Value *val = fn.argument (builder, 0); | |
2016 val = builder.CreateFSub (val, one); | |
2017 fn.do_return (builder, val); | |
2018 } | |
2019 unary_ops[octave_value::op_decr].add_overload (fn); | |
2020 | |
2021 fn = create_internal ("octave_jit_uminus", single, single); | |
2022 body = fn.new_block (); | |
2023 builder.SetInsertPoint (body); | |
2024 { | |
2025 llvm::Value *mone = llvm::ConstantFP::get (single_t, -1); | |
2026 llvm::Value *val = fn.argument (builder, 0); | |
2027 val = builder.CreateFMul (val, mone); | |
2028 fn.do_return (builder, val); | |
2029 } | |
2030 unary_ops[octave_value::op_uminus].add_overload (fn); | |
2031 | |
2032 fn = create_identity (single); | |
2033 unary_ops[octave_value::op_uplus].add_overload (fn); | |
2034 unary_ops[octave_value::op_transpose].add_overload (fn); | |
2035 unary_ops[octave_value::op_hermitian].add_overload (fn); | |
2036 | |
18555 | 2037 /************************************************************ |
2038 * | |
18557 | 2039 * int8 related operations |
2040 * | |
2041 ************************************************************/ | |
2042 | |
2043 // now for binary int8 operations | |
2044 fn = create_external (JIT_FN (octave_jit_add_int8_int8), intN (8), intN (8), | |
2045 intN (8)); | |
2046 binary_ops[octave_value::op_add].add_overload (fn); | |
2047 fn = create_external (JIT_FN (octave_jit_sub_int8_int8), intN (8), intN (8), | |
2048 intN (8)); | |
2049 binary_ops[octave_value::op_sub].add_overload (fn); | |
2050 fn = create_external (JIT_FN (octave_jit_mul_int8_int8), intN (8), intN (8), | |
2051 intN (8)); | |
2052 binary_ops[octave_value::op_mul].add_overload (fn); | |
2053 binary_ops[octave_value::op_el_mul].add_overload (fn); | |
2054 | |
2055 add_binary_icmp (intN (8), octave_value::op_lt, llvm::CmpInst::ICMP_SLT); | |
2056 add_binary_icmp (intN (8), octave_value::op_le, llvm::CmpInst::ICMP_SLE); | |
2057 add_binary_icmp (intN (8), octave_value::op_eq, llvm::CmpInst::ICMP_EQ); | |
2058 add_binary_icmp (intN (8), octave_value::op_ge, llvm::CmpInst::ICMP_SGE); | |
2059 add_binary_icmp (intN (8), octave_value::op_gt, llvm::CmpInst::ICMP_SGT); | |
2060 add_binary_icmp (intN (8), octave_value::op_ne, llvm::CmpInst::ICMP_NE); | |
2061 | |
2062 // FIXME: saturation divide definition? interpreter convert int to double, calculate and round. | |
2063 // divide is annoying because it might error | |
2064 // FIXME: Implement div | |
2065 | |
2066 // FIXME: Implement pow | |
2067 | |
2068 // now for unary int8 operations | |
2069 // FIXME: Impelment not | |
2070 fn = create_external (JIT_FN (octave_jit_incr_int8), intN (8), intN (8)); | |
2071 unary_ops[octave_value::op_incr].add_overload (fn); | |
2072 | |
2073 fn = create_external (JIT_FN (octave_jit_decr_int8), intN (8), intN (8)); | |
2074 unary_ops[octave_value::op_decr].add_overload (fn); | |
2075 | |
2076 fn = create_internal ("octave_jit_uminus", intN (8), intN (8)); | |
2077 body = fn.new_block (); | |
2078 builder.SetInsertPoint (body); | |
2079 { | |
2080 llvm::Value *mone = llvm::ConstantInt::get (int8__t, -1); | |
2081 llvm::Value *val = fn.argument (builder, 0); | |
2082 val = builder.CreateMul (val, mone); | |
2083 fn.do_return (builder, val); | |
2084 } | |
2085 unary_ops[octave_value::op_uminus].add_overload (fn); | |
2086 | |
2087 fn = create_identity (intN (8)); | |
2088 unary_ops[octave_value::op_uplus].add_overload (fn); | |
2089 unary_ops[octave_value::op_transpose].add_overload (fn); | |
2090 unary_ops[octave_value::op_hermitian].add_overload (fn); | |
2091 | |
2092 /************************************************************ | |
2093 * | |
18559 | 2094 * int16 related operations |
2095 * | |
2096 ************************************************************/ | |
2097 | |
2098 // now for binary int16 operations | |
2099 fn = create_external (JIT_FN (octave_jit_add_int16_int16), intN (16), intN (16), | |
2100 intN (16)); | |
2101 binary_ops[octave_value::op_add].add_overload (fn); | |
2102 fn = create_external (JIT_FN (octave_jit_sub_int16_int16), intN (16), intN (16), | |
2103 intN (16)); | |
2104 binary_ops[octave_value::op_sub].add_overload (fn); | |
2105 fn = create_external (JIT_FN (octave_jit_mul_int16_int16), intN (16), intN (16), | |
2106 intN (16)); | |
2107 binary_ops[octave_value::op_mul].add_overload (fn); | |
2108 binary_ops[octave_value::op_el_mul].add_overload (fn); | |
2109 | |
2110 add_binary_icmp (intN (16), octave_value::op_lt, llvm::CmpInst::ICMP_SLT); | |
2111 add_binary_icmp (intN (16), octave_value::op_le, llvm::CmpInst::ICMP_SLE); | |
2112 add_binary_icmp (intN (16), octave_value::op_eq, llvm::CmpInst::ICMP_EQ); | |
2113 add_binary_icmp (intN (16), octave_value::op_ge, llvm::CmpInst::ICMP_SGE); | |
2114 add_binary_icmp (intN (16), octave_value::op_gt, llvm::CmpInst::ICMP_SGT); | |
2115 add_binary_icmp (intN (16), octave_value::op_ne, llvm::CmpInst::ICMP_NE); | |
2116 | |
2117 // FIXME: saturation divide definition? interpreter convert int to double, calculate and round. | |
2118 // divide is annoying because it might error | |
2119 // FIXME: Implement div | |
2120 | |
2121 // FIXME: Implement pow | |
2122 | |
2123 // now for unary int16 operations | |
2124 // FIXME: Impelment not | |
2125 fn = create_external (JIT_FN (octave_jit_incr_int16), intN (16), intN (16)); | |
2126 unary_ops[octave_value::op_incr].add_overload (fn); | |
2127 | |
2128 fn = create_external (JIT_FN (octave_jit_decr_int16), intN (16), intN (16)); | |
2129 unary_ops[octave_value::op_decr].add_overload (fn); | |
2130 | |
2131 fn = create_internal ("octave_jit_uminus", intN (16), intN (16)); | |
2132 body = fn.new_block (); | |
2133 builder.SetInsertPoint (body); | |
2134 { | |
2135 llvm::Value *mone = llvm::ConstantInt::get (int16__t, -1); | |
2136 llvm::Value *val = fn.argument (builder, 0); | |
2137 val = builder.CreateMul (val, mone); | |
2138 fn.do_return (builder, val); | |
2139 } | |
2140 unary_ops[octave_value::op_uminus].add_overload (fn); | |
2141 | |
2142 fn = create_identity (intN (16)); | |
2143 unary_ops[octave_value::op_uplus].add_overload (fn); | |
2144 unary_ops[octave_value::op_transpose].add_overload (fn); | |
2145 unary_ops[octave_value::op_hermitian].add_overload (fn); | |
2146 | |
2147 /************************************************************ | |
2148 * | |
18560 | 2149 * int32 related operations |
2150 * | |
2151 ************************************************************/ | |
2152 | |
2153 // FIXME: interpreter overflow occurs at minus + minus, minus - plus | |
2154 // now for binary int32 operations | |
2155 fn = create_external (JIT_FN (octave_jit_add_int32_int32), intN (32), intN (32), | |
2156 intN (32)); | |
2157 binary_ops[octave_value::op_add].add_overload (fn); | |
2158 fn = create_external (JIT_FN (octave_jit_sub_int32_int32), intN (32), intN (32), | |
2159 intN (32)); | |
2160 binary_ops[octave_value::op_sub].add_overload (fn); | |
2161 fn = create_external (JIT_FN (octave_jit_mul_int32_int32), intN (32), intN (32), | |
2162 intN (32)); | |
2163 binary_ops[octave_value::op_mul].add_overload (fn); | |
2164 binary_ops[octave_value::op_el_mul].add_overload (fn); | |
2165 | |
2166 add_binary_icmp (intN (32), octave_value::op_lt, llvm::CmpInst::ICMP_SLT); | |
2167 add_binary_icmp (intN (32), octave_value::op_le, llvm::CmpInst::ICMP_SLE); | |
2168 add_binary_icmp (intN (32), octave_value::op_eq, llvm::CmpInst::ICMP_EQ); | |
2169 add_binary_icmp (intN (32), octave_value::op_ge, llvm::CmpInst::ICMP_SGE); | |
2170 add_binary_icmp (intN (32), octave_value::op_gt, llvm::CmpInst::ICMP_SGT); | |
2171 add_binary_icmp (intN (32), octave_value::op_ne, llvm::CmpInst::ICMP_NE); | |
2172 | |
2173 // FIXME: saturation divide definition? interpreter convert int to double, calculate and round. | |
2174 // divide is annoying because it might error | |
2175 // FIXME: Implement div | |
2176 | |
2177 // FIXME: Implement pow | |
2178 | |
2179 // now for unary int32 operations | |
2180 // FIXME: Impelment not | |
2181 fn = create_external (JIT_FN (octave_jit_incr_int32), intN (32), intN (32)); | |
2182 unary_ops[octave_value::op_incr].add_overload (fn); | |
2183 | |
2184 fn = create_external (JIT_FN (octave_jit_decr_int32), intN (32), intN (32)); | |
2185 unary_ops[octave_value::op_decr].add_overload (fn); | |
2186 | |
2187 fn = create_internal ("octave_jit_uminus", intN (32), intN (32)); | |
2188 body = fn.new_block (); | |
2189 builder.SetInsertPoint (body); | |
2190 { | |
2191 llvm::Value *mone = llvm::ConstantInt::get (int32__t, -1); | |
2192 llvm::Value *val = fn.argument (builder, 0); | |
2193 val = builder.CreateMul (val, mone); | |
2194 fn.do_return (builder, val); | |
2195 } | |
2196 unary_ops[octave_value::op_uminus].add_overload (fn); | |
2197 | |
2198 fn = create_identity (intN (32)); | |
2199 unary_ops[octave_value::op_uplus].add_overload (fn); | |
2200 unary_ops[octave_value::op_transpose].add_overload (fn); | |
2201 unary_ops[octave_value::op_hermitian].add_overload (fn); | |
2202 | |
2203 /************************************************************ | |
2204 * | |
18558
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2205 * int64 related operations |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2206 * |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2207 ************************************************************/ |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2208 |
18559 | 2209 // FIXME: interpreter overflow occurs at minus + minus, minus - plus |
18558
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2210 // now for binary int64 operations |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2211 fn = create_external (JIT_FN (octave_jit_add_int64_int64), intN (64), intN (64), |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2212 intN (64)); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2213 binary_ops[octave_value::op_add].add_overload (fn); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2214 fn = create_external (JIT_FN (octave_jit_sub_int64_int64), intN (64), intN (64), |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2215 intN (64)); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2216 binary_ops[octave_value::op_sub].add_overload (fn); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2217 fn = create_external (JIT_FN (octave_jit_mul_int64_int64), intN (64), intN (64), |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2218 intN (64)); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2219 binary_ops[octave_value::op_mul].add_overload (fn); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2220 binary_ops[octave_value::op_el_mul].add_overload (fn); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2221 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2222 add_binary_icmp (intN (64), octave_value::op_lt, llvm::CmpInst::ICMP_SLT); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2223 add_binary_icmp (intN (64), octave_value::op_le, llvm::CmpInst::ICMP_SLE); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2224 add_binary_icmp (intN (64), octave_value::op_eq, llvm::CmpInst::ICMP_EQ); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2225 add_binary_icmp (intN (64), octave_value::op_ge, llvm::CmpInst::ICMP_SGE); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2226 add_binary_icmp (intN (64), octave_value::op_gt, llvm::CmpInst::ICMP_SGT); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2227 add_binary_icmp (intN (64), octave_value::op_ne, llvm::CmpInst::ICMP_NE); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2228 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2229 // FIXME: saturation divide definition? interpreter convert int to double, calculate and round. |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2230 // divide is annoying because it might error |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2231 // FIXME: Implement div |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2232 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2233 // FIXME: Implement pow |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2234 |
18559 | 2235 // now for unary int64 operations |
18558
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2236 // FIXME: Impelment not |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2237 fn = create_external (JIT_FN (octave_jit_incr_int64), intN (64), intN (64)); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2238 unary_ops[octave_value::op_incr].add_overload (fn); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2239 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2240 fn = create_external (JIT_FN (octave_jit_decr_int64), intN (64), intN (64)); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2241 unary_ops[octave_value::op_decr].add_overload (fn); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2242 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2243 fn = create_internal ("octave_jit_uminus", intN (64), intN (64)); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2244 body = fn.new_block (); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2245 builder.SetInsertPoint (body); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2246 { |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2247 llvm::Value *mone = llvm::ConstantInt::get (int64__t, -1); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2248 llvm::Value *val = fn.argument (builder, 0); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2249 val = builder.CreateMul (val, mone); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2250 fn.do_return (builder, val); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2251 } |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2252 unary_ops[octave_value::op_uminus].add_overload (fn); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2253 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2254 fn = create_identity (intN (64)); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2255 unary_ops[octave_value::op_uplus].add_overload (fn); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2256 unary_ops[octave_value::op_transpose].add_overload (fn); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2257 unary_ops[octave_value::op_hermitian].add_overload (fn); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2258 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2259 /************************************************************ |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2260 * |
18561 | 2261 * uint8 related operations |
2262 * | |
2263 ************************************************************/ | |
2264 | |
2265 // now for binary uint8 operations | |
2266 fn = create_external (JIT_FN (octave_jit_add_uint8_uint8), uintN (8), uintN (8), | |
2267 uintN (8)); | |
2268 binary_ops[octave_value::op_add].add_overload (fn); | |
2269 fn = create_external (JIT_FN (octave_jit_sub_uint8_uint8), uintN (8), uintN (8), | |
2270 uintN (8)); | |
2271 binary_ops[octave_value::op_sub].add_overload (fn); | |
2272 fn = create_external (JIT_FN (octave_jit_mul_uint8_uint8), uintN (8), uintN (8), | |
2273 uintN (8)); | |
2274 binary_ops[octave_value::op_mul].add_overload (fn); | |
2275 binary_ops[octave_value::op_el_mul].add_overload (fn); | |
2276 | |
2277 add_binary_icmp (uintN (8), octave_value::op_lt, llvm::CmpInst::ICMP_ULT); | |
2278 add_binary_icmp (uintN (8), octave_value::op_le, llvm::CmpInst::ICMP_ULE); | |
2279 add_binary_icmp (uintN (8), octave_value::op_eq, llvm::CmpInst::ICMP_EQ); | |
2280 add_binary_icmp (uintN (8), octave_value::op_ge, llvm::CmpInst::ICMP_UGE); | |
2281 add_binary_icmp (uintN (8), octave_value::op_gt, llvm::CmpInst::ICMP_UGT); | |
2282 add_binary_icmp (uintN (8), octave_value::op_ne, llvm::CmpInst::ICMP_NE); | |
2283 | |
2284 // FIXME: saturation divide definition? interpreter convert uint to double, calculate and round. | |
2285 // divide is annoying because it might error | |
2286 // FIXME: Implement div | |
2287 | |
2288 // FIXME: Implement pow | |
2289 | |
2290 // now for unary uint8 operations | |
2291 // FIXME: Impelment not | |
2292 fn = create_external (JIT_FN (octave_jit_incr_uint8), uintN (8), uintN (8)); | |
2293 unary_ops[octave_value::op_incr].add_overload (fn); | |
2294 | |
2295 fn = create_external (JIT_FN (octave_jit_decr_uint8), uintN (8), uintN (8)); | |
2296 unary_ops[octave_value::op_decr].add_overload (fn); | |
2297 | |
2298 fn = create_internal ("octave_jit_uminus", uintN (8), uintN (8)); | |
2299 body = fn.new_block (); | |
2300 builder.SetInsertPoint (body); | |
2301 { | |
2302 llvm::Value *zero = llvm::ConstantInt::get (uint8__t, 0); | |
2303 | |
2304 fn.do_return (builder, zero); | |
2305 } | |
2306 unary_ops[octave_value::op_uminus].add_overload (fn); | |
2307 | |
2308 fn = create_identity (uintN (8)); | |
2309 unary_ops[octave_value::op_uplus].add_overload (fn); | |
2310 unary_ops[octave_value::op_transpose].add_overload (fn); | |
2311 unary_ops[octave_value::op_hermitian].add_overload (fn); | |
2312 | |
2313 /************************************************************ | |
2314 * | |
18555 | 2315 * uint16 related operations |
2316 * | |
2317 ************************************************************/ | |
2318 | |
2319 // now for binary uint16 operations | |
2320 fn = create_external (JIT_FN (octave_jit_add_uint16_uint16), uintN (16), uintN (16), | |
2321 uintN (16)); | |
2322 binary_ops[octave_value::op_add].add_overload (fn); | |
2323 fn = create_external (JIT_FN (octave_jit_sub_uint16_uint16), uintN (16), uintN (16), | |
2324 uintN (16)); | |
2325 binary_ops[octave_value::op_sub].add_overload (fn); | |
2326 fn = create_external (JIT_FN (octave_jit_mul_uint16_uint16), uintN (16), uintN (16), | |
2327 uintN (16)); | |
2328 binary_ops[octave_value::op_mul].add_overload (fn); | |
2329 binary_ops[octave_value::op_el_mul].add_overload (fn); | |
2330 | |
2331 add_binary_icmp (uintN (16), octave_value::op_lt, llvm::CmpInst::ICMP_ULT); | |
2332 add_binary_icmp (uintN (16), octave_value::op_le, llvm::CmpInst::ICMP_ULE); | |
2333 add_binary_icmp (uintN (16), octave_value::op_eq, llvm::CmpInst::ICMP_EQ); | |
2334 add_binary_icmp (uintN (16), octave_value::op_ge, llvm::CmpInst::ICMP_UGE); | |
2335 add_binary_icmp (uintN (16), octave_value::op_gt, llvm::CmpInst::ICMP_UGT); | |
2336 add_binary_icmp (uintN (16), octave_value::op_ne, llvm::CmpInst::ICMP_NE); | |
2337 | |
2338 // FIXME: saturation divide definition? interpreter convert uint to double, calculate and round. | |
2339 // divide is annoying because it might error | |
2340 #if 0 | |
2341 fn = create_internal ("octave_jit_div_uint16_uint16", uintN (16), uintN (16), uintN (16)); | |
2342 fn.mark_can_error (); | |
2343 | |
2344 body = fn.new_block (); | |
2345 builder.SetInsertPoint (body); | |
2346 { | |
2347 llvm::BasicBlock *warn_block = fn.new_block ("warn"); | |
2348 llvm::BasicBlock *normal_block = fn.new_block ("normal"); | |
2349 | |
2350 llvm::Value *zero = llvm::ConstantInt::get (uint16__t, 0); | |
2351 llvm::Value *check = builder.CreateICmpEQ (zero, fn.argument (builder, 1)); | |
2352 builder.CreateCondBr (check, warn_block, normal_block); | |
2353 | |
2354 builder.SetInsertPoint (warn_block); | |
2355 gripe_div0.call (builder); | |
2356 builder.CreateBr (normal_block); | |
2357 | |
2358 builder.SetInsertPoint (normal_block); | |
2359 llvm::Value *ret = builder.CreateUDiv (fn.argument (builder, 0), | |
2360 fn.argument (builder, 1)); | |
2361 fn.do_return (builder, ret); | |
2362 } | |
2363 binary_ops[octave_value::op_div].add_overload (fn); | |
2364 binary_ops[octave_value::op_el_div].add_overload (fn); | |
2365 | |
2366 // ldiv is the same as div with the operators reversed | |
2367 fn = mirror_binary (fn); | |
2368 binary_ops[octave_value::op_ldiv].add_overload (fn); | |
2369 binary_ops[octave_value::op_el_ldiv].add_overload (fn); | |
2370 #endif | |
2371 | |
2372 // FIXME: Implement pow | |
2373 | |
2374 // now for unary uint16 operations | |
2375 // FIXME: Impelment not | |
2376 fn = create_external (JIT_FN (octave_jit_incr_uint16), uintN (16), uintN (16)); | |
2377 unary_ops[octave_value::op_incr].add_overload (fn); | |
2378 | |
2379 fn = create_external (JIT_FN (octave_jit_decr_uint16), uintN (16), uintN (16)); | |
2380 unary_ops[octave_value::op_decr].add_overload (fn); | |
2381 | |
2382 fn = create_internal ("octave_jit_uminus", uintN (16), uintN (16)); | |
2383 body = fn.new_block (); | |
2384 builder.SetInsertPoint (body); | |
2385 { | |
2386 llvm::Value *zero = llvm::ConstantInt::get (uint16__t, 0); | |
2387 | |
2388 fn.do_return (builder, zero); | |
2389 } | |
2390 unary_ops[octave_value::op_uminus].add_overload (fn); | |
2391 | |
2392 fn = create_identity (uintN (16)); | |
2393 unary_ops[octave_value::op_uplus].add_overload (fn); | |
2394 unary_ops[octave_value::op_transpose].add_overload (fn); | |
2395 unary_ops[octave_value::op_hermitian].add_overload (fn); | |
2396 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2397 fn = create_internal ("octave_jit_*_scalar_complex", complex, scalar, |
15016 | 2398 complex); |
2399 jit_function mul_scalar_complex = fn; | |
2400 body = fn.new_block (); | |
2401 builder.SetInsertPoint (body); | |
2402 { | |
15583
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2403 llvm::BasicBlock *complex_mul = fn.new_block ("complex_mul"); |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2404 llvm::BasicBlock *scalar_mul = fn.new_block ("scalar_mul"); |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2405 |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2406 llvm::Value *fzero = llvm::ConstantFP::get (scalar_t, 0); |
15016 | 2407 llvm::Value *lhs = fn.argument (builder, 0); |
2408 llvm::Value *rhs = fn.argument (builder, 1); | |
15583
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2409 |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2410 llvm::Value *cmp = builder.CreateFCmpUEQ (complex_imag (rhs), fzero); |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2411 builder.CreateCondBr (cmp, scalar_mul, complex_mul); |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2412 |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2413 builder.SetInsertPoint (scalar_mul); |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2414 llvm::Value *temp = complex_real (rhs); |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2415 temp = builder.CreateFMul (lhs, temp); |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2416 fn.do_return (builder, complex_new (temp, fzero), false); |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2417 |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2418 |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
2419 builder.SetInsertPoint (complex_mul); |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2420 temp = complex_new (builder.CreateFMul (lhs, complex_real (rhs)), |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2421 builder.CreateFMul (lhs, complex_imag (rhs))); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2422 fn.do_return (builder, temp); |
15016 | 2423 } |
2424 binary_ops[octave_value::op_mul].add_overload (fn); | |
2425 binary_ops[octave_value::op_el_mul].add_overload (fn); | |
2426 | |
2427 | |
2428 fn = mirror_binary (mul_scalar_complex); | |
2429 binary_ops[octave_value::op_mul].add_overload (fn); | |
2430 binary_ops[octave_value::op_el_mul].add_overload (fn); | |
2431 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2432 fn = create_internal ("octave_jit_+_scalar_complex", complex, scalar, |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2433 complex); |
15016 | 2434 body = fn.new_block (); |
2435 builder.SetInsertPoint (body); | |
2436 { | |
2437 llvm::Value *lhs = fn.argument (builder, 0); | |
2438 llvm::Value *rhs = fn.argument (builder, 1); | |
2439 llvm::Value *real = builder.CreateFAdd (lhs, complex_real (rhs)); | |
2440 fn.do_return (builder, complex_real (rhs, real)); | |
2441 } | |
2442 binary_ops[octave_value::op_add].add_overload (fn); | |
2443 | |
2444 fn = mirror_binary (fn); | |
2445 binary_ops[octave_value::op_add].add_overload (fn); | |
2446 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2447 fn = create_internal ("octave_jit_-_complex_scalar", complex, complex, |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2448 scalar); |
15016 | 2449 body = fn.new_block (); |
2450 builder.SetInsertPoint (body); | |
2451 { | |
2452 llvm::Value *lhs = fn.argument (builder, 0); | |
2453 llvm::Value *rhs = fn.argument (builder, 1); | |
2454 llvm::Value *real = builder.CreateFSub (complex_real (lhs), rhs); | |
2455 fn.do_return (builder, complex_real (lhs, real)); | |
2456 } | |
2457 binary_ops[octave_value::op_sub].add_overload (fn); | |
2458 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2459 fn = create_internal ("octave_jit_-_scalar_complex", complex, scalar, |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2460 complex); |
15016 | 2461 body = fn.new_block (); |
2462 builder.SetInsertPoint (body); | |
2463 { | |
2464 llvm::Value *lhs = fn.argument (builder, 0); | |
2465 llvm::Value *rhs = fn.argument (builder, 1); | |
2466 llvm::Value *real = builder.CreateFSub (lhs, complex_real (rhs)); | |
2467 fn.do_return (builder, complex_real (rhs, real)); | |
2468 } | |
2469 binary_ops[octave_value::op_sub].add_overload (fn); | |
2470 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2471 fn = create_external (JIT_FN (octave_jit_pow_scalar_complex), complex, scalar, |
15016 | 2472 complex); |
2473 binary_ops[octave_value::op_pow].add_overload (fn); | |
2474 binary_ops[octave_value::op_el_pow].add_overload (fn); | |
2475 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2476 fn = create_external (JIT_FN (octave_jit_pow_complex_scalar), complex, |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2477 complex, scalar); |
15016 | 2478 binary_ops[octave_value::op_pow].add_overload (fn); |
2479 binary_ops[octave_value::op_el_pow].add_overload (fn); | |
2480 | |
2481 // now for binary index operators | |
2482 add_binary_op (index, octave_value::op_add, llvm::Instruction::Add); | |
2483 | |
2484 // and binary bool operators | |
2485 add_binary_op (boolean, octave_value::op_el_or, llvm::Instruction::Or); | |
2486 add_binary_op (boolean, octave_value::op_el_and, llvm::Instruction::And); | |
2487 | |
2488 // now for printing functions | |
2489 print_fn.stash_name ("print"); | |
15019
ae3670d4df29
Update the execution engine's global mapping for external functions
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
2490 add_print (any, reinterpret_cast<void *> (&octave_jit_print_any)); |
ae3670d4df29
Update the execution engine's global mapping for external functions
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
2491 add_print (scalar, reinterpret_cast<void *> (&octave_jit_print_scalar)); |
15016 | 2492 |
2493 // initialize for loop | |
2494 for_init_fn.stash_name ("for_init"); | |
2495 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2496 fn = create_internal ("octave_jit_for_range_init", index, range); |
15016 | 2497 body = fn.new_block (); |
2498 builder.SetInsertPoint (body); | |
2499 { | |
2500 llvm::Value *zero = llvm::ConstantInt::get (index_t, 0); | |
2501 fn.do_return (builder, zero); | |
2502 } | |
2503 for_init_fn.add_overload (fn); | |
2504 | |
2505 // bounds check for for loop | |
2506 for_check_fn.stash_name ("for_check"); | |
2507 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2508 fn = create_internal ("octave_jit_for_range_check", boolean, range, index); |
15016 | 2509 body = fn.new_block (); |
2510 builder.SetInsertPoint (body); | |
2511 { | |
2512 llvm::Value *nelem | |
2513 = builder.CreateExtractValue (fn.argument (builder, 0), 3); | |
2514 llvm::Value *idx = fn.argument (builder, 1); | |
2515 llvm::Value *ret = builder.CreateICmpULT (idx, nelem); | |
2516 fn.do_return (builder, ret); | |
2517 } | |
2518 for_check_fn.add_overload (fn); | |
2519 | |
2520 // index variabe for for loop | |
2521 for_index_fn.stash_name ("for_index"); | |
2522 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2523 fn = create_internal ("octave_jit_for_range_idx", scalar, range, index); |
15016 | 2524 body = fn.new_block (); |
2525 builder.SetInsertPoint (body); | |
2526 { | |
2527 llvm::Value *idx = fn.argument (builder, 1); | |
2528 llvm::Value *didx = builder.CreateSIToFP (idx, scalar_t); | |
2529 llvm::Value *rng = fn.argument (builder, 0); | |
2530 llvm::Value *base = builder.CreateExtractValue (rng, 0); | |
2531 llvm::Value *inc = builder.CreateExtractValue (rng, 2); | |
2532 | |
2533 llvm::Value *ret = builder.CreateFMul (didx, inc); | |
2534 ret = builder.CreateFAdd (base, ret); | |
2535 fn.do_return (builder, ret); | |
2536 } | |
2537 for_index_fn.add_overload (fn); | |
2538 | |
2539 // logically true | |
2540 logically_true_fn.stash_name ("logically_true"); | |
2541 | |
2542 jit_function gripe_nantl | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2543 = create_external (JIT_FN (octave_jit_gripe_nan_to_logical_conversion), 0); |
15016 | 2544 gripe_nantl.mark_can_error (); |
2545 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2546 fn = create_internal ("octave_jit_logically_true_scalar", boolean, scalar); |
15016 | 2547 fn.mark_can_error (); |
2548 | |
2549 body = fn.new_block (); | |
2550 builder.SetInsertPoint (body); | |
2551 { | |
2552 llvm::BasicBlock *error_block = fn.new_block ("error"); | |
2553 llvm::BasicBlock *normal_block = fn.new_block ("normal"); | |
2554 | |
2555 llvm::Value *check = builder.CreateFCmpUNE (fn.argument (builder, 0), | |
2556 fn.argument (builder, 0)); | |
2557 builder.CreateCondBr (check, error_block, normal_block); | |
2558 | |
2559 builder.SetInsertPoint (error_block); | |
2560 gripe_nantl.call (builder); | |
2561 builder.CreateBr (normal_block); | |
2562 builder.SetInsertPoint (normal_block); | |
2563 | |
2564 llvm::Value *zero = llvm::ConstantFP::get (scalar_t, 0); | |
2565 llvm::Value *ret = builder.CreateFCmpONE (fn.argument (builder, 0), zero); | |
2566 fn.do_return (builder, ret); | |
2567 } | |
2568 logically_true_fn.add_overload (fn); | |
2569 | |
2570 // logically_true boolean | |
2571 fn = create_identity (boolean); | |
2572 logically_true_fn.add_overload (fn); | |
2573 | |
2574 // make_range | |
2575 // FIXME: May be benificial to implement all in LLVM | |
2576 make_range_fn.stash_name ("make_range"); | |
2577 jit_function compute_nelem | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2578 = create_external (JIT_FN (octave_jit_compute_nelem), |
15016 | 2579 index, scalar, scalar, scalar); |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2580 |
15016 | 2581 |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2582 fn = create_internal ("octave_jit_make_range", range, scalar, scalar, scalar); |
15016 | 2583 body = fn.new_block (); |
2584 builder.SetInsertPoint (body); | |
2585 { | |
2586 llvm::Value *base = fn.argument (builder, 0); | |
2587 llvm::Value *limit = fn.argument (builder, 1); | |
2588 llvm::Value *inc = fn.argument (builder, 2); | |
2589 llvm::Value *nelem = compute_nelem.call (builder, base, limit, inc); | |
2590 | |
2591 llvm::Value *dzero = llvm::ConstantFP::get (scalar_t, 0); | |
2592 llvm::Value *izero = llvm::ConstantInt::get (index_t, 0); | |
2593 llvm::Value *rng = llvm::ConstantStruct::get (range_t, dzero, dzero, dzero, | |
2594 izero, NULL); | |
2595 rng = builder.CreateInsertValue (rng, base, 0); | |
2596 rng = builder.CreateInsertValue (rng, limit, 1); | |
2597 rng = builder.CreateInsertValue (rng, inc, 2); | |
2598 rng = builder.CreateInsertValue (rng, nelem, 3); | |
2599 fn.do_return (builder, rng); | |
2600 } | |
2601 make_range_fn.add_overload (fn); | |
2602 | |
2603 // paren_subsref | |
2604 jit_type *jit_int = intN (sizeof (int) * 8); | |
2605 llvm::Type *int_t = jit_int->to_llvm (); | |
2606 jit_function ginvalid_index | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2607 = create_external (JIT_FN (octave_jit_ginvalid_index), 0); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2608 jit_function gindex_range = create_external (JIT_FN (octave_jit_gindex_range), |
15016 | 2609 0, jit_int, jit_int, index, |
2610 index); | |
2611 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2612 fn = create_internal ("()subsref", scalar, matrix, scalar); |
15016 | 2613 fn.mark_can_error (); |
2614 | |
2615 body = fn.new_block (); | |
2616 builder.SetInsertPoint (body); | |
2617 { | |
18274
e243b705a726
Fix building JIT with 64-bit indexing (bug #41163).
Lasse Schuirmann <lasse@schuirmann.net>
parents:
17787
diff
changeset
|
2618 llvm::Value *one_idx = llvm::ConstantInt::get (index_t, 1); |
e243b705a726
Fix building JIT with 64-bit indexing (bug #41163).
Lasse Schuirmann <lasse@schuirmann.net>
parents:
17787
diff
changeset
|
2619 llvm::Value *one_int = llvm::ConstantInt::get (int_t, 1); |
15016 | 2620 |
2621 llvm::Value *undef = llvm::UndefValue::get (scalar_t); | |
2622 llvm::Value *mat = fn.argument (builder, 0); | |
2623 llvm::Value *idx = fn.argument (builder, 1); | |
2624 | |
2625 // convert index to scalar to integer, and check index >= 1 | |
2626 llvm::Value *int_idx = builder.CreateFPToSI (idx, index_t); | |
2627 llvm::Value *check_idx = builder.CreateSIToFP (int_idx, scalar_t); | |
2628 llvm::Value *cond0 = builder.CreateFCmpUNE (idx, check_idx); | |
18274
e243b705a726
Fix building JIT with 64-bit indexing (bug #41163).
Lasse Schuirmann <lasse@schuirmann.net>
parents:
17787
diff
changeset
|
2629 llvm::Value *cond1 = builder.CreateICmpSLT (int_idx, one_idx); |
15016 | 2630 llvm::Value *cond = builder.CreateOr (cond0, cond1); |
2631 | |
2632 llvm::BasicBlock *done = fn.new_block ("done"); | |
2633 llvm::BasicBlock *conv_error = fn.new_block ("conv_error", done); | |
2634 llvm::BasicBlock *normal = fn.new_block ("normal", done); | |
2635 builder.CreateCondBr (cond, conv_error, normal); | |
2636 | |
2637 builder.SetInsertPoint (conv_error); | |
2638 ginvalid_index.call (builder); | |
2639 builder.CreateBr (done); | |
2640 | |
2641 builder.SetInsertPoint (normal); | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
2642 llvm::Value *len |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
2643 = builder.CreateExtractValue (mat, llvm::ArrayRef<unsigned> (2)); |
15016 | 2644 cond = builder.CreateICmpSGT (int_idx, len); |
2645 | |
2646 | |
2647 llvm::BasicBlock *bounds_error = fn.new_block ("bounds_error", done); | |
2648 llvm::BasicBlock *success = fn.new_block ("success", done); | |
2649 builder.CreateCondBr (cond, bounds_error, success); | |
2650 | |
2651 builder.SetInsertPoint (bounds_error); | |
18274
e243b705a726
Fix building JIT with 64-bit indexing (bug #41163).
Lasse Schuirmann <lasse@schuirmann.net>
parents:
17787
diff
changeset
|
2652 gindex_range.call (builder, one_int, one_int, int_idx, len); |
15016 | 2653 builder.CreateBr (done); |
2654 | |
2655 builder.SetInsertPoint (success); | |
2656 llvm::Value *data = builder.CreateExtractValue (mat, | |
2657 llvm::ArrayRef<unsigned> (1)); | |
2658 llvm::Value *gep = builder.CreateInBoundsGEP (data, int_idx); | |
2659 llvm::Value *ret = builder.CreateLoad (gep); | |
2660 builder.CreateBr (done); | |
2661 | |
2662 builder.SetInsertPoint (done); | |
2663 | |
2664 llvm::PHINode *merge = llvm::PHINode::Create (scalar_t, 3); | |
2665 builder.Insert (merge); | |
2666 merge->addIncoming (undef, conv_error); | |
2667 merge->addIncoming (undef, bounds_error); | |
2668 merge->addIncoming (ret, success); | |
2669 fn.do_return (builder, merge); | |
2670 } | |
2671 paren_subsref_fn.add_overload (fn); | |
2672 | |
2673 // paren subsasgn | |
2674 paren_subsasgn_fn.stash_name ("()subsasgn"); | |
2675 | |
2676 jit_function resize_paren_subsasgn | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2677 = create_external (JIT_FN (octave_jit_paren_subsasgn_impl), matrix, matrix, |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2678 index, scalar); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2679 |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2680 fn = create_internal ("octave_jit_paren_subsasgn", matrix, matrix, scalar, |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2681 scalar); |
15016 | 2682 fn.mark_can_error (); |
2683 body = fn.new_block (); | |
2684 builder.SetInsertPoint (body); | |
2685 { | |
18274
e243b705a726
Fix building JIT with 64-bit indexing (bug #41163).
Lasse Schuirmann <lasse@schuirmann.net>
parents:
17787
diff
changeset
|
2686 llvm::Value *one_idx = llvm::ConstantInt::get (index_t, 1); |
e243b705a726
Fix building JIT with 64-bit indexing (bug #41163).
Lasse Schuirmann <lasse@schuirmann.net>
parents:
17787
diff
changeset
|
2687 llvm::Value *one_int = llvm::ConstantInt::get (int_t, 1); |
15016 | 2688 |
2689 llvm::Value *mat = fn.argument (builder, 0); | |
2690 llvm::Value *idx = fn.argument (builder, 1); | |
2691 llvm::Value *value = fn.argument (builder, 2); | |
2692 | |
2693 llvm::Value *int_idx = builder.CreateFPToSI (idx, index_t); | |
2694 llvm::Value *check_idx = builder.CreateSIToFP (int_idx, scalar_t); | |
2695 llvm::Value *cond0 = builder.CreateFCmpUNE (idx, check_idx); | |
18274
e243b705a726
Fix building JIT with 64-bit indexing (bug #41163).
Lasse Schuirmann <lasse@schuirmann.net>
parents:
17787
diff
changeset
|
2696 llvm::Value *cond1 = builder.CreateICmpSLT (int_idx, one_idx); |
15016 | 2697 llvm::Value *cond = builder.CreateOr (cond0, cond1); |
2698 | |
2699 llvm::BasicBlock *done = fn.new_block ("done"); | |
2700 | |
2701 llvm::BasicBlock *conv_error = fn.new_block ("conv_error", done); | |
2702 llvm::BasicBlock *normal = fn.new_block ("normal", done); | |
2703 builder.CreateCondBr (cond, conv_error, normal); | |
2704 builder.SetInsertPoint (conv_error); | |
2705 ginvalid_index.call (builder); | |
2706 builder.CreateBr (done); | |
2707 | |
2708 builder.SetInsertPoint (normal); | |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
2709 llvm::Value *len = builder.CreateExtractValue (mat, 2); |
15016 | 2710 cond0 = builder.CreateICmpSGT (int_idx, len); |
2711 | |
2712 llvm::Value *rcount = builder.CreateExtractValue (mat, 0); | |
2713 rcount = builder.CreateLoad (rcount); | |
18274
e243b705a726
Fix building JIT with 64-bit indexing (bug #41163).
Lasse Schuirmann <lasse@schuirmann.net>
parents:
17787
diff
changeset
|
2714 cond1 = builder.CreateICmpSGT (rcount, one_int); |
15016 | 2715 cond = builder.CreateOr (cond0, cond1); |
2716 | |
2717 llvm::BasicBlock *bounds_error = fn.new_block ("bounds_error", done); | |
2718 llvm::BasicBlock *success = fn.new_block ("success", done); | |
2719 builder.CreateCondBr (cond, bounds_error, success); | |
2720 | |
2721 // resize on out of bounds access | |
2722 builder.SetInsertPoint (bounds_error); | |
15027
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
2723 llvm::Value *resize_result = resize_paren_subsasgn.call (builder, mat, |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
2724 int_idx, value); |
15016 | 2725 builder.CreateBr (done); |
2726 | |
2727 builder.SetInsertPoint (success); | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
2728 llvm::Value *data |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
2729 = builder.CreateExtractValue (mat, llvm::ArrayRef<unsigned> (1)); |
15016 | 2730 llvm::Value *gep = builder.CreateInBoundsGEP (data, int_idx); |
2731 builder.CreateStore (value, gep); | |
2732 builder.CreateBr (done); | |
2733 | |
2734 builder.SetInsertPoint (done); | |
2735 | |
2736 llvm::PHINode *merge = llvm::PHINode::Create (matrix_t, 3); | |
2737 builder.Insert (merge); | |
2738 merge->addIncoming (mat, conv_error); | |
2739 merge->addIncoming (resize_result, bounds_error); | |
2740 merge->addIncoming (mat, success); | |
2741 fn.do_return (builder, merge); | |
2742 } | |
2743 paren_subsasgn_fn.add_overload (fn); | |
2744 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2745 fn = create_external (JIT_FN (octave_jit_paren_subsasgn_matrix_range), matrix, |
15016 | 2746 matrix, range, scalar); |
2747 fn.mark_can_error (); | |
2748 paren_subsasgn_fn.add_overload (fn); | |
2749 | |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
2750 end1_fn.stash_name ("end1"); |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2751 fn = create_internal ("octave_jit_end1_matrix", scalar, matrix, index, index); |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
2752 body = fn.new_block (); |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
2753 builder.SetInsertPoint (body); |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
2754 { |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
2755 llvm::Value *mat = fn.argument (builder, 0); |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
2756 llvm::Value *ret = builder.CreateExtractValue (mat, 2); |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
2757 fn.do_return (builder, builder.CreateSIToFP (ret, scalar_t)); |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
2758 } |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
2759 end1_fn.add_overload (fn); |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
2760 |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
2761 end_fn.stash_name ("end"); |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2762 fn = create_external (JIT_FN (octave_jit_end_matrix),scalar, matrix, index, |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2763 index); |
15056
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
2764 end_fn.add_overload (fn); |
bc32288f4a42
Support the end keyword for one dimentional indexing in JIT.
Max Brister <max@2bass.com>
parents:
15027
diff
changeset
|
2765 |
15337
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
2766 // -------------------- create_undef -------------------- |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
2767 create_undef_fn.stash_name ("create_undef"); |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2768 fn = create_external (JIT_FN (octave_jit_create_undef), any); |
15337
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
2769 create_undef_fn.add_overload (fn); |
3f43e9d6d86e
JIT compile anonymous functions
Max Brister <max@2bass.com>
parents:
15334
diff
changeset
|
2770 |
15016 | 2771 casts[any->type_id ()].stash_name ("(any)"); |
2772 casts[scalar->type_id ()].stash_name ("(scalar)"); | |
18554 | 2773 casts[single->type_id ()].stash_name ("(single)"); |
18557 | 2774 casts[intN (8)->type_id ()].stash_name ("(int8)"); |
18559 | 2775 casts[intN (16)->type_id ()].stash_name ("(int16)"); |
18560 | 2776 casts[intN (32)->type_id ()].stash_name ("(int32)"); |
18558
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2777 casts[intN (64)->type_id ()].stash_name ("(int64)"); |
18561 | 2778 casts[uintN (8)->type_id ()].stash_name ("(uint8)"); |
18555 | 2779 casts[uintN (16)->type_id ()].stash_name ("(uint16)"); |
15016 | 2780 casts[complex->type_id ()].stash_name ("(complex)"); |
2781 casts[matrix->type_id ()].stash_name ("(matrix)"); | |
15603 | 2782 casts[range->type_id ()].stash_name ("(range)"); |
15016 | 2783 |
2784 // cast any <- matrix | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2785 fn = create_external (JIT_FN (octave_jit_cast_any_matrix), any, matrix); |
15016 | 2786 casts[any->type_id ()].add_overload (fn); |
2787 | |
2788 // cast matrix <- any | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2789 fn = create_external (JIT_FN (octave_jit_cast_matrix_any), matrix, any); |
15016 | 2790 casts[matrix->type_id ()].add_overload (fn); |
2791 | |
15027
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
2792 // cast any <- range |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2793 fn = create_external (JIT_FN (octave_jit_cast_any_range), any, range); |
15027
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
2794 casts[any->type_id ()].add_overload (fn); |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
2795 |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
2796 // cast range <- any |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2797 fn = create_external (JIT_FN (octave_jit_cast_range_any), range, any); |
15027
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
2798 casts[range->type_id ()].add_overload (fn); |
741d2dbcc117
Check trip count before compiling for loops.
Max Brister <max@2bass.com>
parents:
15019
diff
changeset
|
2799 |
15016 | 2800 // cast any <- scalar |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2801 fn = create_external (JIT_FN (octave_jit_cast_any_scalar), any, scalar); |
15016 | 2802 casts[any->type_id ()].add_overload (fn); |
2803 | |
2804 // cast scalar <- any | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2805 fn = create_external (JIT_FN (octave_jit_cast_scalar_any), scalar, any); |
15016 | 2806 casts[scalar->type_id ()].add_overload (fn); |
2807 | |
18554 | 2808 // cast any <- single |
2809 fn = create_external (JIT_FN (octave_jit_cast_any_single), any, single); | |
2810 casts[any->type_id ()].add_overload (fn); | |
2811 | |
2812 // cast single <- any | |
2813 fn = create_external (JIT_FN (octave_jit_cast_single_any), single, any); | |
2814 casts[single->type_id ()].add_overload (fn); | |
2815 | |
18557 | 2816 // cast any <- int8 |
2817 fn = create_external (JIT_FN (octave_jit_cast_any_int8), any, intN (8)); | |
2818 casts[any->type_id ()].add_overload (fn); | |
2819 | |
2820 // cast int8 <- any | |
2821 fn = create_external (JIT_FN (octave_jit_cast_int8_any), intN (8), any); | |
2822 casts[intN (8)->type_id ()].add_overload (fn); | |
2823 | |
18559 | 2824 // cast any <- int16 |
2825 fn = create_external (JIT_FN (octave_jit_cast_any_int16), any, intN (16)); | |
2826 casts[any->type_id ()].add_overload (fn); | |
2827 | |
2828 // cast int16 <- any | |
2829 fn = create_external (JIT_FN (octave_jit_cast_int16_any), intN (16), any); | |
2830 casts[intN (16)->type_id ()].add_overload (fn); | |
2831 | |
18560 | 2832 // cast any <- int32 |
2833 fn = create_external (JIT_FN (octave_jit_cast_any_int32), any, intN (32)); | |
2834 casts[any->type_id ()].add_overload (fn); | |
2835 | |
2836 // cast int32 <- any | |
2837 fn = create_external (JIT_FN (octave_jit_cast_int32_any), intN (32), any); | |
2838 casts[intN (32)->type_id ()].add_overload (fn); | |
2839 | |
18558
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2840 // cast any <- int64 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2841 fn = create_external (JIT_FN (octave_jit_cast_any_int64), any, intN (64)); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2842 casts[any->type_id ()].add_overload (fn); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2843 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2844 // cast int64 <- any |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2845 fn = create_external (JIT_FN (octave_jit_cast_int64_any), intN (64), any); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2846 casts[intN (64)->type_id ()].add_overload (fn); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2847 |
18561 | 2848 // cast any <- uint8 |
2849 fn = create_external (JIT_FN (octave_jit_cast_any_uint8), any, uintN (8)); | |
2850 casts[any->type_id ()].add_overload (fn); | |
2851 | |
2852 // cast uint8 <- any | |
2853 fn = create_external (JIT_FN (octave_jit_cast_uint8_any), uintN (8), any); | |
2854 casts[uintN (8)->type_id ()].add_overload (fn); | |
2855 | |
18555 | 2856 // cast any <- uint16 |
2857 fn = create_external (JIT_FN (octave_jit_cast_any_uint16), any, uintN (16)); | |
2858 casts[any->type_id ()].add_overload (fn); | |
2859 | |
2860 // cast uint16 <- any | |
2861 fn = create_external (JIT_FN (octave_jit_cast_uint16_any), uintN (16), any); | |
2862 casts[uintN (16)->type_id ()].add_overload (fn); | |
2863 | |
15016 | 2864 // cast any <- complex |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2865 fn = create_external (JIT_FN (octave_jit_cast_any_complex), any, complex); |
15016 | 2866 casts[any->type_id ()].add_overload (fn); |
2867 | |
2868 // cast complex <- any | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2869 fn = create_external (JIT_FN (octave_jit_cast_complex_any), complex, any); |
15016 | 2870 casts[complex->type_id ()].add_overload (fn); |
2871 | |
2872 // cast complex <- scalar | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2873 fn = create_internal ("octave_jit_cast_complex_scalar", complex, scalar); |
15016 | 2874 body = fn.new_block (); |
2875 builder.SetInsertPoint (body); | |
2876 { | |
2877 llvm::Value *zero = llvm::ConstantFP::get (scalar_t, 0); | |
2878 fn.do_return (builder, complex_new (fn.argument (builder, 0), zero)); | |
2879 } | |
2880 casts[complex->type_id ()].add_overload (fn); | |
2881 | |
2882 // cast scalar <- complex | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2883 fn = create_internal ("octave_jit_cast_scalar_complex", scalar, complex); |
15016 | 2884 body = fn.new_block (); |
2885 builder.SetInsertPoint (body); | |
2886 fn.do_return (builder, complex_real (fn.argument (builder, 0))); | |
2887 casts[scalar->type_id ()].add_overload (fn); | |
2888 | |
2889 // cast any <- any | |
2890 fn = create_identity (any); | |
2891 casts[any->type_id ()].add_overload (fn); | |
2892 | |
2893 // cast scalar <- scalar | |
2894 fn = create_identity (scalar); | |
2895 casts[scalar->type_id ()].add_overload (fn); | |
2896 | |
18554 | 2897 // cast single <- single |
2898 fn = create_identity (single); | |
2899 casts[single->type_id ()].add_overload (fn); | |
2900 | |
18557 | 2901 // cast int8 <- int8 |
2902 fn = create_identity (intN (8)); | |
2903 casts[intN (8)->type_id ()].add_overload (fn); | |
2904 | |
18559 | 2905 // cast int16 <- int16 |
2906 fn = create_identity (intN (16)); | |
2907 casts[intN (16)->type_id ()].add_overload (fn); | |
2908 | |
18560 | 2909 // cast int32 <- int32 |
2910 fn = create_identity (intN (32)); | |
2911 casts[intN (32)->type_id ()].add_overload (fn); | |
2912 | |
18558
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2913 // cast int64 <- int64 |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2914 fn = create_identity (intN (64)); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2915 casts[intN (64)->type_id ()].add_overload (fn); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
2916 |
18561 | 2917 // cast uint8 <- uint8 |
2918 fn = create_identity (uintN (8)); | |
2919 casts[uintN (8)->type_id ()].add_overload (fn); | |
2920 | |
18555 | 2921 // cast uint16 <- uint16 |
2922 fn = create_identity (uintN (16)); | |
2923 casts[uintN (16)->type_id ()].add_overload (fn); | |
2924 | |
15016 | 2925 // cast complex <- complex |
2926 fn = create_identity (complex); | |
2927 casts[complex->type_id ()].add_overload (fn); | |
2928 | |
2929 // -------------------- builtin functions -------------------- | |
2930 add_builtin ("#unknown_function"); | |
2931 unknown_function = builtins["#unknown_function"]; | |
2932 | |
2933 add_builtin ("sin"); | |
2934 register_intrinsic ("sin", llvm::Intrinsic::sin, scalar, scalar); | |
2935 register_generic ("sin", matrix, matrix); | |
2936 | |
2937 add_builtin ("cos"); | |
2938 register_intrinsic ("cos", llvm::Intrinsic::cos, scalar, scalar); | |
2939 register_generic ("cos", matrix, matrix); | |
2940 | |
2941 add_builtin ("exp"); | |
18446
634d9989bf7b
Fix copy&paste typo when registering exp with JIT (bug #41560).
Rik <rik@octave.org>
parents:
18323
diff
changeset
|
2942 register_intrinsic ("exp", llvm::Intrinsic::exp, scalar, scalar); |
15016 | 2943 register_generic ("exp", matrix, matrix); |
2944 | |
15169
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2945 add_builtin ("balance"); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2946 register_generic ("balance", matrix, matrix); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2947 |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2948 add_builtin ("cond"); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2949 register_generic ("cond", scalar, matrix); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2950 |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2951 add_builtin ("det"); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2952 register_generic ("det", scalar, matrix); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2953 |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2954 add_builtin ("norm"); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2955 register_generic ("norm", scalar, matrix); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2956 |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2957 add_builtin ("rand"); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2958 register_generic ("rand", matrix, scalar); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2959 register_generic ("rand", matrix, std::vector<jit_type *> (2, scalar)); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2960 |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2961 add_builtin ("magic"); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2962 register_generic ("magic", matrix, scalar); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2963 register_generic ("magic", matrix, std::vector<jit_type *> (2, scalar)); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2964 |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2965 add_builtin ("eye"); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2966 register_generic ("eye", matrix, scalar); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2967 register_generic ("eye", matrix, std::vector<jit_type *> (2, scalar)); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2968 |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2969 add_builtin ("mod"); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2970 register_generic ("mod", scalar, std::vector<jit_type *> (2, scalar)); |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
2971 |
15016 | 2972 casts.resize (next_id + 1); |
2973 jit_function any_id = create_identity (any); | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2974 jit_function grab_any = create_external (JIT_FN (octave_jit_grab_any), |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
2975 any, any); |
15016 | 2976 jit_function release_any = get_release (any); |
2977 std::vector<jit_type *> args; | |
2978 args.resize (1); | |
2979 | |
2980 for (std::map<std::string, jit_type *>::iterator iter = builtins.begin (); | |
2981 iter != builtins.end (); ++iter) | |
2982 { | |
2983 jit_type *btype = iter->second; | |
2984 args[0] = btype; | |
2985 | |
15334
8125773322d4
Error on undefined an unused variables in JIT
Max Brister <max@2bass.com>
parents:
15311
diff
changeset
|
2986 grab_fn.add_overload (jit_function (grab_any, btype, args)); |
15016 | 2987 release_fn.add_overload (jit_function (release_any, 0, args)); |
2988 casts[any->type_id ()].add_overload (jit_function (any_id, any, args)); | |
2989 | |
2990 args[0] = any; | |
2991 casts[btype->type_id ()].add_overload (jit_function (any_id, btype, | |
2992 args)); | |
2993 } | |
2994 } | |
2995 | |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
2996 const jit_function& |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
2997 jit_typeinfo::do_end (jit_value *value, jit_value *idx, jit_value *count) |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
2998 { |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
2999 jit_const_index *ccount = dynamic_cast<jit_const_index *> (count); |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
3000 if (ccount && ccount->value () == 1) |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
3001 return end1_fn.overload (value->type (), idx->type (), count->type ()); |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
3002 |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
3003 return end_fn.overload (value->type (), idx->type (), count->type ()); |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
3004 } |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
3005 |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
3006 jit_type* |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
3007 jit_typeinfo::new_type (const std::string& name, jit_type *parent, |
15124
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
3008 llvm::Type *llvm_type, bool skip_paren) |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
3009 { |
15124
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
3010 jit_type *ret = new jit_type (name, parent, llvm_type, skip_paren, next_id++); |
15102
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
3011 id_to_type.push_back (ret); |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
3012 return ret; |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
3013 } |
d29f2583cf7b
Support end in multi indexing in JIT
Max Brister <max@2bass.com>
parents:
15096
diff
changeset
|
3014 |
15016 | 3015 void |
15019
ae3670d4df29
Update the execution engine's global mapping for external functions
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
3016 jit_typeinfo::add_print (jit_type *ty, void *fptr) |
15016 | 3017 { |
3018 std::stringstream name; | |
3019 name << "octave_jit_print_" << ty->name (); | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
3020 jit_function fn = create_external (engine, fptr, name.str (), |
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
3021 0, intN (8), ty); |
15016 | 3022 print_fn.add_overload (fn); |
3023 } | |
3024 | |
3025 // FIXME: cp between add_binary_op, add_binary_icmp, and add_binary_fcmp | |
3026 void | |
3027 jit_typeinfo::add_binary_op (jit_type *ty, int op, int llvm_op) | |
3028 { | |
3029 std::stringstream fname; | |
3030 octave_value::binary_op ov_op = static_cast<octave_value::binary_op>(op); | |
3031 fname << "octave_jit_" << octave_value::binary_op_as_string (ov_op) | |
3032 << "_" << ty->name (); | |
3033 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3034 jit_function fn = create_internal (fname.str (), ty, ty, ty); |
15016 | 3035 llvm::BasicBlock *block = fn.new_block (); |
3036 builder.SetInsertPoint (block); | |
3037 llvm::Instruction::BinaryOps temp | |
3038 = static_cast<llvm::Instruction::BinaryOps>(llvm_op); | |
3039 | |
3040 llvm::Value *ret = builder.CreateBinOp (temp, fn.argument (builder, 0), | |
3041 fn.argument (builder, 1)); | |
3042 fn.do_return (builder, ret); | |
3043 binary_ops[op].add_overload (fn); | |
3044 } | |
3045 | |
3046 void | |
3047 jit_typeinfo::add_binary_icmp (jit_type *ty, int op, int llvm_op) | |
3048 { | |
3049 std::stringstream fname; | |
3050 octave_value::binary_op ov_op = static_cast<octave_value::binary_op>(op); | |
3051 fname << "octave_jit" << octave_value::binary_op_as_string (ov_op) | |
3052 << "_" << ty->name (); | |
3053 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3054 jit_function fn = create_internal (fname.str (), boolean, ty, ty); |
15016 | 3055 llvm::BasicBlock *block = fn.new_block (); |
3056 builder.SetInsertPoint (block); | |
3057 llvm::CmpInst::Predicate temp | |
3058 = static_cast<llvm::CmpInst::Predicate>(llvm_op); | |
3059 llvm::Value *ret = builder.CreateICmp (temp, fn.argument (builder, 0), | |
3060 fn.argument (builder, 1)); | |
3061 fn.do_return (builder, ret); | |
3062 binary_ops[op].add_overload (fn); | |
3063 } | |
3064 | |
3065 void | |
3066 jit_typeinfo::add_binary_fcmp (jit_type *ty, int op, int llvm_op) | |
3067 { | |
3068 std::stringstream fname; | |
3069 octave_value::binary_op ov_op = static_cast<octave_value::binary_op>(op); | |
3070 fname << "octave_jit" << octave_value::binary_op_as_string (ov_op) | |
3071 << "_" << ty->name (); | |
3072 | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3073 jit_function fn = create_internal (fname.str (), boolean, ty, ty); |
15016 | 3074 llvm::BasicBlock *block = fn.new_block (); |
3075 builder.SetInsertPoint (block); | |
3076 llvm::CmpInst::Predicate temp | |
3077 = static_cast<llvm::CmpInst::Predicate>(llvm_op); | |
3078 llvm::Value *ret = builder.CreateFCmp (temp, fn.argument (builder, 0), | |
3079 fn.argument (builder, 1)); | |
3080 fn.do_return (builder, ret); | |
3081 binary_ops[op].add_overload (fn); | |
3082 } | |
3083 | |
3084 jit_function | |
3085 jit_typeinfo::create_function (jit_convention::type cc, const llvm::Twine& name, | |
3086 jit_type *ret, | |
3087 const std::vector<jit_type *>& args) | |
3088 { | |
3089 jit_function result (module, cc, name, ret, args); | |
3090 return result; | |
3091 } | |
3092 | |
3093 jit_function | |
3094 jit_typeinfo::create_identity (jit_type *type) | |
3095 { | |
3096 size_t id = type->type_id (); | |
3097 if (id >= identities.size ()) | |
3098 identities.resize (id + 1); | |
3099 | |
3100 if (! identities[id].valid ()) | |
3101 { | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
3102 std::stringstream name; |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
3103 name << "id_" << type->name (); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
3104 |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3105 jit_function fn = create_internal (name.str (), type, type); |
15016 | 3106 llvm::BasicBlock *body = fn.new_block (); |
3107 builder.SetInsertPoint (body); | |
3108 fn.do_return (builder, fn.argument (builder, 0)); | |
3109 return identities[id] = fn; | |
3110 } | |
3111 | |
3112 return identities[id]; | |
3113 } | |
3114 | |
3115 llvm::Value * | |
15019
ae3670d4df29
Update the execution engine's global mapping for external functions
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
3116 jit_typeinfo::do_insert_error_check (llvm::IRBuilderD& abuilder) |
15016 | 3117 { |
15019
ae3670d4df29
Update the execution engine's global mapping for external functions
Max Brister <max@2bass.com>
parents:
15016
diff
changeset
|
3118 return abuilder.CreateLoad (lerror_state); |
15016 | 3119 } |
3120 | |
15603 | 3121 llvm::Value * |
3122 jit_typeinfo::do_insert_interrupt_check (llvm::IRBuilderD& abuilder) | |
3123 { | |
3124 llvm::LoadInst *val = abuilder.CreateLoad (loctave_interrupt_state); | |
3125 val->setVolatile (true); | |
3126 return abuilder.CreateICmpSGT (val, abuilder.getInt32 (0)); | |
3127 } | |
3128 | |
15016 | 3129 void |
3130 jit_typeinfo::add_builtin (const std::string& name) | |
3131 { | |
15124
0464e3ceb85b
Skip functions when resolving end context in JIT
Max Brister <max@2bass.com>
parents:
15102
diff
changeset
|
3132 jit_type *btype = new_type (name, any, any->to_llvm (), true); |
15016 | 3133 builtins[name] = btype; |
3134 | |
3135 octave_builtin *ov_builtin = find_builtin (name); | |
3136 if (ov_builtin) | |
3137 ov_builtin->stash_jit (*btype); | |
3138 } | |
3139 | |
3140 void | |
3141 jit_typeinfo::register_intrinsic (const std::string& name, size_t iid, | |
3142 jit_type *result, | |
3143 const std::vector<jit_type *>& args) | |
3144 { | |
3145 jit_type *builtin_type = builtins[name]; | |
3146 size_t nargs = args.size (); | |
3147 llvm::SmallVector<llvm::Type *, 5> llvm_args (nargs); | |
3148 for (size_t i = 0; i < nargs; ++i) | |
3149 llvm_args[i] = args[i]->to_llvm (); | |
3150 | |
3151 llvm::Intrinsic::ID id = static_cast<llvm::Intrinsic::ID> (iid); | |
3152 llvm::Function *ifun = llvm::Intrinsic::getDeclaration (module, id, | |
3153 llvm_args); | |
3154 std::stringstream fn_name; | |
3155 fn_name << "octave_jit_" << name; | |
3156 | |
3157 std::vector<jit_type *> args1 (nargs + 1); | |
3158 args1[0] = builtin_type; | |
3159 std::copy (args.begin (), args.end (), args1.begin () + 1); | |
3160 | |
3161 // The first argument will be the Octave function, but we already know that | |
3162 // the function call is the equivalent of the intrinsic, so we ignore it and | |
3163 // call the intrinsic with the remaining arguments. | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3164 jit_function fn = create_internal (fn_name.str (), result, args1); |
15016 | 3165 llvm::BasicBlock *body = fn.new_block (); |
3166 builder.SetInsertPoint (body); | |
3167 | |
3168 llvm::SmallVector<llvm::Value *, 5> fargs (nargs); | |
3169 for (size_t i = 0; i < nargs; ++i) | |
3170 fargs[i] = fn.argument (builder, i + 1); | |
3171 | |
3172 llvm::Value *ret = builder.CreateCall (ifun, fargs); | |
3173 fn.do_return (builder, ret); | |
3174 paren_subsref_fn.add_overload (fn); | |
3175 } | |
3176 | |
3177 octave_builtin * | |
3178 jit_typeinfo::find_builtin (const std::string& name) | |
3179 { | |
3180 // FIXME: Finalize what we want to store in octave_builtin, then add functions | |
3181 // to access these values in octave_value | |
3182 octave_value ov_builtin = symbol_table::find (name); | |
3183 return dynamic_cast<octave_builtin *> (ov_builtin.internal_rep ()); | |
3184 } | |
3185 | |
3186 void | |
15135
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3187 jit_typeinfo::register_generic (const std::string& name, jit_type *result, |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3188 const std::vector<jit_type *>& args) |
15016 | 3189 { |
15135
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3190 octave_builtin *builtin = find_builtin (name); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3191 if (! builtin) |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3192 return; |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3193 |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3194 std::vector<jit_type *> fn_args (args.size () + 1); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3195 fn_args[0] = builtins[name]; |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3196 std::copy (args.begin (), args.end (), fn_args.begin () + 1); |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3197 jit_function fn = create_internal (name, result, fn_args); |
15136
eeaaac7c86b6
jit-typeinfo.cc (jit_typeinfo::register_generic): Mark can error
Max Brister <max@2bass.com>
parents:
15135
diff
changeset
|
3198 fn.mark_can_error (); |
15135
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3199 llvm::BasicBlock *block = fn.new_block (); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3200 builder.SetInsertPoint (block); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3201 llvm::Type *any_t = any->to_llvm (); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3202 llvm::ArrayType *array_t = llvm::ArrayType::get (any_t, args.size ()); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3203 llvm::Value *array = llvm::UndefValue::get (array_t); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3204 for (size_t i = 0; i < args.size (); ++i) |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3205 { |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3206 llvm::Value *arg = fn.argument (builder, i + 1); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3207 jit_function agrab = get_grab (args[i]); |
15169
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
3208 if (agrab.valid ()) |
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
3209 arg = agrab.call (builder, arg); |
15135
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3210 jit_function acast = cast (any, args[i]); |
15169
6242904370bd
Support balance, cond, det, norm, rand, magic, eye, and mod in JIT
Max Brister <max@2bass.com>
parents:
15148
diff
changeset
|
3211 array = builder.CreateInsertValue (array, acast.call (builder, arg), i); |
15135
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3212 } |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3213 |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3214 llvm::Value *array_mem = builder.CreateAlloca (array_t); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3215 builder.CreateStore (array, array_mem); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3216 array = builder.CreateBitCast (array_mem, any_t->getPointerTo ()); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3217 |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3218 jit_type *jintTy = intN (sizeof (octave_builtin::fcn) * 8); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3219 llvm::Type *intTy = jintTy->to_llvm (); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3220 size_t fcn_int = reinterpret_cast<size_t> (builtin->function ()); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3221 llvm::Value *fcn = llvm::ConstantInt::get (intTy, fcn_int); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3222 llvm::Value *nargin = llvm::ConstantInt::get (intTy, args.size ()); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3223 size_t result_int = reinterpret_cast<size_t> (result); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3224 llvm::Value *res_llvm = llvm::ConstantInt::get (intTy, result_int); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3225 llvm::Value *ret = any_call.call (builder, fcn, nargin, array, res_llvm); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3226 |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3227 jit_function cast_result = cast (result, any); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3228 fn.do_return (builder, cast_result.call (builder, ret)); |
bd6bb87e2bea
Support sin, cos, and exp with matrix arguments in JIT
Max Brister <max@2bass.com>
parents:
15124
diff
changeset
|
3229 paren_subsref_fn.add_overload (fn); |
15016 | 3230 } |
3231 | |
3232 jit_function | |
3233 jit_typeinfo::mirror_binary (const jit_function& fn) | |
3234 { | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3235 jit_function ret = create_internal (fn.name () + "_reverse", |
15016 | 3236 fn.result (), fn.argument_type (1), |
3237 fn.argument_type (0)); | |
3238 if (fn.can_error ()) | |
3239 ret.mark_can_error (); | |
3240 | |
3241 llvm::BasicBlock *body = ret.new_block (); | |
3242 builder.SetInsertPoint (body); | |
3243 llvm::Value *result = fn.call (builder, ret.argument (builder, 1), | |
3244 ret.argument (builder, 0)); | |
3245 if (ret.result ()) | |
3246 ret.do_return (builder, result); | |
3247 else | |
3248 ret.do_return (builder); | |
3249 | |
3250 return ret; | |
3251 } | |
3252 | |
3253 llvm::Value * | |
3254 jit_typeinfo::pack_complex (llvm::IRBuilderD& bld, llvm::Value *cplx) | |
3255 { | |
3256 llvm::Type *complex_ret = instance->complex_ret; | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3257 llvm::Value *real = bld.CreateExtractValue (cplx, 0); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3258 llvm::Value *imag = bld.CreateExtractValue (cplx, 1); |
15016 | 3259 llvm::Value *ret = llvm::UndefValue::get (complex_ret); |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
3260 |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
3261 unsigned int re_idx[] = {0, 0}; |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
3262 unsigned int im_idx[] = {0, 1}; |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
3263 ret = bld.CreateInsertValue (ret, real, re_idx); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
3264 return bld.CreateInsertValue (ret, imag, im_idx); |
15016 | 3265 } |
3266 | |
3267 llvm::Value * | |
3268 jit_typeinfo::unpack_complex (llvm::IRBuilderD& bld, llvm::Value *result) | |
3269 { | |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
3270 unsigned int re_idx[] = {0, 0}; |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
3271 unsigned int im_idx[] = {0, 1}; |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
3272 |
15016 | 3273 llvm::Type *complex_t = get_complex ()->to_llvm (); |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
3274 llvm::Value *real = bld.CreateExtractValue (result, re_idx); |
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
3275 llvm::Value *imag = bld.CreateExtractValue (result, im_idx); |
15016 | 3276 llvm::Value *ret = llvm::UndefValue::get (complex_t); |
15370
8355fddce815
Use sret and do not use save/restore stack (bug #37308)
Max Brister <max@2bass.com>
parents:
15337
diff
changeset
|
3277 |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3278 ret = bld.CreateInsertValue (ret, real, 0); |
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3279 return bld.CreateInsertValue (ret, imag, 1); |
15016 | 3280 } |
3281 | |
3282 llvm::Value * | |
3283 jit_typeinfo::complex_real (llvm::Value *cx) | |
3284 { | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3285 return builder.CreateExtractValue (cx, 0); |
15016 | 3286 } |
3287 | |
3288 llvm::Value * | |
3289 jit_typeinfo::complex_real (llvm::Value *cx, llvm::Value *real) | |
3290 { | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3291 return builder.CreateInsertValue (cx, real, 0); |
15016 | 3292 } |
3293 | |
3294 llvm::Value * | |
3295 jit_typeinfo::complex_imag (llvm::Value *cx) | |
3296 { | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3297 return builder.CreateExtractValue (cx, 1); |
15016 | 3298 } |
3299 | |
3300 llvm::Value * | |
3301 jit_typeinfo::complex_imag (llvm::Value *cx, llvm::Value *imag) | |
3302 { | |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3303 return builder.CreateInsertValue (cx, imag, 1); |
15016 | 3304 } |
3305 | |
3306 llvm::Value * | |
3307 jit_typeinfo::complex_new (llvm::Value *real, llvm::Value *imag) | |
3308 { | |
3309 llvm::Value *ret = llvm::UndefValue::get (complex->to_llvm ()); | |
3310 ret = complex_real (ret, real); | |
3311 return complex_imag (ret, imag); | |
3312 } | |
3313 | |
3314 void | |
3315 jit_typeinfo::create_int (size_t nbits) | |
3316 { | |
3317 std::stringstream tname; | |
3318 tname << "int" << nbits; | |
3319 ints[nbits] = new_type (tname.str (), any, llvm::Type::getIntNTy (context, | |
3320 nbits)); | |
3321 } | |
3322 | |
18555 | 3323 void |
3324 jit_typeinfo::create_uint (size_t nbits) | |
3325 { | |
3326 std::stringstream tname; | |
3327 tname << "uint" << nbits; | |
3328 uints[nbits] = new_type (tname.str (), any, llvm::Type::getIntNTy (context, | |
3329 nbits)); | |
3330 } | |
3331 | |
15016 | 3332 jit_type * |
3333 jit_typeinfo::intN (size_t nbits) const | |
3334 { | |
3335 std::map<size_t, jit_type *>::const_iterator iter = ints.find (nbits); | |
3336 if (iter != ints.end ()) | |
3337 return iter->second; | |
3338 | |
3339 throw jit_fail_exception ("No such integer type"); | |
3340 } | |
3341 | |
3342 jit_type * | |
18555 | 3343 jit_typeinfo::uintN (size_t nbits) const |
3344 { | |
3345 std::map<size_t, jit_type *>::const_iterator iter = uints.find (nbits); | |
3346 if (iter != uints.end ()) | |
3347 return iter->second; | |
3348 | |
3349 throw jit_fail_exception ("No such unsigned integer type"); | |
3350 } | |
3351 | |
3352 jit_type * | |
15016 | 3353 jit_typeinfo::do_type_of (const octave_value &ov) const |
3354 { | |
3355 if (ov.is_function ()) | |
3356 { | |
3357 // FIXME: This is ugly, we need to finalize how we want to to this, then | |
3358 // have octave_value fully support the needed functionality | |
3359 octave_builtin *builtin | |
3360 = dynamic_cast<octave_builtin *> (ov.internal_rep ()); | |
3361 return builtin && builtin->to_jit () ? builtin->to_jit () | |
17787
175b392e91fe
Use GNU style coding conventions for code in libinterp/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
3362 : unknown_function; |
15016 | 3363 } |
3364 | |
3365 if (ov.is_range ()) | |
3366 return get_range (); | |
3367 | |
15311
de9bfcf637df
Fix error when compiling with complex matrix (bug #37247)
Max Brister <max@2bass.com>
parents:
15219
diff
changeset
|
3368 if (ov.is_double_type () && ! ov.is_complex_type ()) |
15016 | 3369 { |
3370 if (ov.is_real_scalar ()) | |
3371 return get_scalar (); | |
3372 | |
3373 if (ov.is_matrix_type ()) | |
3374 return get_matrix (); | |
3375 } | |
3376 | |
18554 | 3377 if (ov.is_single_type () && ! ov.is_complex_type ()) |
3378 { | |
3379 if (ov.is_real_scalar ()) | |
3380 return get_single (); | |
3381 } | |
3382 | |
18557 | 3383 if (ov.is_int8_type()) |
3384 { | |
3385 return intN (8); | |
3386 } | |
3387 | |
18559 | 3388 if (ov.is_int16_type()) |
3389 { | |
3390 return intN (16); | |
3391 } | |
3392 | |
18560 | 3393 if (ov.is_int32_type()) |
3394 { | |
3395 return intN (32); | |
3396 } | |
3397 | |
18558
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
3398 if (ov.is_int64_type()) |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
3399 { |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
3400 return intN (64); |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
3401 } |
1867774aaa2e
jit compiler: Add support for int64 type
LYH <lyh.kernel@gmail.com>
parents:
18557
diff
changeset
|
3402 |
18561 | 3403 if (ov.is_uint8_type()) |
3404 { | |
3405 return uintN (8); | |
3406 } | |
3407 | |
18555 | 3408 if (ov.is_uint16_type()) |
3409 { | |
3410 return uintN (16); | |
3411 } | |
3412 | |
15016 | 3413 if (ov.is_complex_scalar ()) |
15583
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
3414 { |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
3415 Complex cv = ov.complex_value (); |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
3416 |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
3417 // We don't really represent complex values, instead we represent |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
3418 // complex_or_scalar. If the imag value is zero, we assume a scalar. |
15893
1f076c40c133
Do not use vectorized llvm commands for complex numbers
Max Brister <max@2bass.com>
parents:
15603
diff
changeset
|
3419 if (cv.imag () != 0) |
15583
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
3420 return get_complex (); |
0754bdfbc8fe
Correct multiplication complex multiplication with NaN in JIT
Max Brister <max@2bass.com>
parents:
15385
diff
changeset
|
3421 } |
15016 | 3422 |
3423 return get_any (); | |
3424 } | |
3425 | |
3426 #endif | |
18553 | 3427 |
3428 #pragma GCC diagnostic pop |