extern crate syn;
use syn::*;
#[derive(Debug, Clone)]
pub enum Dim {
RangeFromZero(String, i32), }
#[allow(unused_assignments)]
pub fn get_global_work_size(
mut global_work_size: Vec<Dim>,
i: ExprForLoop,
) -> (Vec<Dim>, Option<Block>) {
if global_work_size.len() == 3 {
return (global_work_size, None);
}
let mut new_global_work_size_var = None;
let mut new_global_work_size = None;
if i.label.is_some() {
return (global_work_size, None);
}
if let Pat::Ident(ident) = i.pat {
if ident.by_ref.is_none() && ident.mutability.is_none() && ident.subpat.is_none() {
new_global_work_size_var = Some(ident.ident.to_string());
} else {
return (global_work_size, None);
}
} else {
return (global_work_size, None);
}
if let Expr::Range(range) = *i.expr {
if let Some(from) = range.from {
if let Some(to) = range.to {
if let Expr::Lit(from_lit) = *from {
if let Expr::Lit(to_lit) = *to {
if let Lit::Int(from_lit_int) = from_lit.lit {
if let Lit::Int(to_lit_int) = to_lit.lit {
let from_val_raw = from_lit_int.base10_parse::<i32>();
let to_val_raw = to_lit_int.base10_parse::<i32>();
if let Ok(from_val) = from_val_raw {
if let Ok(to_val) = to_val_raw {
if from_val == 0 && from_val < to_val {
if let Some(var) = new_global_work_size_var {
new_global_work_size = Some(to_val - from_val);
global_work_size.push(Dim::RangeFromZero(
var,
new_global_work_size.unwrap(),
));
if i.body.stmts.len() == 1 {
match &i.body.stmts[0] {
Stmt::Expr(expr) => {
if let Expr::ForLoop(for_expr) = expr {
let (
new_global_work_size,
block_for_kernel,
) = get_global_work_size(
global_work_size,
for_expr.clone(),
);
if block_for_kernel.is_none() {
return (
new_global_work_size,
Some(i.body),
);
} else {
return (
new_global_work_size,
block_for_kernel,
);
}
}
}
Stmt::Semi(expr, _) => {
if let Expr::ForLoop(for_expr) = expr {
let (
new_global_work_size,
block_for_kernel,
) = get_global_work_size(
global_work_size,
for_expr.clone(),
);
if block_for_kernel.is_none() {
return (
new_global_work_size,
Some(i.body),
);
} else {
return (
new_global_work_size,
block_for_kernel,
);
}
}
}
_ => {}
}
}
return (global_work_size, Some(i.body));
}
}
}
}
}
}
}
}
}
}
}
(global_work_size, None)
}