update Singeli submodule, match{} → same{}

This commit is contained in:
dzaima 2023-06-29 15:19:50 +03:00
parent a67a19dd0b
commit 5c7934387a
8 changed files with 32 additions and 31 deletions

@ -1 +1 @@
Subproject commit 3b1f6937bce4243aa511c8efa621c26f4778d24d
Subproject commit 29ad697ae528032b76403275d9cf9f09c7918927

View File

@ -4,6 +4,7 @@ include 'util/kind'
oper ~~ reinterpret infix right 55
oper ** broadcast infix right 55
def same = is
def Size = u64
def load{x} = *x
def reinterpret{T, x:X & T==X} = x
@ -49,11 +50,12 @@ def unreachable{} = emit{void, 'si_unreachable'}
def assert{x:u1} = { if (not x) emit{void, 'si_unreachable'} }
# various checks
def oneType{{h:H, ...t}} = {
each{{c:C} => assert{C==H}, t}
H
def oneVal{{h, ...t}} = {
each{{c} => assert{c==h}, t}
h
}
def oneType{{}} = {}
def oneVal{{}} = {}
def oneType{x} = oneVal{each{type, x}}
def isreg = kreg
def isconst = kcon
@ -62,9 +64,9 @@ def istup = ktup
def isunsigned{T} = isint{T} & ~issigned{T}
def isvec {T} = 0; def isvec {T & istype{T}} = match{typekind{T},'vector'}
def isprim{T} = 0; def isprim{T & istype{T}} = match{typekind{T},'primitive'}
def isptr {T} = 0; def isptr {T & istype{T}} = match{typekind{T},'pointer'}
def isvec {T} = 0; def isvec {T & istype{T}} = same{typekind{T},'vector'}
def isprim{T} = 0; def isprim{T & istype{T}} = same{typekind{T},'primitive'}
def isptr {T} = 0; def isptr {T & istype{T}} = same{typekind{T},'pointer'}
def anyNum{x} = isconst{x} | knum{x}

View File

@ -23,15 +23,15 @@ fn cmpIX(dst:*u64, len:Size, x:u64, v:u1) : void = {
fillbits{dst, len, v&~nan, x}
}
def eqne{op} = match{op,__eq}|match{op,__ne}
def eqne{op} = same{op,__eq}|same{op,__ne}
def pathAS{dst, len, T, op, x & issigned{T}} = {
def R{f & eqne{op}} = {
if (rare{floor{f}!=f}) fillbits{dst, len, op{0,1}, x} # also includes check for NaN/sNaN
ftrunc{i64,f}
}
def R{f & match{op,__lt}|match{op,__ge}} = ftrunc{i64,ceil{f}}
def R{f & match{op,__gt}|match{op,__le}} = ftrunc{i64,floor{f}}
def R{f & same{op,__lt}|same{op,__ge}} = ftrunc{i64,ceil{f}}
def R{f & same{op,__gt}|same{op,__le}} = ftrunc{i64,floor{f}}
xf:f64 = interp_f64{x}
xi64:i64 = R{xf}
@ -126,7 +126,7 @@ def table{aa, F, w, G_bit, G_vec} = {
tup{
G_bit{},
...each{{E}=>{
def E2 = (if (aa and isunsigned{E} and ((match{F,__eq} | match{F,__ne}) | (E==u32))) {ty_s{E}} else E)
def E2 = (if (aa and isunsigned{E} and ((same{F,__eq} | same{F,__ne}) | (E==u32))) {ty_s{E}} else E)
def bulk = w/width{E2}
G_vec{[bulk]E2, max{tern{hasarch{'AARCH64'},2,1}, 8/bulk}}
}, tup{i8, i16, i32, f64, u8, u16, u32}}

View File

@ -36,13 +36,13 @@ def arithChk1{F==__sub, M, w:T, x:T, r:T & isvec{T} & tern{hasarch{'X86_64'}, el
def arithChk2{F, M, w:T, x:T & is_s{T} & (match{F,__add} | match{F,__sub})} = {
def arithChk2{F, M, w:T, x:T & is_s{T} & (same{F,__add} | same{F,__sub})} = {
r:= F{w,x}
tup{r, arithChk1{F, M, w, x, r}}
}
# ×
def arithChk2{F, M, w:T, x:T & match{F,__mul} & isvec{T} & i8==eltype{T} & hasarch{'X86_64'}} = {
def arithChk2{F, M, w:T, x:T & same{F,__mul} & isvec{T} & i8==eltype{T} & hasarch{'X86_64'}} = {
def wp = unpackQ{w, T ~~ (T**0 > w)}
def xp = unpackQ{x, T ~~ (T**0 > x)}
def rp = each{__mul, wp, xp}
@ -55,12 +55,12 @@ def arithChk2{F, M, w:T, x:T & match{F,__mul} & isvec{T} & i8==eltype{T} & hasar
tup{packQ{rp}, tup{'~andAllZero', RU~~tree_fold{|, bad}, RU**0xff80}}
}
}
def arithChk2{F, M, w:T, x:T & match{F,__mul} & isvec{T} & i16==eltype{T} & hasarch{'X86_64'}} = {
def arithChk2{F, M, w:T, x:T & same{F,__mul} & isvec{T} & i16==eltype{T} & hasarch{'X86_64'}} = {
rl:= __mul {w,x}
rh:= __mulhi{w,x}
tup{rl, tup{'anyne', rh, rl>>15}}
}
def arithChk2{F, M, w:T, x:T & match{F,__mul} & isvec{T} & i32==eltype{T} & hasarch{'X86_64'}} = {
def arithChk2{F, M, w:T, x:T & same{F,__mul} & isvec{T} & i32==eltype{T} & hasarch{'X86_64'}} = {
max:= to_el{f32, (ty_u{T})**0x4efffffe}
def cf32{x:X} = emit{to_el{f32,X}, tern{T==[8]i32, '_mm256_cvtepi32_ps', '_mm_cvtepi32_ps'}, x}
f32mul:= cf32{w} * cf32{x}
@ -77,7 +77,7 @@ def arithChk2{F, M, w:T, x:T & match{F,__mul} & isvec{T} & i32==eltype{T} & hasa
# tup{packQQ{each{{v} => v & T2**0xFFFFFFFF, rp}}, tup{'homAny', tree_fold{|,bad}}} this doesn't use M
}
def arithChk2{F, M, w:T, x:T & match{F,__mul} & isvec{T} & hasarch{'AARCH64'}} = {
def arithChk2{F, M, w:T, x:T & same{F,__mul} & isvec{T} & hasarch{'AARCH64'}} = {
def r12 = mul12{w, x}
rl:= packLo{r12}
rh:= packHi{r12}
@ -108,7 +108,7 @@ def runner{u, R, F} = {
}
def run{F==__add, M, w:VS, x:VU & is_s{VS} & is_u{VU}} = run{F, M, x, w} # 3+'a' → 'a'+3
def run{F, M, w:VW, x:VX & c & R==u32 & (match{F,__add} | match{F,__sub})} = { # 'a'+1, 'a'-1
def run{F, M, w:VW, x:VX & c & R==u32 & (same{F,__add} | same{F,__sub})} = { # 'a'+1, 'a'-1
r:= F{ty_u{w}, ty_u{x}}
tup{to_el{R, VW}~~r, tup{'homAny', M{r > type{r}**1114111}}}
}
@ -133,8 +133,7 @@ def runChecks{type=='anyne', vals, M} = {
def arithProcess{F, run, overflow, M, is, cw, cx, TY} = {
def {values, checks} = flip{each{{w1, x1} => run{F, M, w1, x1}, cw, cx}}
def ctype = tupsel{0,tupsel{0,checks}}
assert{tree_fold{&, each{{c}=>match{ctype, tupsel{0,c}}, checks}}}
def ctype = oneVal{each{{c}=>tupsel{0,c}, checks}}
if (rare{runChecks{ctype, checks, M}}) overflow{tupsel{0,is}*vcount{TY}}
each{{c} => TY~~c, values}
}
@ -145,7 +144,7 @@ def arithAAimpl{vw, mode, F, W, X, R, w, x, r, len} = {
def bulk = vw/64
def VT = [bulk]u64
@maskedLoop{bulk}(r in tup{'g',*u64~~r}, cw in tup{VT,*u64~~w}, cx in tup{VT,*u64~~x} over cdiv{len, 64}) r{F{cw,cx}}
} else if (match{F,__mul} and W!=u1 and X==u1 and W==R) { # 0‿1‿1‿1‿1‿0‿1‿1×3‿1‿4‿1‿5‿9‿2‿6
} else if (same{F,__mul} and W!=u1 and X==u1 and W==R) { # 0‿1‿1‿1‿1‿0‿1‿1×3‿1‿4‿1‿5‿9‿2‿6
def bulk = vw / width{W}
def TU = ty_u{R}
def TV = [bulk]TU
@ -158,7 +157,7 @@ def arithAAimpl{vw, mode, F, W, X, R, w, x, r, len} = {
def overflow = tern{mode==1, {i}=>return{i}, tern{mode==2, {i}=>return{1}, 0}}
def TY = [bulk]R
def run = runner{match{overflow, 0}, R, F}
def run = runner{same{overflow, 0}, R, F}
def unr = tern{mode==0, 2, 1} # 2x unroll non-overflowing cases; suppresses clang's default unrolling, which unrolls a lot more; 2x appears to be plenty
@muLoop{bulk, unr}(sr in tup{'g',*R~~r}, cw in tup{ty_sc{W,TY},*W~~w}, cx in tup{ty_sc{X,TY},*X~~x}, M in 'm' over is to len) {

View File

@ -70,8 +70,8 @@ def storeBatch{ptr:P, ns, xs, M & istup{ns}} = each{{n,x} => storeBatch{ptr, n,
# "harmless" pointer cast that'll only cast void*
def hCast{T,p} = assert{show{'expected pointer with element',T,'or void but got ',p}}
def hCast{T,p:P & match{T,eltype{P}}} = p
def hCast{T,p:P & match{P,*void}} = *T~~p
def hCast{T,p:P & same{T,eltype{P}}} = p
def hCast{T,p:P & same{P,*void}} = *T~~p
# masked loop arguments
# p:*T - regular pointer, loaded by the batch index(es)

View File

@ -8,7 +8,7 @@ def nvecu = genchk{nvec, {T} => isunsigned{T}}
def nvecf = genchk{nvec, {T} => isfloat{T}}
def reinterpret{T, v & match{'pointer',typekind{T}} & ktup{v}} = { tmp:T=v }
def reinterpret{T, v & same{'pointer',typekind{T}} & ktup{v}} = { tmp:T=v }
def nty{T== u8} = 'u8'; def nty{T== i8} = 's8'
def nty{T==u16} = 'u16'; def nty{T==i16} = 's16'
@ -89,9 +89,9 @@ def fold_add {a:T & nvec{T}} = emit{eltype{T}, ntyp{'vaddv', T}, a}
def fold_addw{a:T & nveci{T}} = emit{ty_dbl{eltype{T}}, ntyp{'vaddlv', T}, a}
def fold_min {a:T & nvec{T} & ~nveci{T,64}} = emit{eltype{T}, ntyp{'vminv', T}, a}
def fold_max {a:T & nvec{T} & ~nveci{T,64}} = emit{eltype{T}, ntyp{'vmaxv', T}, a}
def vfold{F, x:T & nvec{T} & ~nveci{T,64} & match{F, min}} = fold_min{x}
def vfold{F, x:T & nvec{T} & ~nveci{T,64} & match{F, max}} = fold_max{x}
def vfold{F, x:T & nvec{T} & match{F, +}} = fold_add{x}
def vfold{F, x:T & nvec{T} & ~nveci{T,64} & same{F, min}} = fold_min{x}
def vfold{F, x:T & nvec{T} & ~nveci{T,64} & same{F, max}} = fold_max{x}
def vfold{F, x:T & nvec{T} & same{F, +}} = fold_add{x}
# TODO don't rely on regular stores being unaligned
local def storeu{ptr:P, e:T} = store{ptr, 0, e}

View File

@ -72,7 +72,7 @@ export{'avx2_scan_min_init_f64', avx2_scan_idem{f64, min}}; export{'avx2_scan_ma
fn avx2_scan_idem_id{T, op}(x:*T, r:*T, len:u64) : void = {
def m = 1 << (width{T}-1)
def id = (if (match{op,min}) m-1; else -m)
def id = (if (same{op,min}) m-1; else -m)
avx2_scan_idem{T, op}(x, r, len, id)
}
export{'avx2_scan_min_i8', avx2_scan_idem_id{i8 , min}}; export{'avx2_scan_max_i8', avx2_scan_idem_id{i8 , max}}

View File

@ -156,7 +156,7 @@ def do_bittab{x0:*void, n:u64, tab:*void, u:u8, t, mode, r0} = {
def rval = mode == 'unique'
def rind = mode == 'index'
def storebit{i, v:T} = if (rbit) store{*T~~r0, i, v}
if (rbit or rval) assert{match{t,0}}
if (rbit or rval) assert{same{t,0}}
btab:= *i8~~tab
def settab_sub{x, v, i} = {
@ -204,7 +204,7 @@ def do_bittab{x0:*void, n:u64, tab:*void, u:u8, t, mode, r0} = {
i0:= i; iw:= i/k
v:= load{xv, iw}
m:= bitsel{v} # Mask of possibly-new values
if (not match{t,0}) m^= uk~~promote{ik, t}
if (not same{t,0}) m^= uk~~promote{ik, t}
i+= k
if (i > n) m&= (~uk~~0)>>((-n)%k)
# Any new values?