use super::{
Context, Error, LibISLError, MultiUnionPwAff, ScheduleNode, Set, Space, UnionMap,
UnionPwMultiAff, UnionSet,
};
use libc::uintptr_t;
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
pub struct Schedule {
pub ptr: uintptr_t,
pub should_free_on_drop: bool,
}
extern "C" {
fn isl_schedule_align_params(schedule: uintptr_t, space: uintptr_t) -> uintptr_t;
fn isl_schedule_copy(sched: uintptr_t) -> uintptr_t;
fn isl_schedule_dump(schedule: uintptr_t) -> ();
fn isl_schedule_empty(space: uintptr_t) -> uintptr_t;
fn isl_schedule_expand(schedule: uintptr_t, contraction: uintptr_t, expansion: uintptr_t)
-> uintptr_t;
fn isl_schedule_free(sched: uintptr_t) -> uintptr_t;
fn isl_schedule_from_domain(domain: uintptr_t) -> uintptr_t;
fn isl_schedule_get_ctx(sched: uintptr_t) -> uintptr_t;
fn isl_schedule_get_domain(schedule: uintptr_t) -> uintptr_t;
fn isl_schedule_get_map(sched: uintptr_t) -> uintptr_t;
fn isl_schedule_get_root(schedule: uintptr_t) -> uintptr_t;
fn isl_schedule_gist_domain_params(schedule: uintptr_t, context: uintptr_t) -> uintptr_t;
fn isl_schedule_insert_context(schedule: uintptr_t, context: uintptr_t) -> uintptr_t;
fn isl_schedule_insert_guard(schedule: uintptr_t, guard: uintptr_t) -> uintptr_t;
fn isl_schedule_insert_partial_schedule(schedule: uintptr_t, partial: uintptr_t) -> uintptr_t;
fn isl_schedule_intersect_domain(schedule: uintptr_t, domain: uintptr_t) -> uintptr_t;
fn isl_schedule_plain_is_equal(schedule1: uintptr_t, schedule2: uintptr_t) -> i32;
fn isl_schedule_pullback_union_pw_multi_aff(schedule: uintptr_t, upma: uintptr_t) -> uintptr_t;
fn isl_schedule_read_from_str(ctx: uintptr_t, str_: *const c_char) -> uintptr_t;
fn isl_schedule_reset_user(schedule: uintptr_t) -> uintptr_t;
fn isl_schedule_sequence(schedule1: uintptr_t, schedule2: uintptr_t) -> uintptr_t;
fn isl_schedule_set(schedule1: uintptr_t, schedule2: uintptr_t) -> uintptr_t;
fn isl_schedule_to_str(schedule: uintptr_t) -> *const c_char;
}
impl Schedule {
pub fn align_params(self, space: Space) -> Result<Schedule, LibISLError> {
let schedule = self;
let isl_rs_ctx = schedule.get_ctx();
let mut schedule = schedule;
schedule.do_not_free_on_drop();
let schedule = schedule.ptr;
let mut space = space;
space.do_not_free_on_drop();
let space = space.ptr;
let isl_rs_result = unsafe { isl_schedule_align_params(schedule, space) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn copy(&self) -> Result<Schedule, LibISLError> {
let sched = self;
let isl_rs_ctx = sched.get_ctx();
let sched = sched.ptr;
let isl_rs_result = unsafe { isl_schedule_copy(sched) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn dump(&self) -> Result<(), LibISLError> {
let schedule = self;
let isl_rs_ctx = schedule.get_ctx();
let schedule = schedule.ptr;
let isl_rs_result = unsafe { isl_schedule_dump(schedule) };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn empty(space: Space) -> Result<Schedule, LibISLError> {
let isl_rs_ctx = space.get_ctx();
let mut space = space;
space.do_not_free_on_drop();
let space = space.ptr;
let isl_rs_result = unsafe { isl_schedule_empty(space) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn expand(self, contraction: UnionPwMultiAff, expansion: Schedule)
-> Result<Schedule, LibISLError> {
let schedule = self;
let isl_rs_ctx = schedule.get_ctx();
let mut schedule = schedule;
schedule.do_not_free_on_drop();
let schedule = schedule.ptr;
let mut contraction = contraction;
contraction.do_not_free_on_drop();
let contraction = contraction.ptr;
let mut expansion = expansion;
expansion.do_not_free_on_drop();
let expansion = expansion.ptr;
let isl_rs_result = unsafe { isl_schedule_expand(schedule, contraction, expansion) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn free(self) -> Result<Schedule, LibISLError> {
let sched = self;
let isl_rs_ctx = sched.get_ctx();
let mut sched = sched;
sched.do_not_free_on_drop();
let sched = sched.ptr;
let isl_rs_result = unsafe { isl_schedule_free(sched) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn from_domain(domain: UnionSet) -> Result<Schedule, LibISLError> {
let isl_rs_ctx = domain.get_ctx();
let mut domain = domain;
domain.do_not_free_on_drop();
let domain = domain.ptr;
let isl_rs_result = unsafe { isl_schedule_from_domain(domain) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn get_ctx(&self) -> Context {
let sched = self;
let sched = sched.ptr;
let isl_rs_result = unsafe { isl_schedule_get_ctx(sched) };
let isl_rs_result = Context { ptr: isl_rs_result,
should_free_on_drop: false };
isl_rs_result
}
pub fn get_domain(&self) -> Result<UnionSet, LibISLError> {
let schedule = self;
let isl_rs_ctx = schedule.get_ctx();
let schedule = schedule.ptr;
let isl_rs_result = unsafe { isl_schedule_get_domain(schedule) };
let isl_rs_result = UnionSet { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn get_map(&self) -> Result<UnionMap, LibISLError> {
let sched = self;
let isl_rs_ctx = sched.get_ctx();
let sched = sched.ptr;
let isl_rs_result = unsafe { isl_schedule_get_map(sched) };
let isl_rs_result = UnionMap { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn get_root(&self) -> Result<ScheduleNode, LibISLError> {
let schedule = self;
let isl_rs_ctx = schedule.get_ctx();
let schedule = schedule.ptr;
let isl_rs_result = unsafe { isl_schedule_get_root(schedule) };
let isl_rs_result = ScheduleNode { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn gist_domain_params(self, context: Set) -> Result<Schedule, LibISLError> {
let schedule = self;
let isl_rs_ctx = schedule.get_ctx();
let mut schedule = schedule;
schedule.do_not_free_on_drop();
let schedule = schedule.ptr;
let mut context = context;
context.do_not_free_on_drop();
let context = context.ptr;
let isl_rs_result = unsafe { isl_schedule_gist_domain_params(schedule, context) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn insert_context(self, context: Set) -> Result<Schedule, LibISLError> {
let schedule = self;
let isl_rs_ctx = schedule.get_ctx();
let mut schedule = schedule;
schedule.do_not_free_on_drop();
let schedule = schedule.ptr;
let mut context = context;
context.do_not_free_on_drop();
let context = context.ptr;
let isl_rs_result = unsafe { isl_schedule_insert_context(schedule, context) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn insert_guard(self, guard: Set) -> Result<Schedule, LibISLError> {
let schedule = self;
let isl_rs_ctx = schedule.get_ctx();
let mut schedule = schedule;
schedule.do_not_free_on_drop();
let schedule = schedule.ptr;
let mut guard = guard;
guard.do_not_free_on_drop();
let guard = guard.ptr;
let isl_rs_result = unsafe { isl_schedule_insert_guard(schedule, guard) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn insert_partial_schedule(self, partial: MultiUnionPwAff)
-> Result<Schedule, LibISLError> {
let schedule = self;
let isl_rs_ctx = schedule.get_ctx();
let mut schedule = schedule;
schedule.do_not_free_on_drop();
let schedule = schedule.ptr;
let mut partial = partial;
partial.do_not_free_on_drop();
let partial = partial.ptr;
let isl_rs_result = unsafe { isl_schedule_insert_partial_schedule(schedule, partial) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn intersect_domain(self, domain: UnionSet) -> Result<Schedule, LibISLError> {
let schedule = self;
let isl_rs_ctx = schedule.get_ctx();
let mut schedule = schedule;
schedule.do_not_free_on_drop();
let schedule = schedule.ptr;
let mut domain = domain;
domain.do_not_free_on_drop();
let domain = domain.ptr;
let isl_rs_result = unsafe { isl_schedule_intersect_domain(schedule, domain) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn plain_is_equal(&self, schedule2: &Schedule) -> Result<bool, LibISLError> {
let schedule1 = self;
let isl_rs_ctx = schedule1.get_ctx();
let schedule1 = schedule1.ptr;
let schedule2 = schedule2.ptr;
let isl_rs_result = unsafe { isl_schedule_plain_is_equal(schedule1, schedule2) };
let isl_rs_result = match isl_rs_result {
0 => false,
1 => true,
_ => {
return Err(LibISLError::new(Error::Unknown, "Got isl_bool = -1"));
}
};
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn pullback_union_pw_multi_aff(self, upma: UnionPwMultiAff)
-> Result<Schedule, LibISLError> {
let schedule = self;
let isl_rs_ctx = schedule.get_ctx();
let mut schedule = schedule;
schedule.do_not_free_on_drop();
let schedule = schedule.ptr;
let mut upma = upma;
upma.do_not_free_on_drop();
let upma = upma.ptr;
let isl_rs_result = unsafe { isl_schedule_pullback_union_pw_multi_aff(schedule, upma) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn read_from_str(ctx: &Context, str_: &str) -> Result<Schedule, LibISLError> {
let isl_rs_ctx = Context { ptr: ctx.ptr,
should_free_on_drop: false };
let ctx = ctx.ptr;
let str_ = CString::new(str_).unwrap();
let str_ = str_.as_ptr();
let isl_rs_result = unsafe { isl_schedule_read_from_str(ctx, str_) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn reset_user(self) -> Result<Schedule, LibISLError> {
let schedule = self;
let isl_rs_ctx = schedule.get_ctx();
let mut schedule = schedule;
schedule.do_not_free_on_drop();
let schedule = schedule.ptr;
let isl_rs_result = unsafe { isl_schedule_reset_user(schedule) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn sequence(self, schedule2: Schedule) -> Result<Schedule, LibISLError> {
let schedule1 = self;
let isl_rs_ctx = schedule1.get_ctx();
let mut schedule1 = schedule1;
schedule1.do_not_free_on_drop();
let schedule1 = schedule1.ptr;
let mut schedule2 = schedule2;
schedule2.do_not_free_on_drop();
let schedule2 = schedule2.ptr;
let isl_rs_result = unsafe { isl_schedule_sequence(schedule1, schedule2) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn set(self, schedule2: Schedule) -> Result<Schedule, LibISLError> {
let schedule1 = self;
let isl_rs_ctx = schedule1.get_ctx();
let mut schedule1 = schedule1;
schedule1.do_not_free_on_drop();
let schedule1 = schedule1.ptr;
let mut schedule2 = schedule2;
schedule2.do_not_free_on_drop();
let schedule2 = schedule2.ptr;
let isl_rs_result = unsafe { isl_schedule_set(schedule1, schedule2) };
let isl_rs_result = Schedule { ptr: isl_rs_result,
should_free_on_drop: true };
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn to_str(&self) -> Result<&str, LibISLError> {
let schedule = self;
let isl_rs_ctx = schedule.get_ctx();
let schedule = schedule.ptr;
let isl_rs_result = unsafe { isl_schedule_to_str(schedule) };
let isl_rs_result = unsafe { CStr::from_ptr(isl_rs_result) };
let isl_rs_result = isl_rs_result.to_str().unwrap();
let err = isl_rs_ctx.last_error();
if err != Error::None_ {
let err_msg = isl_rs_ctx.last_error_msg();
isl_rs_ctx.reset_error();
return Err(LibISLError::new(err, err_msg));
}
Ok(isl_rs_result)
}
pub fn do_not_free_on_drop(&mut self) {
self.should_free_on_drop = false;
}
}
impl Drop for Schedule {
fn drop(&mut self) {
if self.should_free_on_drop {
unsafe {
isl_schedule_free(self.ptr);
}
}
}
}