use std::num::NonZeroU32;
use std::sync::atomic::{AtomicU32, Ordering};
pub(in crate::ir) type ValueId = NonZeroU32;
const GLOBAL_VALUE_ID_STARTS_FROM: ValueId = NonZeroU32::new(1).unwrap();
const LOCAL_VALUE_ID_STARTS_FROM: ValueId = NonZeroU32::new(0x40000000).unwrap();
pub(in crate::ir) type BasicBlockId = NonZeroU32;
const BB_ID_STARTS_FROM: BasicBlockId = NonZeroU32::new(1).unwrap();
pub(in crate::ir) type FunctionId = NonZeroU32;
const FUNC_ID_STARTS_FROM: FunctionId = NonZeroU32::new(1).unwrap();
pub(in crate::ir) fn next_global_value_id() -> ValueId {
static NEXT_GLOBAL_VALUE_ID: AtomicU32 = AtomicU32::new(GLOBAL_VALUE_ID_STARTS_FROM.get());
let id = NEXT_GLOBAL_VALUE_ID.fetch_add(1, Ordering::Relaxed);
unsafe { NonZeroU32::new_unchecked(id) }
}
pub(in crate::ir) fn next_local_value_id() -> ValueId {
static NEXT_LOCAL_VALUE_ID: AtomicU32 = AtomicU32::new(LOCAL_VALUE_ID_STARTS_FROM.get());
let id = NEXT_LOCAL_VALUE_ID.fetch_add(1, Ordering::Relaxed);
unsafe { NonZeroU32::new_unchecked(id) }
}
pub(in crate::ir) fn is_global_id(value: ValueId) -> bool {
value >= GLOBAL_VALUE_ID_STARTS_FROM && value < LOCAL_VALUE_ID_STARTS_FROM
}
pub(in crate::ir) fn next_bb_id() -> BasicBlockId {
static NEXT_BB_ID: AtomicU32 = AtomicU32::new(BB_ID_STARTS_FROM.get());
let id = NEXT_BB_ID.fetch_add(1, Ordering::Relaxed);
unsafe { NonZeroU32::new_unchecked(id) }
}
pub(in crate::ir) fn next_func_id() -> FunctionId {
static NEXT_FUNC_ID: AtomicU32 = AtomicU32::new(FUNC_ID_STARTS_FROM.get());
let id = NEXT_FUNC_ID.fetch_add(1, Ordering::Relaxed);
unsafe { NonZeroU32::new_unchecked(id) }
}