summaryrefslogtreecommitdiff
path: root/src/text_run.c
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-13 19:22:05 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-13 19:22:05 +0300
commit01e1c61e9fcf4a0b0164a7fe5395a209a50f6905 (patch)
tree1f1eb33e49eab338650a42e8f602af75d8d28a24 /src/text_run.c
parent2d02d39d2cd32e9eb559638865d2746f02c08556 (diff)
Optimize hot loops with direct access, LUTs, and closed-form formulas
Diffstat (limited to 'src/text_run.c')
-rw-r--r--src/text_run.c52
1 files changed, 30 insertions, 22 deletions
diff --git a/src/text_run.c b/src/text_run.c
index 3901cbe..9df7ac0 100644
--- a/src/text_run.c
+++ b/src/text_run.c
@@ -53,11 +53,19 @@ static TERM_MAYBE_UNUSED int width_run_find(uint32_t cp)
static TERM_MAYBE_UNUSED uint16_t width_cache_covers(const struct width_cache *wc,
const uint32_t *cp)
{
+ uint32_t lo0 = wc->lo[0], span0 = wc->span[0];
+ uint32_t lo1 = wc->lo[1], span1 = wc->span[1];
+ uint32_t lo2 = wc->lo[2], span2 = wc->span[2];
+ uint32_t lo3 = wc->lo[3], span3 = wc->span[3];
uint16_t covered = 0;
- for (int j = 0; j < TERM_WIDTH_SLOTS; j++)
- for (int l = 0; l < 16; l++)
- if (cp[l] - wc->lo[j] <= wc->span[j])
- covered |= (uint16_t)(1u << l);
+ for (int l = 0; l < 16; l++) {
+ uint32_t c = cp[l];
+ bool hit = ((c - lo0 <= span0) |
+ (c - lo1 <= span1) |
+ (c - lo2 <= span2) |
+ (c - lo3 <= span3));
+ covered |= (uint16_t)(hit << l);
+ }
return covered;
}
@@ -70,10 +78,8 @@ static TERM_MAYBE_UNUSED bool width_cache_extend(struct width_cache *wc, const u
uint8_t k = width_run_class[r];
if (k != 1 && k != 2) return false;
if (k != wc->klass) {
- for (int j = 0; j < TERM_WIDTH_SLOTS; j++) {
- wc->lo[j] = 0xFFFFFFFFu;
- wc->span[j] = 0;
- }
+ memset(wc->lo, 0xFF, sizeof(wc->lo));
+ memset(wc->span, 0, sizeof(wc->span));
wc->klass = k;
wc->next = 0;
}
@@ -140,10 +146,14 @@ TERM_TARGET_AVX512
static inline struct width_ranges width_ranges_load(const struct width_cache *wc)
{
struct width_ranges r;
- for (int j = 0; j < TERM_WIDTH_SLOTS; j++) {
- r.lo[j] = _mm512_set1_epi32((int)wc->lo[j]);
- r.span[j] = _mm512_set1_epi32((int)wc->span[j]);
- }
+ r.lo[0] = _mm512_set1_epi32((int)wc->lo[0]);
+ r.span[0] = _mm512_set1_epi32((int)wc->span[0]);
+ r.lo[1] = _mm512_set1_epi32((int)wc->lo[1]);
+ r.span[1] = _mm512_set1_epi32((int)wc->span[1]);
+ r.lo[2] = _mm512_set1_epi32((int)wc->lo[2]);
+ r.span[2] = _mm512_set1_epi32((int)wc->span[2]);
+ r.lo[3] = _mm512_set1_epi32((int)wc->lo[3]);
+ r.span[3] = _mm512_set1_epi32((int)wc->span[3]);
return r;
}
@@ -519,16 +529,14 @@ static inline int decode_3byte_quads(uint64_t **dst_io, const char *buf, int len
uint8_t k2 = unicode_fast_class[cp[2]], k3 = unicode_fast_class[cp[3]];
if (!k0 || !k1 || !k2 || !k3)
break;
- const uint8_t k[4] = { k0, k1, k2, k3 };
- for (int j = 0; j < 4; j++) {
- if (k[j] == 1) {
- dst = store_cell(dst, b, cp[j]);
- cx++;
- } else {
- dst = store_cell_wide(dst, b, cp[j]);
- cx += 2;
- }
- }
+ if (k0 == 1) { dst = store_cell(dst, b, cp[0]); cx++; }
+ else { dst = store_cell_wide(dst, b, cp[0]); cx += 2; }
+ if (k1 == 1) { dst = store_cell(dst, b, cp[1]); cx++; }
+ else { dst = store_cell_wide(dst, b, cp[1]); cx += 2; }
+ if (k2 == 1) { dst = store_cell(dst, b, cp[2]); cx++; }
+ else { dst = store_cell_wide(dst, b, cp[2]); cx += 2; }
+ if (k3 == 1) { dst = store_cell(dst, b, cp[3]); cx++; }
+ else { dst = store_cell_wide(dst, b, cp[3]); cx += 2; }
*last = cp[3];
i += 12;
}