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 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
86 }
87 Ok(isl_rs_result)
88 }
89
90 pub fn copy(&self) -> Result<Schedule, LibISLError> {
92 let sched = self;
93 let isl_rs_ctx = sched.get_ctx();
94 let sched = sched.ptr;
95 let isl_rs_result = unsafe { isl_schedule_copy(sched) };
96 let isl_rs_result = Schedule { ptr: isl_rs_result,
97 should_free_on_drop: true };
98 let err = isl_rs_ctx.last_error();
99 if err != Error::None_ {
100 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
101 }
102 Ok(isl_rs_result)
103 }
104
105 pub fn dump(&self) -> Result<(), LibISLError> {
107 let schedule = self;
108 let isl_rs_ctx = schedule.get_ctx();
109 let schedule = schedule.ptr;
110 let isl_rs_result = unsafe { isl_schedule_dump(schedule) };
111 let err = isl_rs_ctx.last_error();
112 if err != Error::None_ {
113 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
114 }
115 Ok(isl_rs_result)
116 }
117
118 pub fn empty(space: Space) -> Result<Schedule, LibISLError> {
120 let isl_rs_ctx = space.get_ctx();
121 let mut space = space;
122 space.do_not_free_on_drop();
123 let space = space.ptr;
124 let isl_rs_result = unsafe { isl_schedule_empty(space) };
125 let isl_rs_result = Schedule { ptr: isl_rs_result,
126 should_free_on_drop: true };
127 let err = isl_rs_ctx.last_error();
128 if err != Error::None_ {
129 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
130 }
131 Ok(isl_rs_result)
132 }
133
134 pub fn expand(self, contraction: UnionPwMultiAff, expansion: Schedule)
136 -> Result<Schedule, LibISLError> {
137 let schedule = self;
138 let isl_rs_ctx = schedule.get_ctx();
139 let mut schedule = schedule;
140 schedule.do_not_free_on_drop();
141 let schedule = schedule.ptr;
142 let mut contraction = contraction;
143 contraction.do_not_free_on_drop();
144 let contraction = contraction.ptr;
145 let mut expansion = expansion;
146 expansion.do_not_free_on_drop();
147 let expansion = expansion.ptr;
148 let isl_rs_result = unsafe { isl_schedule_expand(schedule, contraction, expansion) };
149 let isl_rs_result = Schedule { ptr: isl_rs_result,
150 should_free_on_drop: true };
151 let err = isl_rs_ctx.last_error();
152 if err != Error::None_ {
153 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
154 }
155 Ok(isl_rs_result)
156 }
157
158 pub fn free(self) -> Result<Schedule, LibISLError> {
160 let sched = self;
161 let isl_rs_ctx = sched.get_ctx();
162 let mut sched = sched;
163 sched.do_not_free_on_drop();
164 let sched = sched.ptr;
165 let isl_rs_result = unsafe { isl_schedule_free(sched) };
166 let isl_rs_result = Schedule { ptr: isl_rs_result,
167 should_free_on_drop: true };
168 let err = isl_rs_ctx.last_error();
169 if err != Error::None_ {
170 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
171 }
172 Ok(isl_rs_result)
173 }
174
175 pub fn from_domain(domain: UnionSet) -> Result<Schedule, LibISLError> {
177 let isl_rs_ctx = domain.get_ctx();
178 let mut domain = domain;
179 domain.do_not_free_on_drop();
180 let domain = domain.ptr;
181 let isl_rs_result = unsafe { isl_schedule_from_domain(domain) };
182 let isl_rs_result = Schedule { ptr: isl_rs_result,
183 should_free_on_drop: true };
184 let err = isl_rs_ctx.last_error();
185 if err != Error::None_ {
186 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
187 }
188 Ok(isl_rs_result)
189 }
190
191 pub fn get_ctx(&self) -> Context {
193 let sched = self;
194 let sched = sched.ptr;
195 let isl_rs_result = unsafe { isl_schedule_get_ctx(sched) };
196 let isl_rs_result = Context { ptr: isl_rs_result,
197 should_free_on_drop: false };
198 isl_rs_result
199 }
200
201 pub fn get_domain(&self) -> Result<UnionSet, LibISLError> {
203 let schedule = self;
204 let isl_rs_ctx = schedule.get_ctx();
205 let schedule = schedule.ptr;
206 let isl_rs_result = unsafe { isl_schedule_get_domain(schedule) };
207 let isl_rs_result = UnionSet { ptr: isl_rs_result,
208 should_free_on_drop: true };
209 let err = isl_rs_ctx.last_error();
210 if err != Error::None_ {
211 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
212 }
213 Ok(isl_rs_result)
214 }
215
216 pub fn get_map(&self) -> Result<UnionMap, LibISLError> {
218 let sched = self;
219 let isl_rs_ctx = sched.get_ctx();
220 let sched = sched.ptr;
221 let isl_rs_result = unsafe { isl_schedule_get_map(sched) };
222 let isl_rs_result = UnionMap { ptr: isl_rs_result,
223 should_free_on_drop: true };
224 let err = isl_rs_ctx.last_error();
225 if err != Error::None_ {
226 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
227 }
228 Ok(isl_rs_result)
229 }
230
231 pub fn get_root(&self) -> Result<ScheduleNode, LibISLError> {
233 let schedule = self;
234 let isl_rs_ctx = schedule.get_ctx();
235 let schedule = schedule.ptr;
236 let isl_rs_result = unsafe { isl_schedule_get_root(schedule) };
237 let isl_rs_result = ScheduleNode { ptr: isl_rs_result,
238 should_free_on_drop: true };
239 let err = isl_rs_ctx.last_error();
240 if err != Error::None_ {
241 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
242 }
243 Ok(isl_rs_result)
244 }
245
246 pub fn gist_domain_params(self, context: Set) -> Result<Schedule, LibISLError> {
248 let schedule = self;
249 let isl_rs_ctx = schedule.get_ctx();
250 let mut schedule = schedule;
251 schedule.do_not_free_on_drop();
252 let schedule = schedule.ptr;
253 let mut context = context;
254 context.do_not_free_on_drop();
255 let context = context.ptr;
256 let isl_rs_result = unsafe { isl_schedule_gist_domain_params(schedule, context) };
257 let isl_rs_result = Schedule { ptr: isl_rs_result,
258 should_free_on_drop: true };
259 let err = isl_rs_ctx.last_error();
260 if err != Error::None_ {
261 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
262 }
263 Ok(isl_rs_result)
264 }
265
266 pub fn insert_context(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_insert_context(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 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
282 }
283 Ok(isl_rs_result)
284 }
285
286 pub fn insert_guard(self, guard: Set) -> Result<Schedule, LibISLError> {
288 let schedule = self;
289 let isl_rs_ctx = schedule.get_ctx();
290 let mut schedule = schedule;
291 schedule.do_not_free_on_drop();
292 let schedule = schedule.ptr;
293 let mut guard = guard;
294 guard.do_not_free_on_drop();
295 let guard = guard.ptr;
296 let isl_rs_result = unsafe { isl_schedule_insert_guard(schedule, guard) };
297 let isl_rs_result = Schedule { ptr: isl_rs_result,
298 should_free_on_drop: true };
299 let err = isl_rs_ctx.last_error();
300 if err != Error::None_ {
301 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
302 }
303 Ok(isl_rs_result)
304 }
305
306 pub fn insert_partial_schedule(self, partial: MultiUnionPwAff)
308 -> Result<Schedule, LibISLError> {
309 let schedule = self;
310 let isl_rs_ctx = schedule.get_ctx();
311 let mut schedule = schedule;
312 schedule.do_not_free_on_drop();
313 let schedule = schedule.ptr;
314 let mut partial = partial;
315 partial.do_not_free_on_drop();
316 let partial = partial.ptr;
317 let isl_rs_result = unsafe { isl_schedule_insert_partial_schedule(schedule, partial) };
318 let isl_rs_result = Schedule { ptr: isl_rs_result,
319 should_free_on_drop: true };
320 let err = isl_rs_ctx.last_error();
321 if err != Error::None_ {
322 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
323 }
324 Ok(isl_rs_result)
325 }
326
327 pub fn intersect_domain(self, domain: UnionSet) -> Result<Schedule, LibISLError> {
329 let schedule = self;
330 let isl_rs_ctx = schedule.get_ctx();
331 let mut schedule = schedule;
332 schedule.do_not_free_on_drop();
333 let schedule = schedule.ptr;
334 let mut domain = domain;
335 domain.do_not_free_on_drop();
336 let domain = domain.ptr;
337 let isl_rs_result = unsafe { isl_schedule_intersect_domain(schedule, domain) };
338 let isl_rs_result = Schedule { ptr: isl_rs_result,
339 should_free_on_drop: true };
340 let err = isl_rs_ctx.last_error();
341 if err != Error::None_ {
342 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
343 }
344 Ok(isl_rs_result)
345 }
346
347 pub fn plain_is_equal(&self, schedule2: &Schedule) -> Result<bool, LibISLError> {
349 let schedule1 = self;
350 let isl_rs_ctx = schedule1.get_ctx();
351 let schedule1 = schedule1.ptr;
352 let schedule2 = schedule2.ptr;
353 let isl_rs_result = unsafe { isl_schedule_plain_is_equal(schedule1, schedule2) };
354 let isl_rs_result = match isl_rs_result {
355 0 => false,
356 1 => true,
357 _ => panic!("Got isl_bool = -1"),
358 };
359 let err = isl_rs_ctx.last_error();
360 if err != Error::None_ {
361 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
362 }
363 Ok(isl_rs_result)
364 }
365
366 pub fn pullback_union_pw_multi_aff(self, upma: UnionPwMultiAff)
368 -> Result<Schedule, LibISLError> {
369 let schedule = self;
370 let isl_rs_ctx = schedule.get_ctx();
371 let mut schedule = schedule;
372 schedule.do_not_free_on_drop();
373 let schedule = schedule.ptr;
374 let mut upma = upma;
375 upma.do_not_free_on_drop();
376 let upma = upma.ptr;
377 let isl_rs_result = unsafe { isl_schedule_pullback_union_pw_multi_aff(schedule, upma) };
378 let isl_rs_result = Schedule { ptr: isl_rs_result,
379 should_free_on_drop: true };
380 let err = isl_rs_ctx.last_error();
381 if err != Error::None_ {
382 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
383 }
384 Ok(isl_rs_result)
385 }
386
387 pub fn read_from_str(ctx: &Context, str_: &str) -> Result<Schedule, LibISLError> {
389 let isl_rs_ctx = Context { ptr: ctx.ptr,
390 should_free_on_drop: false };
391 let ctx = ctx.ptr;
392 let str_ = CString::new(str_).unwrap();
393 let str_ = str_.as_ptr();
394 let isl_rs_result = unsafe { isl_schedule_read_from_str(ctx, str_) };
395 let isl_rs_result = Schedule { ptr: isl_rs_result,
396 should_free_on_drop: true };
397 let err = isl_rs_ctx.last_error();
398 if err != Error::None_ {
399 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
400 }
401 Ok(isl_rs_result)
402 }
403
404 pub fn reset_user(self) -> Result<Schedule, LibISLError> {
406 let schedule = self;
407 let isl_rs_ctx = schedule.get_ctx();
408 let mut schedule = schedule;
409 schedule.do_not_free_on_drop();
410 let schedule = schedule.ptr;
411 let isl_rs_result = unsafe { isl_schedule_reset_user(schedule) };
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 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
417 }
418 Ok(isl_rs_result)
419 }
420
421 pub fn sequence(self, schedule2: Schedule) -> Result<Schedule, LibISLError> {
423 let schedule1 = self;
424 let isl_rs_ctx = schedule1.get_ctx();
425 let mut schedule1 = schedule1;
426 schedule1.do_not_free_on_drop();
427 let schedule1 = schedule1.ptr;
428 let mut schedule2 = schedule2;
429 schedule2.do_not_free_on_drop();
430 let schedule2 = schedule2.ptr;
431 let isl_rs_result = unsafe { isl_schedule_sequence(schedule1, schedule2) };
432 let isl_rs_result = Schedule { ptr: isl_rs_result,
433 should_free_on_drop: true };
434 let err = isl_rs_ctx.last_error();
435 if err != Error::None_ {
436 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
437 }
438 Ok(isl_rs_result)
439 }
440
441 pub fn set(self, schedule2: Schedule) -> Result<Schedule, LibISLError> {
443 let schedule1 = self;
444 let isl_rs_ctx = schedule1.get_ctx();
445 let mut schedule1 = schedule1;
446 schedule1.do_not_free_on_drop();
447 let schedule1 = schedule1.ptr;
448 let mut schedule2 = schedule2;
449 schedule2.do_not_free_on_drop();
450 let schedule2 = schedule2.ptr;
451 let isl_rs_result = unsafe { isl_schedule_set(schedule1, schedule2) };
452 let isl_rs_result = Schedule { ptr: isl_rs_result,
453 should_free_on_drop: true };
454 let err = isl_rs_ctx.last_error();
455 if err != Error::None_ {
456 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
457 }
458 Ok(isl_rs_result)
459 }
460
461 pub fn to_str(&self) -> Result<&str, LibISLError> {
463 let schedule = self;
464 let isl_rs_ctx = schedule.get_ctx();
465 let schedule = schedule.ptr;
466 let isl_rs_result = unsafe { isl_schedule_to_str(schedule) };
467 let isl_rs_result = unsafe { CStr::from_ptr(isl_rs_result) };
468 let isl_rs_result = isl_rs_result.to_str().unwrap();
469 let err = isl_rs_ctx.last_error();
470 if err != Error::None_ {
471 return Err(LibISLError::new(err, isl_rs_ctx.last_error_msg()));
472 }
473 Ok(isl_rs_result)
474 }
475
476 pub fn do_not_free_on_drop(&mut self) {
479 self.should_free_on_drop = false;
480 }
481}
482
483impl Drop for Schedule {
484 fn drop(&mut self) {
485 if self.should_free_on_drop {
486 unsafe {
487 isl_schedule_free(self.ptr);
488 }
489 }
490 }
491}