fix(gen): 模块前言 C 库声明名改落 PermPool,避免被回绕的模块池覆盖
现象:@malloc 的声明名被渲染成乱码,mlir-opt 报 llvm.call @malloc does not reference a symbol in the current scope。根因:create_declare 用 _str_dup(pool, name) 把名字拷进传入的池,而前言用的是模块池(大模块上会被复用/回绕),早期分配的声明名被后续分配覆盖;类型是 mlirlite 内部 interned 的,所以只有名字坏、参数类型正常。修法:声明与参数名改落 CompilerFactory.PermPool(never reset)。
This commit is contained in:
1 parent
8fb0e38f4c
commit
8b2008031d
1 file changed
+20
-10
@@ -10,6 +10,7 @@ import stdio
|
||||
import stdlib
|
||||
import viperlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.Projectrans.Config as Config
|
||||
import lib.Stub.StubMerger.StubMergerBuild as StubMergerBuild
|
||||
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
|
||||
@@ -413,34 +414,43 @@ novirtual class Translator:
|
||||
i8_ty: mlirlite.LLVMType* = mlirlite.Int8(pool)
|
||||
i8_ptr_ty: mlirlite.LLVMType* = mlirlite.Ptr(pool, i8_ty)
|
||||
|
||||
# 模块前言里 C 库声明的**名字**必须落在 PermPool:create_declare 会 _str_dup(pool, name)
|
||||
# 把名字拷进传入的池,而本模块池(trans.Pool)在大模块上会被复用/回绕,覆盖早期分配 →
|
||||
# 名字悬空(现场:@malloc 被渲染成乱码 @"PL\xEF\xBF\xBDp…",mlir-opt 报
|
||||
# "'llvm.call' op 'malloc' does not reference a symbol in the current scope";
|
||||
# 类型是 mlirlite 内部 interned 的,所以只有名字坏、参数类型正常)。
|
||||
# PermPool 是"persistent data; never reset",正好符合声明名的生命周期。
|
||||
decl_pool: memhub.MemBuddy* = CompilerFactory.factory.PermPool
|
||||
if decl_pool is None: decl_pool = pool
|
||||
|
||||
# Declare printf
|
||||
printf_func: mlirlite.Function* = mlirlite.create_declare(pool, mod, "printf", i32_ty)
|
||||
printf_func: mlirlite.Function* = mlirlite.create_declare(decl_pool, mod, "printf", i32_ty)
|
||||
if printf_func is None:
|
||||
VLogger.error("CreateDeclare printf returned NULL", "TR")
|
||||
return 1
|
||||
mlirlite.add_param(pool, printf_func, i8_ptr_ty, "fmt")
|
||||
mlirlite.add_param(decl_pool, printf_func, i8_ptr_ty, "fmt")
|
||||
printf_func.IsVarArg = 1
|
||||
# Declare LLVM va_start/va_end intrinsics (used inside *args function bodies):
|
||||
# declare void @llvm.va_start(i8*) / declare void @llvm.va_end(i8*)
|
||||
void_ty_decl: mlirlite.LLVMType* = mlirlite.Void(pool)
|
||||
va_start_func: mlirlite.Function* = mlirlite.create_declare(pool, mod, "llvm.va_start", void_ty_decl)
|
||||
if va_start_func is not None: mlirlite.add_param(pool, va_start_func, i8_ptr_ty, "ap")
|
||||
va_end_func: mlirlite.Function* = mlirlite.create_declare(pool, mod, "llvm.va_end", void_ty_decl)
|
||||
if va_end_func is not None: mlirlite.add_param(pool, va_end_func, i8_ptr_ty, "ap")
|
||||
va_start_func: mlirlite.Function* = mlirlite.create_declare(decl_pool, mod, "llvm.va_start", void_ty_decl)
|
||||
if va_start_func is not None: mlirlite.add_param(decl_pool, va_start_func, i8_ptr_ty, "ap")
|
||||
va_end_func: mlirlite.Function* = mlirlite.create_declare(decl_pool, mod, "llvm.va_end", void_ty_decl)
|
||||
if va_end_func is not None: mlirlite.add_param(decl_pool, va_end_func, i8_ptr_ty, "ap")
|
||||
|
||||
# Declare malloc (for closure allocation)
|
||||
malloc_func: mlirlite.Function* = mlirlite.create_declare(pool, mod, "malloc", i8_ptr_ty)
|
||||
malloc_func: mlirlite.Function* = mlirlite.create_declare(decl_pool, mod, "malloc", i8_ptr_ty)
|
||||
if malloc_func is not None:
|
||||
i64_ty: mlirlite.LLVMType* = mlirlite.Int64(pool)
|
||||
mlirlite.add_param(pool, malloc_func, i64_ty, "size")
|
||||
mlirlite.add_param(decl_pool, malloc_func, i64_ty, "size")
|
||||
|
||||
# Declare free (counterpart of malloc): M3 owned slife 的出口释放要用它。
|
||||
# 必须在这里(模块前言)声明:释放点只做**查表 + fail-fast**(VarGenMixin._SlifeEmitGuardedFree),不再现场建 declare——
|
||||
# 否则同一模块的每个出口各建一份重复 declare。缺了它 mlir-opt 会报
|
||||
# "'llvm.call' op 'free' does not reference a symbol in the current scope"
|
||||
# (现场:Test/NewLifetimeTest 未 import stdlib,拿不到 stdlib vpi 的 declare)。
|
||||
free_func: mlirlite.Function* = mlirlite.create_declare(pool, mod, "free", void_ty_decl)
|
||||
if free_func is not None: mlirlite.add_param(pool, free_func, i8_ptr_ty, "p")
|
||||
free_func: mlirlite.Function* = mlirlite.create_declare(decl_pool, mod, "free", void_ty_decl)
|
||||
if free_func is not None: mlirlite.add_param(decl_pool, free_func, i8_ptr_ty, "p")
|
||||
|
||||
# Check whether the user defined a main function
|
||||
has_user_main: int = 0
|
||||
|
||||
Reference in new issue
Block a user