fix(mlir): 全局初始化器区域缓冲溢出不再误报为模块缓冲溢出
- GV_REGION_BUF_SIZE 由 32KB 提升到 4MB,并改用 malloc 分配(原走模块子池,容量受限) - 新增 _MlirGvOutTrunc 与 _append_gv:区域缓冲溢出独立上报,不再置位模块截断标志 - MlirGvResetScratch 负责释放这两块 malloc 缓冲 复现:font 这类嵌套聚合全局初始化器超过 23 行(368 元素)即误报 module text exceeds output buffer,实际模块缓冲 8MB 远未写满。
This commit is contained in:
1 parent
825919b202
commit
825cd2b027
1 file changed
+64
-36
+64
-36
@@ -923,7 +923,10 @@ def _MlirArrayDenseAt(buf: str, size: sizet, src: str,
|
||||
# top-level aggregate and whose index path comes from a parallel initializer/type walk. Element MLIR
|
||||
# types come from the global type tree via TypePrint; constexpr bitcast/GEP are treated as symbol
|
||||
# references; unsupported leaves fail loud.
|
||||
define GV_REGION_BUF_SIZE = 32768
|
||||
# Sized for large aggregate tables (e.g. a [256][16] uint8 font: 4096 leaves plus 4096 insertvalue
|
||||
# lines of ~110 B each ≈ 450 KiB). These two buffers are malloc'd instead of taken from the module
|
||||
# sub-pool, so their size is independent of the pool capacity.
|
||||
define GV_REGION_BUF_SIZE = 4194304
|
||||
|
||||
# Index-path reuse stack: one slot per recursion depth (top-level path="" → depth d in slot d).
|
||||
# Depth cap matches _MlirGvWalk's 64-level guard with margin (72); 512 bytes per slot suffices.
|
||||
@@ -939,6 +942,9 @@ _MlirGvPrev: str = None # SSA name of the previous insertvalue result
|
||||
_MlirGvPool: memhub.MemBuddy* = None
|
||||
_MlirGvLeafSeq: int = 0
|
||||
_MlirGvInsSeq: int = 0
|
||||
# Set when a region scratch buffer (leaf/insertvalue) overflows, so its failure is reported as a
|
||||
# region-buffer overflow instead of being conflated with the module output buffer.
|
||||
_MlirGvOutTrunc: int = 0
|
||||
|
||||
# ---- Region-render REUSED scratch buffers (lazily allocated once, shared across globals/nodes) ----
|
||||
# Allocating new buffers per global/node exhausted the ~2 MiB sub-pool for struct/vtable-heavy
|
||||
@@ -957,9 +963,13 @@ def MlirGvResetScratch():
|
||||
|
||||
The scratch is reused only within a single PrintModule (shared across globals/nodes); clearing
|
||||
it at print end prevents reusing a previous print's pointers (freed or reused pool → dangling).
|
||||
The two large region buffers are malloc'd, so they are freed here.
|
||||
"""
|
||||
global _MlirGvLeafBuf
|
||||
global _MlirGvLeafBuf, _MlirGvInsBuf
|
||||
if _MlirGvLeafBuf is not None: stdlib.free(_MlirGvLeafBuf)
|
||||
if _MlirGvInsBuf is not None: stdlib.free(_MlirGvInsBuf)
|
||||
_MlirGvLeafBuf = None
|
||||
_MlirGvInsBuf = None
|
||||
|
||||
|
||||
def _MlirGvEnsureScratch(pool: memhub.MemBuddy*) -> int:
|
||||
@@ -969,8 +979,8 @@ def _MlirGvEnsureScratch(pool: memhub.MemBuddy*) -> int:
|
||||
global _MlirGvTyBuf, _MlirGvNameBuf, _MlirGvPathStack
|
||||
if _MlirGvLeafBuf is not None:
|
||||
return 1
|
||||
lb: str = pool.alloc(GV_REGION_BUF_SIZE)
|
||||
ib: str = pool.alloc(GV_REGION_BUF_SIZE)
|
||||
lb: str = stdlib.malloc(GV_REGION_BUF_SIZE)
|
||||
ib: str = stdlib.malloc(GV_REGION_BUF_SIZE)
|
||||
tb: str = pool.alloc(4096)
|
||||
la: str = pool.alloc(32)
|
||||
pr: str = pool.alloc(32)
|
||||
@@ -1067,7 +1077,7 @@ def _MlirGlobalInitRegion(buf: str, size: sizet,
|
||||
|
||||
Each line ends with '\\n'; the caller appends '}' and the module layer re-indents by 2.
|
||||
"""
|
||||
global _MlirGvPool, _MlirGvLeafSeq, _MlirGvInsSeq
|
||||
global _MlirGvPool, _MlirGvLeafSeq, _MlirGvInsSeq, _MlirGvOutTrunc
|
||||
x: str = gv.Initializer
|
||||
if x is None:
|
||||
return
|
||||
@@ -1089,6 +1099,7 @@ def _MlirGlobalInitRegion(buf: str, size: sizet,
|
||||
_MlirGvPool = pool
|
||||
_MlirGvLeafSeq = 0
|
||||
_MlirGvInsSeq = 0
|
||||
_MlirGvOutTrunc = 0
|
||||
|
||||
is_agg: int = 0
|
||||
match gv.Ty:
|
||||
@@ -1102,7 +1113,9 @@ def _MlirGlobalInitRegion(buf: str, size: sizet,
|
||||
# Start of the insertvalue chain: top-level undef
|
||||
string.strcpy(prevbuf, "%undef")
|
||||
|
||||
_MlirGvWalk(x, gv.Ty, "", 0)
|
||||
_MlirGvWalk(x, gv.Ty, "", 0)
|
||||
if _MlirGvOutTrunc != 0:
|
||||
MlirFail("MLIR render: global initializer region text exceeds GV_REGION_BUF_SIZE (increase it)")
|
||||
|
||||
# Emit leaf ops first, then the undef + insertvalue chain
|
||||
_append_cstr(buf, size, leafbuf)
|
||||
@@ -1462,11 +1475,11 @@ def _MlirGvNextLeafName() -> str:
|
||||
def _MlirGvEmitAddressOf(name: str):
|
||||
"""Emit a leaf op: %vN = llvm.mlir.addressof @"name" : !llvm.ptr."""
|
||||
ln: str = _MlirGvNextLeafName()
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " ")
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, ln)
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " = llvm.mlir.addressof ")
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " ")
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, ln)
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " = llvm.mlir.addressof ")
|
||||
_MlirSymRefAppend(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, name)
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " : !llvm.ptr\n")
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " : !llvm.ptr\n")
|
||||
string.strcpy(_MlirGvLast, ln)
|
||||
|
||||
|
||||
@@ -1476,11 +1489,11 @@ def _MlirGvEmitZero(ty: LLVMType*):
|
||||
mt[0] = '\0'
|
||||
TypePrint(mt, 4096, ty, _MlirGvPool)
|
||||
ln: str = _MlirGvNextLeafName()
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " ")
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, ln)
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " = llvm.mlir.zero : ")
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, mt)
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, "\n")
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " ")
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, ln)
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " = llvm.mlir.zero : ")
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, mt)
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, "\n")
|
||||
string.strcpy(_MlirGvLast, ln)
|
||||
|
||||
|
||||
@@ -1492,19 +1505,19 @@ def _MlirGvEmitConst(val: str, ty: LLVMType*):
|
||||
if mt[0] != 'i' and mt[0] != 'f':
|
||||
MlirFail("MLIR render: global initializer scalar element type is neither integer nor float")
|
||||
ln: str = _MlirGvNextLeafName()
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " ")
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, ln)
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " = llvm.mlir.constant(")
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, val)
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " ")
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, ln)
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " = llvm.mlir.constant(")
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, val)
|
||||
# i1's `true`/`false` are MLIR bare boolean keywords and take no type suffix
|
||||
# (`llvm.mlir.constant(false : i1)` errors "expected ')'"); other scalars must use
|
||||
# `value : type` (otherwise they are untyped attrs and mismatch the result type).
|
||||
if string.strcmp(val, "true") != 0 and string.strcmp(val, "false") != 0:
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " : ")
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, mt)
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, ") : ")
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, mt)
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, "\n")
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " : ")
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, mt)
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, ") : ")
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, mt)
|
||||
_append_gv(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, "\n")
|
||||
string.strcpy(_MlirGvLast, ln)
|
||||
|
||||
|
||||
@@ -1514,17 +1527,17 @@ def _MlirGvInsertLeaf(path: str):
|
||||
_MlirGvInsSeq += 1
|
||||
sn: str = _MlirGvNameBuf
|
||||
viperlib.snprintf(sn, 32, "%%s%d", _MlirGvInsSeq)
|
||||
_append_cstr(_MlirGvInsBuf, GV_REGION_BUF_SIZE, " ")
|
||||
_append_cstr(_MlirGvInsBuf, GV_REGION_BUF_SIZE, sn)
|
||||
_append_cstr(_MlirGvInsBuf, GV_REGION_BUF_SIZE, " = llvm.insertvalue ")
|
||||
_append_cstr(_MlirGvInsBuf, GV_REGION_BUF_SIZE, _MlirGvLast)
|
||||
_append_cstr(_MlirGvInsBuf, GV_REGION_BUF_SIZE, ", ")
|
||||
_append_cstr(_MlirGvInsBuf, GV_REGION_BUF_SIZE, _MlirGvPrev)
|
||||
_append_cstr(_MlirGvInsBuf, GV_REGION_BUF_SIZE, "[")
|
||||
_append_cstr(_MlirGvInsBuf, GV_REGION_BUF_SIZE, path)
|
||||
_append_cstr(_MlirGvInsBuf, GV_REGION_BUF_SIZE, "] : ")
|
||||
_append_cstr(_MlirGvInsBuf, GV_REGION_BUF_SIZE, _MlirGvTopType)
|
||||
_append_cstr(_MlirGvInsBuf, GV_REGION_BUF_SIZE, "\n")
|
||||
_append_gv(_MlirGvInsBuf, GV_REGION_BUF_SIZE, " ")
|
||||
_append_gv(_MlirGvInsBuf, GV_REGION_BUF_SIZE, sn)
|
||||
_append_gv(_MlirGvInsBuf, GV_REGION_BUF_SIZE, " = llvm.insertvalue ")
|
||||
_append_gv(_MlirGvInsBuf, GV_REGION_BUF_SIZE, _MlirGvLast)
|
||||
_append_gv(_MlirGvInsBuf, GV_REGION_BUF_SIZE, ", ")
|
||||
_append_gv(_MlirGvInsBuf, GV_REGION_BUF_SIZE, _MlirGvPrev)
|
||||
_append_gv(_MlirGvInsBuf, GV_REGION_BUF_SIZE, "[")
|
||||
_append_gv(_MlirGvInsBuf, GV_REGION_BUF_SIZE, path)
|
||||
_append_gv(_MlirGvInsBuf, GV_REGION_BUF_SIZE, "] : ")
|
||||
_append_gv(_MlirGvInsBuf, GV_REGION_BUF_SIZE, _MlirGvTopType)
|
||||
_append_gv(_MlirGvInsBuf, GV_REGION_BUF_SIZE, "\n")
|
||||
string.strcpy(_MlirGvPrev, sn)
|
||||
string.strcpy(_MlirGvLast, sn)
|
||||
|
||||
@@ -1597,4 +1610,19 @@ def _append_cstr(dst: str, dst_size: sizet, src: str):
|
||||
if i < slen:
|
||||
_MlirModOutTrunc = 1
|
||||
dst[dlen + i] = '\0'
|
||||
_g_last_pos = dlen + i
|
||||
_g_last_pos = dlen + i
|
||||
|
||||
|
||||
def _append_gv(dst: str, dst_size: sizet, src: str):
|
||||
"""Append to a global-initializer region scratch buffer; overflow sets _MlirGvOutTrunc.
|
||||
|
||||
_append_cstr carries a single truncation flag shared with the module output buffer, so that flag
|
||||
is masked out here and a region-buffer overflow is recorded separately (otherwise a region
|
||||
overflow is misreported as "module text exceeds output buffer").
|
||||
"""
|
||||
global _MlirGvOutTrunc, _MlirModOutTrunc
|
||||
saved: int = _MlirModOutTrunc
|
||||
_MlirModOutTrunc = 0
|
||||
_append_cstr(dst, dst_size, src)
|
||||
if _MlirModOutTrunc != 0: _MlirGvOutTrunc = 1
|
||||
_MlirModOutTrunc = saved
|
||||
Reference in new issue
Block a user