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