aboutsummaryrefslogtreecommitdiff
path: root/cbits
diff options
context:
space:
mode:
authorTom Smeding <tom@tomsmeding.com>2025-02-16 23:49:56 +0100
committerTom Smeding <tom@tomsmeding.com>2025-02-16 23:50:07 +0100
commit71908c23307952fac26a4e24066e064d9cbb71c0 (patch)
tree6bcb91ff66d0c6623c36ed965514d06e76585a14 /cbits
parentc14017f4bc28951be7e298d01769b5b49384a7c3 (diff)
arith: Only strided unary int ops
This should have negligible overhead and will save a whole bunch of C code duplication when the FUnops are also converted to strided form.
Diffstat (limited to 'cbits')
-rw-r--r--cbits/arith.c26
1 files changed, 10 insertions, 16 deletions
diff --git a/cbits/arith.c b/cbits/arith.c
index f08e456..6ea197d 100644
--- a/cbits/arith.c
+++ b/cbits/arith.c
@@ -113,7 +113,7 @@ static void print_shape(FILE *stream, i64 rank, const i64 *shape) {
// Provides idx, outlinidx, arrlinidx.
#define TARRAY_WALK_NOINNER(again_label_name, rank, shape, strides, body) \
do { \
- i64 idx[(rank) - 1]; \
+ i64 idx[(rank) /* - 1 */]; /* Note: [zero-length VLA] */ \
memset(idx, 0, ((rank) - 1) * sizeof(idx[0])); \
i64 arrlinidx = 0; \
i64 outlinidx = 0; \
@@ -138,7 +138,7 @@ static void print_shape(FILE *stream, i64 rank, const i64 *shape) {
// Provides idx, outlinidx, arrlinidx1, arrlinidx2.
#define TARRAY_WALK2_NOINNER(again_label_name, rank, shape, strides1, strides2, body) \
do { \
- i64 idx[(rank) - 1]; \
+ i64 idx[(rank) /* - 1 */]; /* Note: [zero-length VLA] */ \
memset(idx, 0, ((rank) - 1) * sizeof(idx[0])); \
i64 arrlinidx1 = 0, arrlinidx2 = 0; \
i64 outlinidx = 0; \
@@ -433,16 +433,6 @@ enum unop_tag_t {
#define LIST_UNOP(name, id, _)
};
-#define ENTRY_UNARY_OPS(typ) \
- void oxarop_unary_ ## typ(enum unop_tag_t tag, i64 n, typ *out, const typ *x) { \
- switch (tag) { \
- case UO_NEG: oxarop_op_neg_ ## typ(n, out, x); break; \
- case UO_ABS: oxarop_op_abs_ ## typ(n, out, x); break; \
- case UO_SIGNUM: oxarop_op_signum_ ## typ(n, out, x); break; \
- default: wrong_op("unary", tag); \
- } \
- }
-
#define ENTRY_UNARY_STRIDED_OPS(typ) \
void oxarop_unary_ ## typ ## _strided(enum unop_tag_t tag, i64 rank, typ *out, const i64 *shape, const i64 *strides, const typ *x) { \
switch (tag) { \
@@ -526,9 +516,6 @@ enum redop_tag_t {
COMM_OP(add, +, typ) \
NONCOMM_OP(sub, -, typ) \
COMM_OP(mul, *, typ) \
- UNARY_OP(neg, -, typ) \
- UNARY_OP(abs, GEN_ABS, typ) \
- UNARY_OP(signum, GEN_SIGNUM, typ) \
UNARY_OP_STRIDED(neg, -, typ) \
UNARY_OP_STRIDED(abs, GEN_ABS, typ) \
UNARY_OP_STRIDED(signum, GEN_SIGNUM, typ) \
@@ -537,7 +524,6 @@ enum redop_tag_t {
REDUCEFULL_OP(sumfull, +, typ) \
REDUCEFULL_OP(productfull, *, typ) \
ENTRY_BINARY_OPS(typ) \
- ENTRY_UNARY_OPS(typ) \
ENTRY_UNARY_STRIDED_OPS(typ) \
ENTRY_REDUCE1_OPS(typ) \
ENTRY_REDUCEFULL_OPS(typ) \
@@ -552,6 +538,7 @@ NUM_TYPES_XLIST
NONCOMM_OP(fdiv, /, typ) \
PREFIX_BINOP(pow, GEN_POW, typ) \
PREFIX_BINOP(logbase, GEN_LOGBASE, typ) \
+ /* TODO: when replaced with UNARY_OP_STRIDED, remove UNARY_OP entirely */ \
UNARY_OP(recip, 1.0/, typ) \
UNARY_OP(exp, GEN_EXP, typ) \
UNARY_OP(log, GEN_LOG, typ) \
@@ -576,3 +563,10 @@ NUM_TYPES_XLIST
ENTRY_FUNARY_OPS(typ)
FLOAT_TYPES_XLIST
#undef X
+
+// Note: [zero-length VLA]
+//
+// Zero-length variable-length arrays are not allowed in C(99). Thus whenever we
+// have a VLA that could sometimes suffice to be empty (e.g. `idx` in the
+// TARRAY_WALK_NOINNER macros), we tweak the length formula (typically by just
+// adding 1) so that it never ends up empty.