1use super::{
5 Context, Error, LibISLError, MultiUnionPwAff, ScheduleNode, Set, Space, UnionMap,
6 UnionPwMultiAff, UnionSet,
7};
8use libc::uintptr_t;
9use std::ffi::{CStr, CString};
10use std::os::raw::c_char;
11
12pub struct Schedule {
14 pub ptr: uintptr_t,
15 pub should_free_on_drop: bool,
16}
17
18extern "C" {
19
20 fn isl_schedule_align_params(schedule: uintptr_t, space: uintptr_t) -> uintptr_t;
21
22 fn isl_schedule_copy(sched: uintptr_t) -> uintptr_t;
23
24 fn isl_schedule_dump(schedule: uintptr_t) -> ();
25
26 fn isl_schedule_empty(space: uintptr_t) -> uintptr_t;
27
28 fn isl_schedule_expand(schedule: uintptr_t, contraction: uintptr_t, expansion: uintptr_t)
29 -> uintptr_t;
30
31 fn isl_schedule_free(sched: uintptr_t) -> uintptr_t;
32
33 fn isl_schedule_from_domain(domain: uintptr_t) -> uintptr_t;
34
35 fn isl_schedule_get_ctx(sched: uintptr_t) -> uintptr_t;
36
37 fn isl_schedule_get_domain(schedule: uintptr_t) -> uintptr_t;
38
39 fn isl_schedule_get_map(sched: uintptr_t) -> uintptr_t;
40
41 fn isl_schedule_get_root(schedule: uintptr_t) -> uintptr_t;
42
43 fn isl_schedule_gist_domain_params(schedule: uintptr_t, context: uintptr_t) -> uintptr_t;
44
45 fn isl_schedule_insert_context(schedule: uintptr_t, context: uintptr_t) -> uintptr_t;
46
47 fn isl_schedule_insert_guard(schedule: uintptr_t, guard: uintptr_t) -> uintptr_t;
48
49 fn isl_schedule_insert_partial_schedule(schedule: uintptr_t, partial: uintptr_t) -> uintptr_t;
50
51 fn isl_schedule_intersect_domain(schedule: uintptr_t, domain: uintptr_t) -> uintptr_t;
52
53 fn isl_schedule_plain_is_equal(schedule1: uintptr_t, schedule2: uintptr_t) -> i32;
54
55 fn isl_schedule_pullback_union_pw_multi_aff(schedule: uintptr_t, upma: uintptr_t) -> uintptr_t;
56
57 fn isl_schedule_read_from_str(ctx: uintptr_t, str_: *const c_char) -> uintptr_t;
58
59 fn isl_schedule_reset_user(schedule: uintptr_t) -> uintptr_t;
60
61 fn isl_schedule_sequence(schedule1: uintptr_t, schedule2: uintptr_t) -> uintptr_t;
62
63 fn isl_schedule_set(schedule1: uintptr_t, schedule2: uintptr_t) -> uintptr_t;
64
65 fn isl_schedule_to_str(schedule: uintptr_t) -> *const c_char;
66
67}
68
69impl Schedule {
70 pub fn align_params(self, space: Space) -> Result<Schedule, LibISLError> {
72 let schedule = self;
73 let isl_rs_ctx = schedule.get_ctx();
74 let mut schedule = schedule;
75 schedule.do_not_free_on_drop();
76 let schedule = schedule.ptr;
77 let mut space = space;
78 space.do_not_free_on_drop();
79 let space = space.ptr;
80 let isl_rs_result = unsafe { isl_schedule_align_params(schedule, space) };
81 let isl_rs_result = Schedule { ptr: isl_rs_result,
82 should_free_on_drop: true };
83 let err = isl_rs_ctx.last_error();
84 if err != Error::None_ {
85 let err_msg = isl_rs_ctx.last_error_msg();
86 isl_rs_ctx.reset_error();
87 return Err(LibISLError::new(err, err_msg));
88 }
89 Ok(isl_rs_result)
90 }
91
92 pub fn copy(&self) -> Result<Schedule, LibISLError> {
94 let sched = self;
95 let isl_rs_ctx = sched.get_ctx();
96 let sched = sched.ptr;
97 let isl_rs_result = unsafe { isl_schedule_copy(sched) };
98 let isl_rs_result = Schedule { ptr: isl_rs_result,
99 should_free_on_drop: true };
100 let err = isl_rs_ctx.last_error();
101 if err != Error::None_ {
102 let err_msg = isl_rs_ctx.last_error_msg();
103 isl_rs_ctx.reset_error();
104 return Err(LibISLError::new(err, err_msg));
105 }
106 Ok(isl_rs_result)
107 }
108
109 pub fn dump(&self) -> Result<(), LibISLError> {
111 let schedule = self;
112 let isl_rs_ctx = schedule.get_ctx();
113 let schedule = schedule.ptr;
114 let isl_rs_result = unsafe { isl_schedule_dump(schedule) };
115 let err = isl_rs_ctx.last_error();
116 if err != Error::None_ {
117 let err_msg = isl_rs_ctx.last_error_msg();
118 isl_rs_ctx.reset_error();
119 return Err(LibISLError::new(err, err_msg));
120 }
121 Ok(isl_rs_result)
122 }
123
124 pub fn empty(space: Space) -> Result<Schedule, LibISLError> {
126 let isl_rs_ctx = space.get_ctx();
127 let mut space = space;
128 space.do_not_free_on_drop();
129 let space = space.ptr;
130 let isl_rs_result = unsafe { isl_schedule_empty(space) };
131 let isl_rs_result = Schedule { ptr: isl_rs_result,
132 should_free_on_drop: true };
133 let err = isl_rs_ctx.last_error();
134 if err != Error::None_ {
135 let err_msg = isl_rs_ctx.last_error_msg();
136 isl_rs_ctx.reset_error();
137 return Err(LibISLError::new(err, err_msg));
138 }
139 Ok(isl_rs_result)
140 }
141
142 pub fn expand(self, contraction: UnionPwMultiAff, expansion: Schedule)
144 -> Result<Schedule, LibISLError> {
145 let schedule = self;
146 let isl_rs_ctx = schedule.get_ctx();
147 let mut schedule = schedule;
148 schedule.do_not_free_on_drop();
149 let schedule = schedule.ptr;
150 let mut contraction = contraction;
151 contraction.do_not_free_on_drop();
152 let contraction = contraction.ptr;
153 let mut expansion = expansion;
154 expansion.do_not_free_on_drop();
155 let expansion = expansion.ptr;
156 let isl_rs_result = unsafe { isl_schedule_expand(schedule, contraction, expansion) };
157 let isl_rs_result = Schedule { ptr: isl_rs_result,
158 should_free_on_drop: true };
159 let err = isl_rs_ctx.last_error();
160 if err != Error::None_ {
161 let err_msg = isl_rs_ctx.last_error_msg();
162 isl_rs_ctx.reset_error();
163 return Err(LibISLError::new(err, err_msg));
164 }
165 Ok(isl_rs_result)
166 }
167
168 pub fn free(self) -> Result<Schedule, LibISLError> {
170 let sched = self;
171 let isl_rs_ctx = sched.get_ctx();
172 let mut sched = sched;
173 sched.do_not_free_on_drop();
174 let sched = sched.ptr;
175 let isl_rs_result = unsafe { isl_schedule_free(sched) };
176 let isl_rs_result = Schedule { ptr: isl_rs_result,
177 should_free_on_drop: true };
178 let err = isl_rs_ctx.last_error();
179 if err != Error::None_ {
180 let err_msg = isl_rs_ctx.last_error_msg();
181 isl_rs_ctx.reset_error();
182 return Err(LibISLError::new(err, err_msg));
183 }
184 Ok(isl_rs_result)
185 }
186
187 pub fn from_domain(domain: UnionSet) -> Result<Schedule, LibISLError> {
189 let isl_rs_ctx = domain.get_ctx();
190 let mut domain = domain;
191 domain.do_not_free_on_drop();
192 let domain = domain.ptr;
193 let isl_rs_result = unsafe { isl_schedule_from_domain(domain) };
194 let isl_rs_result = Schedule { ptr: isl_rs_result,
195 should_free_on_drop: true };
196 let err = isl_rs_ctx.last_error();
197 if err != Error::None_ {
198 let err_msg = isl_rs_ctx.last_error_msg();
199 isl_rs_ctx.reset_error();
200 return Err(LibISLError::new(err, err_msg));
201 }
202 Ok(isl_rs_result)
203 }
204
205 pub fn get_ctx(&self) -> Context {
207 let sched = self;
208 let sched = sched.ptr;
209 let isl_rs_result = unsafe { isl_schedule_get_ctx(sched) };
210 let isl_rs_result = Context { ptr: isl_rs_result,
211 should_free_on_drop: false };
212 isl_rs_result
213 }
214
215 pub fn get_domain(&self) -> Result<UnionSet, LibISLError> {
217 let schedule = self;
218 let isl_rs_ctx = schedule.get_ctx();
219 let schedule = schedule.ptr;
220 let isl_rs_result = unsafe { isl_schedule_get_domain(schedule) };
221 let isl_rs_result = UnionSet { ptr: isl_rs_result,
222 should_free_on_drop: true };
223 let err = isl_rs_ctx.last_error();
224 if err != Error::None_ {
225 let err_msg = isl_rs_ctx.last_error_msg();
226 isl_rs_ctx.reset_error();
227 return Err(LibISLError::new(err, err_msg));
228 }
229 Ok(isl_rs_result)
230 }
231
232 pub fn get_map(&self) -> Result<UnionMap, LibISLError> {
234 let sched = self;
235 let isl_rs_ctx = sched.get_ctx();
236 let sched = sched.ptr;
237 let isl_rs_result = unsafe { isl_schedule_get_map(sched) };
238 let isl_rs_result = UnionMap { ptr: isl_rs_result,
239 should_free_on_drop: true };
240 let err = isl_rs_ctx.last_error();
241 if err != Error::None_ {
242 let err_msg = isl_rs_ctx.last_error_msg();
243 isl_rs_ctx.reset_error();
244 return Err(LibISLError::new(err, err_msg));
245 }
246 Ok(isl_rs_result)
247 }
248
249 pub fn get_root(&self) -> Result<ScheduleNode, LibISLError> {
251 let schedule = self;
252 let isl_rs_ctx = schedule.get_ctx();
253 let schedule = schedule.ptr;
254 let isl_rs_result = unsafe { isl_schedule_get_root(schedule) };
255 let isl_rs_result = ScheduleNode { ptr: isl_rs_result,
256 should_free_on_drop: true };
257 let err = isl_rs_ctx.last_error();
258 if err != Error::None_ {
259 let err_msg = isl_rs_ctx.last_error_msg();
260 isl_rs_ctx.reset_error();
261 return Err(LibISLError::new(err, err_msg));
262 }
263 Ok(isl_rs_result)
264 }
265
266 pub fn gist_domain_params(self, context: Set) -> Result<Schedule, LibISLError> {
268 let schedule = self;
269 let isl_rs_ctx = schedule.get_ctx();
270 let mut schedule = schedule;
271 schedule.do_not_free_on_drop();
272 let schedule = schedule.ptr;
273 let mut context = context;
274 context.do_not_free_on_drop();
275 let context = context.ptr;
276 let isl_rs_result = unsafe { isl_schedule_gist_domain_params(schedule, context) };
277 let isl_rs_result = Schedule { ptr: isl_rs_result,
278 should_free_on_drop: true };
279 let err = isl_rs_ctx.last_error();
280 if err != Error::None_ {
281 let err_msg = isl_rs_ctx.last_error_msg();
282 isl_rs_ctx.reset_error();
283 return Err(LibISLError::new(err, err_msg));
284 }
285 Ok(isl_rs_result)
286 }
287
288 pub fn insert_context(self, context: Set) -> Result<Schedule, LibISLError> {
290 let schedule = self;
291 let isl_rs_ctx = schedule.get_ctx();
292 let mut schedule = schedule;
293 schedule.do_not_free_on_drop();
294 let schedule = schedule.ptr;
295 let mut context = context;
296 context.do_not_free_on_drop();
297 let context = context.ptr;
298 let isl_rs_result = unsafe { isl_schedule_insert_context(schedule, context) };
299 let isl_rs_result = Schedule { ptr: isl_rs_result,
300 should_free_on_drop: true };
301 let err = isl_rs_ctx.last_error();
302 if err != Error::None_ {
303 let err_msg = isl_rs_ctx.last_error_msg();
304 isl_rs_ctx.reset_error();
305 return Err(LibISLError::new(err, err_msg));
306 }
307 Ok(isl_rs_result)
308 }
309
310 pub fn insert_guard(self, guard: Set) -> Result<Schedule, LibISLError> {
312 let schedule = self;
313 let isl_rs_ctx = schedule.get_ctx();
314 let mut schedule = schedule;
315 schedule.do_not_free_on_drop();
316 let schedule = schedule.ptr;
317 let mut guard = guard;
318 guard.do_not_free_on_drop();
319 let guard = guard.ptr;
320 let isl_rs_result = unsafe { isl_schedule_insert_guard(schedule, guard) };
321 let isl_rs_result = Schedule { ptr: isl_rs_result,
322 should_free_on_drop: true };
323 let err = isl_rs_ctx.last_error();
324 if err != Error::None_ {
325 let err_msg = isl_rs_ctx.last_error_msg();
326 isl_rs_ctx.reset_error();
327 return Err(LibISLError::new(err, err_msg));
328 }
329 Ok(isl_rs_result)
330 }
331
332 pub fn insert_partial_schedule(self, partial: MultiUnionPwAff)
334 -> Result<Schedule, LibISLError> {
335 let schedule = self;
336 let isl_rs_ctx = schedule.get_ctx();
337 let mut schedule = schedule;
338 schedule.do_not_free_on_drop();
339 let schedule = schedule.ptr;
340 let mut partial = partial;
341 partial.do_not_free_on_drop();
342 let partial = partial.ptr;
343 let isl_rs_result = unsafe { isl_schedule_insert_partial_schedule(schedule, partial) };
344 let isl_rs_result = Schedule { ptr: isl_rs_result,
345 should_free_on_drop: true };
346 let err = isl_rs_ctx.last_error();
347 if err != Error::None_ {
348 let err_msg = isl_rs_ctx.last_error_msg();
349 isl_rs_ctx.reset_error();
350 return Err(LibISLError::new(err, err_msg));
351 }
352 Ok(isl_rs_result)
353 }
354
355 pub fn intersect_domain(self, domain: UnionSet) -> Result<Schedule, LibISLError> {
357 let schedule = self;
358 let isl_rs_ctx = schedule.get_ctx();
359 let mut schedule = schedule;
360 schedule.do_not_free_on_drop();
361 let schedule = schedule.ptr;
362 let mut domain = domain;
363 domain.do_not_free_on_drop();
364 let domain = domain.ptr;
365 let isl_rs_result = unsafe { isl_schedule_intersect_domain(schedule, domain) };
366 let isl_rs_result = Schedule { ptr: isl_rs_result,
367 should_free_on_drop: true };
368 let err = isl_rs_ctx.last_error();
369 if err != Error::None_ {
370 let err_msg = isl_rs_ctx.last_error_msg();
371 isl_rs_ctx.reset_error();
372 return Err(LibISLError::new(err, err_msg));
373 }
374 Ok(isl_rs_result)
375 }
376
377 pub fn plain_is_equal(&self, schedule2: &Schedule) -> Result<bool, LibISLError> {
379 let schedule1 = self;
380 let isl_rs_ctx = schedule1.get_ctx();
381 let schedule1 = schedule1.ptr;
382 let schedule2 = schedule2.ptr;
383 let isl_rs_result = unsafe { isl_schedule_plain_is_equal(schedule1, schedule2) };
384 let isl_rs_result = match isl_rs_result {
385 0 => false,
386 1 => true,
387 _ => {
388 return Err(LibISLError::new(Error::Unknown, "Got isl_bool = -1"));
389 }
390 };
391 let err = isl_rs_ctx.last_error();
392 if err != Error::None_ {
393 let err_msg = isl_rs_ctx.last_error_msg();
394 isl_rs_ctx.reset_error();
395 return Err(LibISLError::new(err, err_msg));
396 }
397 Ok(isl_rs_result)
398 }
399
400 pub fn pullback_union_pw_multi_aff(self, upma: UnionPwMultiAff)
402 -> Result<Schedule, LibISLError> {
403 let schedule = self;
404 let isl_rs_ctx = schedule.get_ctx();
405 let mut schedule = schedule;
406 schedule.do_not_free_on_drop();
407 let schedule = schedule.ptr;
408 let mut upma = upma;
409 upma.do_not_free_on_drop();
410 let upma = upma.ptr;
411 let isl_rs_result = unsafe { isl_schedule_pullback_union_pw_multi_aff(schedule, upma) };
412 let isl_rs_result = Schedule { ptr: isl_rs_result,
413 should_free_on_drop: true };
414 let err = isl_rs_ctx.last_error();
415 if err != Error::None_ {
416 let err_msg = isl_rs_ctx.last_error_msg();
417 isl_rs_ctx.reset_error();
418 return Err(LibISLError::new(err, err_msg));
419 }
420 Ok(isl_rs_result)
421 }
422
423 pub fn read_from_str(ctx: &Context, str_: &str) -> Result<Schedule, LibISLError> {
425 let isl_rs_ctx = Context { ptr: ctx.ptr,
426 should_free_on_drop: false };
427 let ctx = ctx.ptr;
428 let str_ = CString::new(str_).unwrap();
429 let str_ = str_.as_ptr();
430 let isl_rs_result = unsafe { isl_schedule_read_from_str(ctx, str_) };
431 let isl_rs_result = Schedule { ptr: isl_rs_result,
432 should_free_on_drop: true };
433 let err = isl_rs_ctx.last_error();
434 if err != Error::None_ {
435 let err_msg = isl_rs_ctx.last_error_msg();
436 isl_rs_ctx.reset_error();
437 return Err(LibISLError::new(err, err_msg));
438 }
439 Ok(isl_rs_result)
440 }
441
442 pub fn reset_user(self) -> Result<Schedule, LibISLError> {
444 let schedule = self;
445 let isl_rs_ctx = schedule.get_ctx();
446 let mut schedule = schedule;
447 schedule.do_not_free_on_drop();
448 let schedule = schedule.ptr;
449 let isl_rs_result = unsafe { isl_schedule_reset_user(schedule) };
450 let isl_rs_result = Schedule { ptr: isl_rs_result,
451 should_free_on_drop: true };
452 let err = isl_rs_ctx.last_error();
453 if err != Error::None_ {
454 let err_msg = isl_rs_ctx.last_error_msg();
455 isl_rs_ctx.reset_error();
456 return Err(LibISLError::new(err, err_msg));
457 }
458 Ok(isl_rs_result)
459 }
460
461 pub fn sequence(self, schedule2: Schedule) -> Result<Schedule, LibISLError> {
463 let schedule1 = self;
464 let isl_rs_ctx = schedule1.get_ctx();
465 let mut schedule1 = schedule1;
466 schedule1.do_not_free_on_drop();
467 let schedule1 = schedule1.ptr;
468 let mut schedule2 = schedule2;
469 schedule2.do_not_free_on_drop();
470 let schedule2 = schedule2.ptr;
471 let isl_rs_result = unsafe { isl_schedule_sequence(schedule1, schedule2) };
472 let isl_rs_result = Schedule { ptr: isl_rs_result,
473 should_free_on_drop: true };
474 let err = isl_rs_ctx.last_error();
475 if err != Error::None_ {
476 let err_msg = isl_rs_ctx.last_error_msg();
477 isl_rs_ctx.reset_error();
478 return Err(LibISLError::new(err, err_msg));
479 }
480 Ok(isl_rs_result)
481 }
482
483 pub fn set(self, schedule2: Schedule) -> Result<Schedule, LibISLError> {
485 let schedule1 = self;
486 let isl_rs_ctx = schedule1.get_ctx();
487 let mut schedule1 = schedule1;
488 schedule1.do_not_free_on_drop();
489 let schedule1 = schedule1.ptr;
490 let mut schedule2 = schedule2;
491 schedule2.do_not_free_on_drop();
492 let schedule2 = schedule2.ptr;
493 let isl_rs_result = unsafe { isl_schedule_set(schedule1, schedule2) };
494 let isl_rs_result = Schedule { ptr: isl_rs_result,
495 should_free_on_drop: true };
496 let err = isl_rs_ctx.last_error();
497 if err != Error::None_ {
498 let err_msg = isl_rs_ctx.last_error_msg();
499 isl_rs_ctx.reset_error();
500 return Err(LibISLError::new(err, err_msg));
501 }
502 Ok(isl_rs_result)
503 }
504
505 pub fn to_str(&self) -> Result<&str, LibISLError> {
507 let schedule = self;
508 let isl_rs_ctx = schedule.get_ctx();
509 let schedule = schedule.ptr;
510 let isl_rs_result = unsafe { isl_schedule_to_str(schedule) };
511 let isl_rs_result = unsafe { CStr::from_ptr(isl_rs_result) };
512 let isl_rs_result = isl_rs_result.to_str().unwrap();
513 let err = isl_rs_ctx.last_error();
514 if err != Error::None_ {
515 let err_msg = isl_rs_ctx.last_error_msg();
516 isl_rs_ctx.reset_error();
517 return Err(LibISLError::new(err, err_msg));
518 }
519 Ok(isl_rs_result)
520 }
521
522 pub fn do_not_free_on_drop(&mut self) {
525 self.should_free_on_drop = false;
526 }
527}
528
529impl Drop for Schedule {
530 fn drop(&mut self) {
531 if self.should_free_on_drop {
532 unsafe {
533 isl_schedule_free(self.ptr);
534 }
535 }
536 }
537}