perf(llvmlite): 窥孔 alloca 判定加首字符短路并消除逐行 strlen

_peep_is_alloc_of 增加首字符预筛、两个调用点同步加守卫,避免逐行乘逐槽的 strncmp 与函数调用(该点实测约 439 万次 strncmp)。

_peep_replace_token 预扫改为以 NUL 为界单趟扫描,strlen(line_buf) 后移到命中之后,无命中调用不再求长(该点实测约 134 万次 strlen)。均保持逐输入等价。
This commit is contained in:
TermiNexus committed 2026-09-14 08:21:37 +08:00
1 parent c4c6eafd70
commit c4fe8bd496
1 file changed
+14 -5
+14 -5
View File
@@ -694,15 +694,18 @@ def _peep_replace_token(pool: rowptr[memhub.MemBuddy],
return line_buf
if tlen == 0:
return line_buf
ln: t.CSizeT = string.strlen(line_buf)
# 预扫是否命中
# 预扫是否命中:不依赖 strlen,以 NUL 为界单趟扫描(绝大多数调用无命中即返回,
# 从而省去逐行 strlen)。逐输入等价:tok 无 NUL(tlen=strlen(tok)),故
# strncmp 判等必蕴含记号完整落在串内(i+tlen 处仍非 NUL);凡 i+tlen>ln 的
# 位置 strncmp 必先遇到 line_buf 的 NUL 而与 tok 的非 NUL 字节不等,故原
# 上界 i+tlen<=ln 从未排除任一可能命中,去掉后命中判定不变。
hit: int = 0
i: t.CSizeT = 0
while i + tlen <= ln:
while line_buf[i] != '\0':
if line_buf[i] == '%' and line_buf[i + 1] == tok[0] \
and string.strncmp(line_buf + i + 1, tok, tlen) == 0:
nxt: int = 0
if i + 1 + tlen < ln:
if line_buf[i + 1 + tlen] != '\0':
cc: int = line_buf[i + 1 + tlen]
if (cc >= 48 and cc <= 57) or (cc >= 65 and cc <= 90) or (cc >= 97 and cc <= 122) or cc == 95:
nxt = 1
@@ -712,6 +715,7 @@ def _peep_replace_token(pool: rowptr[memhub.MemBuddy],
i += 1
if hit == 0:
return line_buf
ln: t.CSizeT = string.strlen(line_buf)
# 缓冲大小上界:单行最多 ⌊ln/2⌋ 次替换,每次去掉 ≥2 字节(%+名)换入 rlen 字节;
# 最坏输出 ≤ ln + (ln/2)·rlen + NUL。ln + 1 + rlen·(ln+1) 恒覆盖该上界,
# 避免 K≥2 且替换串更长时把新缓冲写穿(随机内存破坏)。
@@ -801,6 +805,11 @@ def _peep_is_alloc_of(eb: str, a_name: str, nl: t.CSizeT) -> int:
"""
if eb is None or a_name is None or nl == 0 or eb[0] != '%':
return 0
# 首字符预筛:nl>=1,strncmp 判等必然蕴含首字符相等;首字符不同即可廉价拒绝,
# 避免绝大多数行进入 strncmp 调用。逐输入等价:本分支拒绝当且仅当原 strncmp
# 也必返回非 0(首字节不同)。eb[0]=='%' 非 NUL ⇒ eb[1] 读在串内(最多为 NUL)。
if eb[1] != a_name[0]:
return 0
if string.strncmp(eb + 1, a_name, nl) != 0:
return 0
eqpos: str = string.strstr(eb, " = alloca ")
@@ -997,7 +1006,7 @@ def _peephole_opt(func: rowptr[Function], pool: rowptr[memhub.MemBuddy]):
db: str = ld.Buf
if db is not None:
kill: int = 0
if db[0] == '%':
if db[0] == '%' and db[1] == a_name[0]:
if _peep_is_alloc_of(db, a_name, a_name_len) != 0:
kill = 1
if kill == 0 and _peep_last_ref_eq(db, a_name, a_name_len) != 0: