Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions cuda-oxide/crates/cuda-device/src/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1328,8 +1328,10 @@ pub fn __unchecked_indexing_config<const ENABLED: bool>() {
/// }
/// ```
///
/// The pass currently recognizes explicit counted `while` loops. Range-based
/// `for` loops are not yet recognized.
/// The pass currently recognizes explicit counted `while` loops and range `for`
/// loops (`for i in a..b` and `(a..b).rev()`) over any integer counter,
/// including `isize`. Other iterator loops, such as `a..=b` or `.step_by(k)`,
/// are not yet recognized.
///
/// Loops with several `continue` paths are supported. Full `#[unroll]` also
/// preserves `break` paths and multiple exit targets. Partial `#[unroll(N)]`
Expand Down
18 changes: 11 additions & 7 deletions cuda-oxide/crates/cuda-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,8 +418,10 @@ pub fn cuda_module(attr: TokenStream, item: TokenStream) -> TokenStream {
/// `generic_const_exprs` feature. Partial factors must be in `2..=1024`; an
/// invalid specialization fails compilation instead of becoming a no-op.
///
/// The pass currently recognizes explicit counted `while` loops. Range-based
/// `for` loops are not yet recognized.
/// The pass currently recognizes explicit counted `while` loops and range `for`
/// loops (`for i in a..b` and `(a..b).rev()`) over any integer counter,
/// including `isize`. Other iterator loops, such as `a..=b` or `.step_by(k)`,
/// are not yet recognized.
///
/// Only the annotated loop is unrolled. Inner loops are copied intact unless
/// they carry their own annotation. Several `continue` paths (multiple
Expand Down Expand Up @@ -817,11 +819,13 @@ pub fn cooperative_launch(attr: TokenStream, item: TokenStream) -> TokenStream {
/// # Loop unrolling
///
/// Loop annotations work the same way in device function definitions as they do
/// in kernels. Use an explicit counted `while` loop; range-based `for` loops are
/// not yet recognized. Partial factors must be `N >= 2`. Multiple `continue`
/// paths are supported; full unrolling preserves `break` and multiple exit
/// targets. Partial unrolling requires a positive counter step, a `<` or `<=`
/// test, an unchanging limit, and no exit besides the normal header test.
/// in kernels. Use an explicit counted `while` loop or a range `for` loop
/// (`for i in a..b` or `(a..b).rev()`, over any integer counter including
/// `isize`); other iterator loops are not yet recognized. Partial
/// factors must be `N >= 2`. Multiple `continue` paths are supported; full
/// unrolling preserves `break` and multiple exit targets. Partial unrolling
/// requires a positive counter step, a `<` or `<=` test, an unchanging limit,
/// and no exit besides the normal header test.
///
/// One annotation may create at most 1,024 body copies, 8,192 cloned basic
/// blocks, and 65,536 cloned operations. Factors above 1,024 are rejected;
Expand Down
11 changes: 11 additions & 0 deletions cuda-oxide/crates/mir-importer/src/translator/rvalue/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,17 @@ pub fn translate_rvalue(

let result_type = types::translate_type(ctx, ty)?;

// A cast whose source and target lower to the same dialect type
// changes nothing. `isize` and `i64` are that pair on this target:
// core steps an `isize` with `overflowing_add(self as i64, rhs as
// i64)` and casts the sum back. Leaving those casts in the step
// block hides the range `for` from the unroller. Return the operand
// and emit no operation, as the reborrow path in this function does
// when its transmute would be between identical types.
if operand_val.get_type(ctx) == result_type {
return Ok((None, operand_val, prev_op_after_operand));
}

let op = Operation::new(
ctx,
MirCastOp::get_concrete_op_info(),
Expand Down
6 changes: 3 additions & 3 deletions cuda-oxide/crates/mir-transforms/src/analyses/induction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub enum CmpPred {
impl CmpPred {
/// The opposite test: the one that is true exactly when this one is false.
/// (`<` becomes `>=`, and so on.)
fn negate(self) -> CmpPred {
pub(crate) fn negate(self) -> CmpPred {
match self {
CmpPred::Lt => CmpPred::Ge,
CmpPred::Le => CmpPred::Gt,
Expand Down Expand Up @@ -191,7 +191,7 @@ pub(crate) fn edge_operands(
/// value underneath and whether the number peeled off was odd (so `!!x` reports
/// "not negated" and `!x` reports "negated"). Used so a guard written `!(i < n)`
/// is understood the same as `i >= n`.
fn unwrap_not(ctx: &Context, mut v: Value) -> (Value, bool) {
pub(crate) fn unwrap_not(ctx: &Context, mut v: Value) -> (Value, bool) {
let mut negated = false;
while let Some(def) = v.defining_op() {
if Operation::get_op::<MirNotOp>(def, ctx).is_some() {
Expand All @@ -206,7 +206,7 @@ fn unwrap_not(ctx: &Context, mut v: Value) -> (Value, bool) {

/// If `op` is a comparison (`<`, `<=`, `>`, `>=`), return which one it is and
/// its two sides (left, right); `None` for any other op.
fn match_cmp(ctx: &Context, op: Ptr<Operation>) -> Option<(CmpPred, Value, Value)> {
pub(crate) fn match_cmp(ctx: &Context, op: Ptr<Operation>) -> Option<(CmpPred, Value, Value)> {
let pred = if Operation::get_op::<MirLtOp>(op, ctx).is_some() {
CmpPred::Lt
} else if Operation::get_op::<MirLeOp>(op, ctx).is_some() {
Expand Down
Loading
Loading