diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index 755a2d6a..96832e7b 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -296,6 +296,7 @@ B select_c2(B t, B w, B x) { else if (TI(w,elType)==el_i16) TYPE(i16) else if (TI(w,elType)==el_i32) TYPE(i32) else { + SLOW2("π•¨βŠπ•©", w, x); usz i=0; HArr_p r = m_harrs(wia, &i); SGetU(w) for (; i < wia; i++) { @@ -309,6 +310,7 @@ B select_c2(B t, B w, B x) { } #undef CASE } else { + SLOW2("π•¨βŠπ•©", w, x); SGetU(w) ur wr = rnk(w); i32 rr = wr+xr-1; @@ -339,24 +341,23 @@ B select_c2(B t, B w, B x) { return c2(rt_select, w, x); } -static NOINLINE B slash_c1R(B x, u64 s) { - usz xia = a(x)->ia; - SGetU(x) - f64* rp; B r = m_f64arrv(&rp, s); usz ri = 0; - for (usz i = 0; i < xia; i++) { - usz c = o2s(GetU(x, i)); - for (usz j = 0; j < c; j++) rp[ri++] = i; - } - dec(x); - return r; -} extern B rt_slash; B slash_c1(B t, B x) { if (RARE(isAtm(x)) || RARE(rnk(x)!=1)) thrF("/: Argument must have rank 1 (%H ≑ ≒𝕩)", x); i64 s = isum(x); if(s<0) thrM("/: Argument must consist of natural numbers"); usz xia = a(x)->ia; - if (RARE(xia>=I32_MAX)) return slash_c1R(x, s); + if (RARE(xia>=I32_MAX)) { + usz xia = a(x)->ia; + SGetU(x) + f64* rp; B r = m_f64arrv(&rp, s); usz ri = 0; + for (usz i = 0; i < xia; i++) { + usz c = o2s(GetU(x, i)); + for (usz j = 0; j < c; j++) rp[ri++] = i; + } + dec(x); + return r; + } i32* rp; B r = m_i32arrv(&rp, s); u8 xe = TI(x,elType); if (xe==el_i8) { @@ -386,6 +387,7 @@ B slash_c1(B t, B x) { } } } else { + SLOW1("/𝕩", x); SGetU(x) for (u64 i = 0; i < xia; i++) { usz c = o2s(GetU(x, i)); @@ -442,6 +444,7 @@ B slash_c2(B t, B w, B x) { if (TI(w,elType)==el_i32) TYPED(i32,31); #undef TYPED #undef CASE + SLOW2("𝕨/𝕩", w, x); i64 ria = isum(w); if (ria>USZ_MAX) thrOOM(); HArr_p r = m_harrs(ria, &ri); @@ -822,6 +825,7 @@ B group_c2(B t, B w, B x) { dec(w); dec(x); TFREE(lenO); TFREE(pos); return taga(r); } else { + SLOW2("π•¨βŠ”π•©", w, x); SGetU(w) i64 ria = wia==xia? 0 : o2i64(GetU(w, xia)); if (ria<-1) thrM("βŠ”: 𝕨 can't contain elements less than Β―1"); @@ -886,6 +890,7 @@ B reverse_c1(B t, B x) { dec(x); return r; } + SLOW1("βŒ½π•©", x); usz csz = arr_csz(x); usz cam = a(x)->sh[0]; usz rp = 0; @@ -1003,6 +1008,7 @@ B select_ucw(B t, B o, B w, B x) { for (i64 i = 0; i < xia; i++) set[i] = false; #define EQ(F) if (set[cw] && (F)) thrM("π”½βŒΎ(a⊸⊏): Incompatible result elements"); set[cw] = true; #define FREE_CHECK TFREE(set) + SLOWIF(xia>100 && wia100 && wiap); } void slice_print(B x) { arr_print(x); } char* type_repr(u8 u) { - switch(u) { default: return"(unknown type)"; + switch(u) { default: return "(unknown type)"; #define F(X) case t_##X: return #X; FOR_TYPE(F) #undef F } } +char* eltype_repr(u8 u) { + switch(u) { default: return "(bad elType)"; + case el_bit: return "el_bit"; case el_f64: return "el_f64"; case el_B: return "el_B"; + case el_i8: return "el_i8"; case el_c8: return "el_c8"; + case el_i16: return "el_i16"; case el_c16: return "el_c16"; + case el_i32: return "el_i32"; case el_c32: return "el_c32"; + } +} bool isPureFn(B x) { // doesn't consume if (isCallable(x)) { if (isPrim(x)) return true; @@ -715,3 +730,19 @@ NOINLINE void printAllocStats() { err(""); } #endif +#if WARN_SLOW==1 + BBB2B ptr; + static void warn_ln(B x) { + if (isArr(x)) print_fmt("%s items, %S, shape=%H\n", a(x)->ia, eltype_repr(TI(x,elType)), x); + else printf("not array\n"); + } + void warn_slow1(char* s, B x) { + if (isArr(x) && a(x)->ia<100) return; + printf("slow %s: ", s); warn_ln(x); + } + void warn_slow2(char* s, B w, B x) { + if ((isArr(w)||isArr(x)) && (!isArr(x) || a(x)->ia<50) && (!isArr(x) || a(x)->ia<50)) return; + printf("slow %s:\n 𝕨: ", s); warn_ln(w); + printf(" 𝕩: "); warn_ln(x); + } +#endif diff --git a/src/core/stuff.h b/src/core/stuff.h index 756b5024..7ec9aa16 100644 --- a/src/core/stuff.h +++ b/src/core/stuff.h @@ -125,6 +125,7 @@ i32 num_fmt(char buf[30], f64 x); #define NUM_FMT_BUF(N,X) char N[30]; num_fmt(N, X); B append_fmt(B s, char* p, ...); B make_fmt(char* p, ...); +void print_fmt(char* p, ...); #define AJOIN(X) s = vec_join(s,X) // consumes X #define AOBJ(X) s = vec_add(s,X) // consumes X #define ACHR(X) AOBJ(m_c32(X)) @@ -138,6 +139,7 @@ char* type_repr(u8 u); char* pfn_repr(u8 u); char* pm1_repr(u8 u); char* pm2_repr(u8 u); +char* eltype_repr(u8 u); bool isPureFn(B x); // doesn't consume B bqn_merge(B x); // consumes @@ -252,7 +254,6 @@ static inline void onFree(Value* x) { // x->refc = 0x61616161; } - extern _Thread_local i64 comp_currEnvPos; extern _Thread_local B comp_currPath; extern _Thread_local B comp_currArgs; diff --git a/src/h.h b/src/h.h index 204cb39f..a995045b 100644 --- a/src/h.h +++ b/src/h.h @@ -247,6 +247,17 @@ typedef struct Arr { #define VALIDATEP(x) (x) #define UD __builtin_unreachable(); #endif +#if WARN_SLOW==1 + void warn_slow1(char* s, B x); + void warn_slow2(char* s, B w, B x); + #define SLOW1(S, X) warn_slow1(S, X) + #define SLOW2(S, W, X) warn_slow2(S, W, X) + #define SLOWIF(C) if(C) +#else + #define SLOW1(S, X) + #define SLOW2(S, W,X) + #define SLOWIF(C) +#endif // memory manager typedef void (*V2v)(Value*); diff --git a/src/utils/each.h b/src/utils/each.h index 16de2637..a4aa68fc 100644 --- a/src/utils/each.h +++ b/src/utils/each.h @@ -152,6 +152,7 @@ static B eachd(B f, B w, B x) { // complete w FΒ¨ x without fills #if CATCH_ERRORS static inline B arith_recd(BBB2B f, B w, B x) { + SLOWIF((!isArr(w) || TI(w,elType)!=el_B) && (!isArr(x) || TI(x,elType)!=el_B)) SLOW2("arith", w, x); B fx = getFillQ(x); if (noFill(fx)) return eachd_fn(f, bi_N, w, x); B fw = getFillQ(w);