is_pow2 helper
This commit is contained in:
parent
0ec37303ea
commit
98f1c97653
@ -21,6 +21,7 @@ def any_num = match { {x:T}=>primt{T}; {x} => knum{x} }
|
||||
def any_int = match { {x:T}=>isint{T}; {x} => knum{x} and (x>>0) == x }
|
||||
def int_idx{_, _} = 0
|
||||
def int_idx{k if knum{k}, l} = (k>>0)==k and k>=0 and k<l
|
||||
def is_pow2{i if any_int{i}} = (i & (i-1)) == 0
|
||||
def elwidth{T} = width{eltype{T}}
|
||||
|
||||
def reinterpret{T, x:T} = x
|
||||
|
||||
@ -239,7 +239,7 @@ fn extract_column(x0:*void, r0:*void, n:usz, l:usz, el:u8) : usz = {
|
||||
def thr = __min{vl+2, 20}
|
||||
if ((not has_simd) or n < vl or l > usz~~thr>>el or l<<el >= thr) return{0}
|
||||
nv := n / vl
|
||||
if (has_simd and (l & (l-1)) == 0) {
|
||||
if (has_simd and is_pow2{l}) {
|
||||
def try_unzip{T, k} = if (k < thr and l == k) {
|
||||
extract_column_pow2{T, x0, r0, nv, k}
|
||||
goto{'ret'}
|
||||
@ -320,7 +320,7 @@ def fold_rows_bit_lt64{
|
||||
# To move size-a groups spaced at distance b together,
|
||||
# the multiplier has up to b/a bits spaced by b-a.
|
||||
dm:= cast_i{usz, popc{el}} # minimum output bits per word
|
||||
dm-= promote{usz, l&(l-1) == 0} # for divisors of 64, e0 effectively overflows; subtract 1 to correct
|
||||
dm-= promote{usz, is_pow2{l}} # for divisors of 64, e0 effectively overflows; subtract 1 to correct
|
||||
def loop{...par} = {
|
||||
et:= e0 << clz{e0}
|
||||
@for (xo in xp over nw) {
|
||||
|
||||
@ -556,7 +556,7 @@ fn scan_rows_andor{id}(src:*u64, dst:*u64, nl:usz, l:usz) : void = {
|
||||
if (qand) s & (~f | c) else s | (f & c)
|
||||
}
|
||||
if (l < 64) {
|
||||
if ((l & (l-1)) == 0) {
|
||||
if (is_pow2{l}) {
|
||||
if (l == 2) {
|
||||
@for (r in dst, x in src over nw) {
|
||||
r = (if (qand) x & (x<<1 | 64w2b01) else x | (x<<1 & 64w2b10))
|
||||
@ -637,7 +637,7 @@ fn scan_rows_neq(x:*u64, r:*u64, nl:usz, l:usz) : void = {
|
||||
b:= s<<1 & m # last bit of previous row
|
||||
s ^ (b<<l - b)
|
||||
}
|
||||
if ((l & (l-1)) == 0) {
|
||||
if (is_pow2{l}) {
|
||||
m:u64 = aligned_spaced_mask{l}
|
||||
@for (r, x over nw) r = apply_mask{scan_word{x}, m}
|
||||
} else if (has_simd) {
|
||||
@ -690,7 +690,7 @@ fn scan_rows_left(x:*u64, r:*u64, nl:usz, l:usz) : void = {
|
||||
def apply_carry{s, c, f} = s | (f & c)
|
||||
if (l < 64) {
|
||||
def apply_mask{x, m} = { b:= x & m; b<<l - b }
|
||||
if ((l & (l-1)) == 0) {
|
||||
if (is_pow2{l}) {
|
||||
m:u64 = aligned_spaced_mask{l}
|
||||
@for (r, x over nw) r = apply_mask{x, m}
|
||||
} else if (has_simd) {
|
||||
@ -740,7 +740,7 @@ fn scan_stride_bool_assoc{op}(x:*u64, r:*u64, nl:usz, l:usz) : void = {
|
||||
def {flip,opf} = if (same{op, &}) tup{~,|} else tup{{x}=>x,op} # such that identity of opf is 0
|
||||
nw:= cdiv{nl, 64}
|
||||
if (l <= 64) {
|
||||
if (same{op, ^} and hasarch{'PCLMUL'} and (l & (l-1)) == 0) {
|
||||
if (same{op, ^} and hasarch{'PCLMUL'} and is_pow2{l}) {
|
||||
clmul_scan_ne_any{}(*void~~x, *void~~r, 0, nw, aligned_spaced_mask{l})
|
||||
return{}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ def spaced_mask_of{l} = emit{u64, 'get_spaced_mask', l} # see slash.singeli
|
||||
|
||||
def aligned_spaced_mask{l} = {
|
||||
assert{l <= 64}
|
||||
assert{l&(l-1) == 0}
|
||||
assert{is_pow2{l}}
|
||||
spaced_mask_of{l}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user