feat(backend): 新增 MLIR 后端开关/产物隔离/降级管线/模块别名(默认 llvm 逐字不变)
- Config: BackendTarget/BackendIsMlir/set_backend/is_mlir_backend/backend_dir_suffix/alias_module_name;读取 options.backend(回退 options.target) - main.vp: 新增 --backend llvm|mlir(CLI 优先级最高,默认 llvm),加载工程后、resolve_paths 前生效 - 产物隔离: temp/output 追加 _mlir 后缀;includes 缓存追加后端后缀(.binary[_asan][_mlir]) - BuildPipeline: MLIR 降级 mlir-opt(校验) -> mlir-translate --mlir-to-llvmir,覆盖串行/并行/--phase2command,且置于 ASan opt 之前;LlcTask 增 MlirOptCmd/MlirTranslateCmd 字段 - 别名: ResolveModuleToPath 与 _FindSha1ByModName 经 Config.alias_module_name 把 llvmlite 重定向到 mlirlite(调用点零改动)
This commit is contained in:
1 parent
4eec3f0908
commit
0ebe2e0752
5 files changed
+219
-14
No files matched your search
@@ -43,6 +43,17 @@ IncludesDirs: str = None # 全部 includes 目录(空格分隔,多
|
||||
# includes 预编译缓存目录后缀(asan 模式用 .binary_asan 隔离 asan 插桩 obj,避免与非 asan obj 混链)
|
||||
_inc_bin_suffix: str = ".binary"
|
||||
|
||||
# ============================================================
|
||||
# 后端(Emitter Backend)
|
||||
#
|
||||
# "llvm"(默认):IR 发射走 includes/llvmlite(LLVM IR 文本),opt/llc 直接消费。
|
||||
# "mlir" :模块名 llvmlite 在解析层重定向到 includes/mlirlite(MLIR 文本),
|
||||
# 并在 opt/llc 之前插入 mlir-opt(校验)→ mlir-translate(降级回 LLVM IR)。
|
||||
# 只认字符串 "mlir":缺省 / 未知值一律按 LLVM(BackendIsMlir=0),保证默认路径逐字不变。
|
||||
# ============================================================
|
||||
BackendTarget: str = "llvm"
|
||||
BackendIsMlir: int = 0
|
||||
|
||||
|
||||
def Load_project_config(path: str) -> int:
|
||||
"""加载工程配置文件(project.vpj)
|
||||
@@ -145,6 +156,16 @@ def Load_project_config(path: str) -> int:
|
||||
sm: JsonValue | t.CPtr = options["strict_mode"]
|
||||
if sm is not None and sm.is_bool():
|
||||
StrictMode = 1 if sm.as_bool() else 0
|
||||
# 后端:options.backend(新键)优先,回退 options.target(兼容旧键)。
|
||||
# 只认 "mlir";其余(含缺省/未知)按 LLVM。CLI --backend 由 main.vp
|
||||
# 在本函数返回后覆盖(CLI 优先级最高)。
|
||||
be_val: JsonValue | t.CPtr = options["backend"]
|
||||
if be_val is not None and be_val.is_string():
|
||||
set_backend(be_val.as_string())
|
||||
else:
|
||||
tgt_be: JsonValue | t.CPtr = options["target"]
|
||||
if tgt_be is not None and tgt_be.is_string():
|
||||
set_backend(tgt_be.as_string())
|
||||
|
||||
# 读取 includes 数组(支持多目录:首元素存 IncludesDir,全部拼接存 IncludesDirs)
|
||||
includes_val: JsonValue | t.CPtr = root["includes"]
|
||||
@@ -424,17 +445,19 @@ def resolve_paths(project_dir: str) -> int:
|
||||
SourceDir = _join_path(SourceDir, project_dir)
|
||||
BuildDir = _join_path(BuildDir, project_dir)
|
||||
|
||||
# TempDir = {BuildDir}/temp
|
||||
# TempDir = {BuildDir}/temp(非 LLVM 后端追加隔离后缀,如 _mlir;LLVM 时后缀为空串,路径逐字不变)
|
||||
if BuildDir is not None:
|
||||
bd_len: sizet = string.strlen(BuildDir)
|
||||
temp_buf: str = _mbuddy.alloc(bd_len + 8)
|
||||
suf_dir: str = backend_dir_suffix()
|
||||
suf_dir_len: sizet = string.strlen(suf_dir)
|
||||
temp_buf: str = _mbuddy.alloc(bd_len + suf_dir_len + 8)
|
||||
if temp_buf is not None:
|
||||
viperlib.snprintf(temp_buf, bd_len + 8, "%s/temp", BuildDir)
|
||||
viperlib.snprintf(temp_buf, bd_len + suf_dir_len + 8, "%s/temp%s", BuildDir, suf_dir)
|
||||
TempDir = temp_buf
|
||||
# OutputDir = {BuildDir}/output
|
||||
output_buf: str = _mbuddy.alloc(bd_len + 8)
|
||||
output_buf: str = _mbuddy.alloc(bd_len + suf_dir_len + 8)
|
||||
if output_buf is not None:
|
||||
viperlib.snprintf(output_buf, bd_len + 8, "%s/output", BuildDir)
|
||||
viperlib.snprintf(output_buf, bd_len + suf_dir_len + 8, "%s/output%s", BuildDir, suf_dir)
|
||||
OutputDir = output_buf
|
||||
|
||||
# includes 路径可能是 ../includes 形式,需要基于 project_dir 解析
|
||||
@@ -638,18 +661,71 @@ def get_includes_binary_dir() -> str:
|
||||
includes 目录如 ../includes,默认返回 ../includes.binary;
|
||||
asan 模式(set_inc_bin_suffix(".binary_asan"))返回 ../includes.binary_asan,
|
||||
隔离 asan 插桩 obj,避免与非 asan obj 混链。
|
||||
非 LLVM 后端再追加后端后缀(如 .binary_asan_mlir),隔离不同后端的 obj。
|
||||
"""
|
||||
if IncludesDir is None:
|
||||
return None
|
||||
inc_len: sizet = string.strlen(IncludesDir)
|
||||
suf_len: sizet = string.strlen(_inc_bin_suffix)
|
||||
buf: str = _mbuddy.alloc(inc_len + suf_len + 1)
|
||||
be_suf: str = backend_dir_suffix()
|
||||
be_suf_len: sizet = string.strlen(be_suf)
|
||||
buf: str = _mbuddy.alloc(inc_len + suf_len + be_suf_len + 1)
|
||||
if buf is None:
|
||||
return None
|
||||
viperlib.snprintf(buf, inc_len + suf_len + 1, "%s%s", IncludesDir, _inc_bin_suffix)
|
||||
viperlib.snprintf(buf, inc_len + suf_len + be_suf_len + 1, "%s%s%s", IncludesDir, _inc_bin_suffix, be_suf)
|
||||
return buf
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 后端开关(Emitter Backend)
|
||||
#
|
||||
# set_backend: 只接受 "llvm" / "mlir"(其余返回 1 且不改动),大小写敏感。
|
||||
# backend_dir_suffix: 非默认后端的目录隔离后缀;LLVM 后端返回空串(调用方拼出的
|
||||
# 路径与改前逐字相同)。用于 TempDir/OutputDir/includes.binary。
|
||||
# is_mlir_backend: 0/1 便捷视图(BuildPipeline 降级管线的门)。
|
||||
# ============================================================
|
||||
def set_backend(name: str) -> int:
|
||||
"""设置后端;0=成功,1=非法(name 为 None 或非 llvm/mlir)"""
|
||||
global BackendTarget, BackendIsMlir
|
||||
if name is None:
|
||||
return 1
|
||||
if string.strcmp(name, "llvm") == 0:
|
||||
BackendTarget = name
|
||||
BackendIsMlir = 0
|
||||
return 0
|
||||
if string.strcmp(name, "mlir") == 0:
|
||||
BackendTarget = name
|
||||
BackendIsMlir = 1
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
def is_mlir_backend() -> int:
|
||||
"""是否 MLIR 后端(1=mlir / 0=llvm)"""
|
||||
return BackendIsMlir
|
||||
|
||||
|
||||
def backend_dir_suffix() -> str:
|
||||
"""非默认后端的目录隔离后缀(LLVM 后端返回空串 ⇒ 路径逐字不变)"""
|
||||
if BackendIsMlir != 0:
|
||||
return "_mlir"
|
||||
return ""
|
||||
|
||||
|
||||
def alias_module_name(name: str) -> str:
|
||||
"""MLIR 后端下把模块名 "llvmlite" 重定向到 "mlirlite"(其余原样返回)。
|
||||
|
||||
这是"TransPyV 调用点零改动"的唯一开关:所有 **名称→模块/文件/SHA1** 的解析
|
||||
都应经此函数(模块文件解析 IncludesScanner.ResolveModuleToPath、依赖名→SHA1
|
||||
StubMergerIR._FindSha1ByModName 等)。LLVM 后端恒等返回,默认路径逐字不变。
|
||||
"""
|
||||
if name is None:
|
||||
return None
|
||||
if BackendIsMlir != 0 and string.strcmp(name, "llvmlite") == 0:
|
||||
return "mlirlite"
|
||||
return name
|
||||
|
||||
|
||||
def asan_runtime_declared() -> int:
|
||||
"""project.vpj 是否已声明 ASan 运行库(1 = 声明过)
|
||||
|
||||
|
||||
Reference in new issue
Block a user