fix(llvmlite): 打印端跳过被同模块定义取代的 external global(消除 redefinition of global)
模块内不变量:同一符号名不得同时打印 external 声明与定义,否则 llc 报 redefinition of global(SysLibTest os/__init__ 的 _mbuddy:循环 import 使 LoadDepVpiIntoModule 把本模块自身 vpi 注入自身 → 先发 external,handle_module_level_var 再发定义)。新增 _module_has_initializer_global:OUTPUT_FULL/STUB/TEXT 三模式对无初值 GV,若模块内存在同名带初值定义则跳过。只处理本模块内同名声明+定义,依赖模块的合法 external(本模块无同名定义)一律保留,不做跨模块去重(与 TransPyC Phase2Translator 合并期 external 去重同构)。
This commit is contained in:
1 parent
7f3b3dea1a
commit
7bd4cda5be
1 file changed
+43
-4
+43
-4
@@ -396,6 +396,11 @@ class LLVMModule:
|
||||
stdio.printf("[IR-DUMP] 链表成环: module globals stub(GlobalCount=%zu,dump 终止)\n",
|
||||
self.GlobalCount)
|
||||
stdlib.exit(1)
|
||||
# 模块内不变量:同名 external 声明若已被同名定义取代则跳过,
|
||||
# 避免 stub 输出出现同一符号两行(见 _module_has_initializer_global)。
|
||||
if gv.Initializer is None and _module_has_initializer_global(self, gv.Name) != 0:
|
||||
gv = gv.Next
|
||||
continue
|
||||
_print_global_stub(buf, size, gv, pool)
|
||||
_append_cstr(buf, size, "\n")
|
||||
gv = gv.Next
|
||||
@@ -409,10 +414,15 @@ class LLVMModule:
|
||||
stdio.printf("[IR-DUMP] 链表成环: module globals(GlobalCount=%zu,dump 终止)\n",
|
||||
self.GlobalCount)
|
||||
stdlib.exit(1)
|
||||
if mode == OUTPUT_TEXT and gv.Initializer is None:
|
||||
gv = gv.Next
|
||||
gv_idx += 1
|
||||
continue
|
||||
# text 模式跳过无初值的全局变量(纯声明);
|
||||
# full 模式亦跳过"已被同名定义取代"的纯声明(见
|
||||
# _module_has_initializer_global)——否则单模块 IR 同名声明+定义
|
||||
# 并存,llc 报 "redefinition of global"。
|
||||
if gv.Initializer is None:
|
||||
if mode == OUTPUT_TEXT or _module_has_initializer_global(self, gv.Name) != 0:
|
||||
gv = gv.Next
|
||||
gv_idx += 1
|
||||
continue
|
||||
_print_global(buf, size, gv, pool)
|
||||
_append_cstr(buf, size, "\n")
|
||||
gv = gv.Next
|
||||
@@ -818,6 +828,35 @@ def LLVMModulePrint(buf: str, size: sizet,
|
||||
# ============================================================
|
||||
# 全局变量打印
|
||||
# ============================================================
|
||||
# _module_has_initializer_global - 模块内是否存在同名"定义"全局(带初值)
|
||||
#
|
||||
# 模块内不变量:同一符号名不得同时出现 external 声明与定义,否则 llc 报
|
||||
# "redefinition of global '@<sha1>.<name>'"。
|
||||
# 触发场景:循环 import(如 os/__init__ 同时 import os._win32/os._posix,二者又
|
||||
# 导入包 os ⇒ imported_modules 含 "os" 自身)使**本模块自己的 .vpi** 被当作依赖
|
||||
# 注入;VpiReader._inject_global_variable_declare 先在本模块加一个同名 external
|
||||
# 声明全局,随后 handle_module_level_var 再发射同名定义 ⇒ 单模块 IR 同名冲突。
|
||||
# 打印端按"同名 + 有初值"判定并跳过纯声明,保证单模块 IR 自足合法(对齐旧编译器
|
||||
# TransPyC/Phase2Translator 合并期的 external 去重:同名的 external 声明被定义取代)。
|
||||
# 只跳过"无初值且有同名初值定义"的声明;依赖模块的合法 external(本模块无同名
|
||||
# 定义)一律保留,不做跨模块去重。
|
||||
# ============================================================
|
||||
def _module_has_initializer_global(mod: rawptr[LLVMModule], name: str) -> int:
|
||||
if mod is None or name is None:
|
||||
return 0
|
||||
cur: rawptr[GlobalVariable] = mod.GlobalHead
|
||||
steps: sizet = 0
|
||||
while cur is not None:
|
||||
steps += 1
|
||||
if steps > IR_DUMP_CHAIN_LIMIT:
|
||||
break
|
||||
if cur.Name is not None and cur.Initializer is not None:
|
||||
if string.strcmp(cur.Name, name) == 0:
|
||||
return 1
|
||||
cur = cur.Next
|
||||
return 0
|
||||
|
||||
|
||||
def _print_global(buf: str, size: sizet,
|
||||
gv: rawptr[GlobalVariable], pool: memhub.MemBuddy*):
|
||||
"""打印单个全局变量: @<name> = [linkage] [unnamed_addr] [constant] <ty> <init>"""
|
||||
|
||||
Reference in new issue
Block a user