feat(hotspot)!: 下线 --func-hotspot 并为 --hotspot-sites 增加每函数计时器
移除 --func-hotspot 全链路(CLI 解析与绑定、Config argparse 与注入、Translator 属性、LlvmGenerator 收口与透传、BaseGen 专属实现、Phase2Translator 透传、帮助文本);全仓已无 FuncHotspot/func-hotspot 残留引用。 通用截断逻辑保留并改名为 _InstallHotspotTruncate,供 --hotspot-sites 使用(分别清空 hotspot_sites.txt 与 hotspot_time.txt);ctor 注册改为直接新建并接收处理器列表(sites 与 time 两个处理器在同一 ctor 内注册)。 --hotspot-sites 现附带每函数计时:入口读一次 @llvm.readcyclecounter() 存起始 tick,在函数所有 ret 之前再读一次并累加差值到 internal i64 __fhs_ftime_N,同时 __fhs_ftime_enter_N 记录进入次数;单位为 tick(x86_64 即 CPU 周期),语义为 inclusive(包含内层调用)。 计时结果按耗时降序写入同目录 hotspot_time.txt(# time <module_sha1> 分段 + 函数名/累计 tick/进入次数),不改变 hotspot_sites.txt 的既有格式与字段。不传 --hotspot-sites 时零影响。
This commit is contained in:
1 parent
2021c0edb7
commit
fc5a6134ca
7 files changed
+359
-356
No files matched your search
@@ -149,8 +149,7 @@ def main() -> None:
|
||||
parser.add_argument('--clear-cache', action='store_true', help='清除 .transpyc_cache 全局缓存(.vpi/.stub.ll/.doc.json)')
|
||||
parser.add_argument('--asan', action='store_true', help='ASan 模式:对全部 .ll 做 opt -passes=asan 插桩,并显式链接 clang64 的 ASan 运行库(mingw64 的 clang 没有 x86_64-w64-windows-gnu 目标的 ASan runtime,不能用 -fsanitize=address)')
|
||||
parser.add_argument('--nowarn-register', action='store_true', help='抑制"外部函数返回类型未登记"类 WARN 输出(透传给自举编译的 TransPyV.exe)')
|
||||
parser.add_argument('--func-hotspot', help='函数热点统计:为每个模块的函数定义插入计数器,运行时 Ctrl+C 各模块以追加方式把计数写入 <path>(含 main 的模块在启动时清空一次,保证每次运行一份结果)(可用 python Projectrans.py --project ... --func-hotspot <path>)')
|
||||
parser.add_argument('--hotspot-sites', nargs='?', const='', default=None, help='调用点热点统计:为每个匹配白名单的直接 call 点插入计数器,运行时 Ctrl+C 各模块按真实次数降序写入 <path>(默认为 hotspot_sites.txt;可独立于 --func-hotspot 使用)')
|
||||
parser.add_argument('--hotspot-sites', nargs='?', const='', default=None, help='调用点热点统计:为每个匹配白名单的直接 call 点插入计数器,运行时 Ctrl+C 各模块按真实次数降序写入 <path>(默认为 hotspot_sites.txt);同时为每个函数定义加计时器,按累计耗时降序写入同目录 hotspot_time.txt')
|
||||
parser.add_argument('--hotspot-callees', default=None, help='--hotspot-sites 的白名单被调函数基名(逗号分隔),默认内存/字符串族 strcmp,strncmp,strchr,strlen,strstr,memcpy,memset,memmove,strcpy,strcat')
|
||||
parser.add_argument('--hotspot-sites-all', action='store_true', help='--hotspot-sites 对全部直接 call 点插桩(忽略白名单;体积/开销大,用于深度排查)')
|
||||
|
||||
@@ -197,11 +196,6 @@ def main() -> None:
|
||||
pass
|
||||
target_triple: str | None = resolved.get('target', {}).get('triple')
|
||||
target_datalayout: str | None = resolved.get('target', {}).get('datalayout')
|
||||
# 函数热点统计(--func-hotspot):解析为绝对路径,保证运行时(exe 工作目录为
|
||||
# output_dir)各模块处理器追加写入的路径与预期完全一致。
|
||||
func_hotspot_file: str | None = args.func_hotspot
|
||||
if func_hotspot_file:
|
||||
func_hotspot_file = os.path.abspath(func_hotspot_file)
|
||||
# 调用点热点统计(--hotspot-sites):None=未启用;''=启用但未给路径(默认
|
||||
# hotspot_sites.txt);其余为显式路径。一律绝对化,保证运行时(exe 工作目录为
|
||||
# output_dir)各模块处理器追加写入的路径与预期一致。
|
||||
@@ -230,10 +224,8 @@ def main() -> None:
|
||||
_vlog().info(f"目标三元组: {target_triple}")
|
||||
if target_datalayout:
|
||||
_vlog().info(f"数据布局: {target_datalayout}")
|
||||
if func_hotspot_file:
|
||||
_vlog().info(f"函数热点统计: {func_hotspot_file}(各模块运行时以追加方式写入,含 main 的模块启动时清空一次)")
|
||||
if hotspot_sites_file:
|
||||
_vlog().info(f"调用点热点统计: {hotspot_sites_file}(按真实调用次数降序落盘,含 main 的模块启动时清空一次)")
|
||||
_vlog().info(f"调用点热点统计: {hotspot_sites_file}(按真实调用次数降序落盘,含 main 的模块启动时清空一次);每函数计时: {os.path.join(os.path.dirname(hotspot_sites_file), 'hotspot_time.txt')}")
|
||||
|
||||
# 每次编译自动清理子进程性能剖析输出(PROF 目录 *.prof,硬编码路径)
|
||||
from lib.Projectrans.Phase2Translator import _CleanProfFiles, PROF_DIR
|
||||
@@ -339,9 +331,7 @@ def main() -> None:
|
||||
trans: Phase2Translator = Phase2Translator(src, temp_dir, output_dir, compile_cmd=cc_cmd, compile_flags=cc_flags, linker_cmd=linker_cmd, linker_flags=linker_flags, linker_output=linker_output, static_libs=static_libs, dynamic_libs=dynamic_libs, include_dirs=project_include_dirs, target_triple=target_triple, target_datalayout=target_datalayout, force_recompile_includes=force_recompile_includes, asan_mode=args.asan)
|
||||
trans.sha1_map = Load_sha1_map(temp_dir)
|
||||
trans.slice_level = slice_level
|
||||
# 函数热点统计(--func-hotspot):None=未启用(零影响)
|
||||
trans.func_hotspot_file = func_hotspot_file
|
||||
# 调用点热点统计(--hotspot-sites):None=未启用(零影响)
|
||||
# 调用点热点统计与每函数计时(--hotspot-sites):None=未启用(零影响)
|
||||
trans.hotspot_sites_file = hotspot_sites_file
|
||||
trans.hotspot_sites_all = bool(args.hotspot_sites_all)
|
||||
trans.hotspot_callees = hotspot_callees
|
||||
|
||||
@@ -162,7 +162,6 @@ def _parallel_translate_worker(src_path: str, out_path: str, src_root: str, temp
|
||||
stub_files: dict[str, str], include_py_map: dict[str, str], slice_level: int,
|
||||
shared_sym_pickle_path: str, struct_sha1_map: dict[str, str],
|
||||
prebuilt_ModuleSha1Map: dict[str, str] | None = None,
|
||||
func_hotspot_file: str | None = None,
|
||||
hotspot_sites_file: str | None = None,
|
||||
hotspot_sites_all: bool = False,
|
||||
hotspot_callees: list[str] | None = None) -> tuple[str, str, str]:
|
||||
@@ -183,10 +182,8 @@ def _parallel_translate_worker(src_path: str, out_path: str, src_root: str, temp
|
||||
trans.include_py_map = include_py_map
|
||||
trans.slice_level = slice_level
|
||||
trans.struct_sha1_map = struct_sha1_map
|
||||
# 函数热点统计(--func-hotspot):worker 子进程无父进程属性,须显式透传
|
||||
# (None=未启用,零影响);生成 IR 时各模块处理器统一追加写最终 <path>
|
||||
trans.func_hotspot_file = func_hotspot_file
|
||||
# 调用点热点统计(--hotspot-sites):同样须显式透传(None=未启用,零影响)
|
||||
# 调用点热点统计与每函数计时(--hotspot-sites):worker 子进程无父进程属性,
|
||||
# 须显式透传(None=未启用,零影响);生成 IR 时各模块处理器统一追加写最终 <path>
|
||||
trans.hotspot_sites_file = hotspot_sites_file
|
||||
trans.hotspot_sites_all = hotspot_sites_all
|
||||
trans.hotspot_callees = hotspot_callees
|
||||
@@ -234,7 +231,6 @@ def _parallel_translate_batch(batch: list, src_root: str, temp_dir: str, output_
|
||||
sha1_map: dict[str, str], sig_files: dict[str, str],
|
||||
stub_files: dict[str, str], include_py_map: dict[str, str], slice_level: int,
|
||||
shared_sym_pickle_path: str, struct_sha1_map: dict[str, str],
|
||||
func_hotspot_file: str | None = None,
|
||||
hotspot_sites_file: str | None = None,
|
||||
hotspot_sites_all: bool = False,
|
||||
hotspot_callees: list[str] | None = None) -> tuple[list, list]:
|
||||
@@ -258,9 +254,7 @@ def _parallel_translate_batch(batch: list, src_root: str, temp_dir: str, output_
|
||||
trans.include_py_map = include_py_map
|
||||
trans.slice_level = slice_level
|
||||
trans.struct_sha1_map = struct_sha1_map
|
||||
# 函数热点统计(--func-hotspot):批内每文件的处理器统一追加写最终 <path>
|
||||
trans.func_hotspot_file = func_hotspot_file
|
||||
# 调用点热点统计(--hotspot-sites):批内每文件同样透传
|
||||
# 调用点热点统计与每函数计时(--hotspot-sites):批内每文件同样透传
|
||||
trans.hotspot_sites_file = hotspot_sites_file
|
||||
trans.hotspot_sites_all = hotspot_sites_all
|
||||
trans.hotspot_callees = hotspot_callees
|
||||
@@ -662,13 +656,10 @@ class Phase2Translator:
|
||||
os.environ['PATH'] = _clang64_bin + os.pathsep + os.environ.get('PATH', '')
|
||||
self.asan_rt_dir = _FindAsanRuntimeDir()
|
||||
self.slice_level = 3
|
||||
# 函数热点统计(--func-hotspot):None=未启用(零影响);str=计数器输出
|
||||
# 文件路径。各模块运行时自带 Ctrl+C 处理器、统一以追加方式写该路径;
|
||||
# 含 main 的模块在 main 入口清空一次 → 每次运行一份结果(无构建后合并步骤)。
|
||||
self.func_hotspot_file: str | None = None
|
||||
# 调用点热点统计(--hotspot-sites):None=未启用(零影响);str=调用点计数
|
||||
# 落盘文件路径。各模块运行时自带 Ctrl+C 处理器、统一以追加方式写该路径;
|
||||
# 含 main 的模块在 main 入口清空一次 → 每次运行一份结果。
|
||||
# 落盘文件路径(每函数计时落同目录 hotspot_time.txt)。各模块运行时自带
|
||||
# Ctrl+C 处理器、统一以追加方式写该路径;含 main 的模块在 main 入口清空一次
|
||||
# → 每次运行一份结果。
|
||||
self.hotspot_sites_file: str | None = None
|
||||
# 是否对全部直接 call 点插桩(忽略白名单);白名单被调函数基名列表(None=默认)
|
||||
self.hotspot_sites_all: bool = False
|
||||
@@ -876,11 +867,11 @@ class Phase2Translator:
|
||||
self.struct_sha1_map = self._build_struct_sha1_map()
|
||||
|
||||
need_translate = []
|
||||
# --func-hotspot / --hotspot-sites:缓存 .ll / .stub.ll+.text.ll 可能不含
|
||||
# 热点计数 IR,启用任一功能时一律重译,保证每个模块都嵌入 internal 计数器
|
||||
# 与 @llvm.global_ctors 自注册。未启用时 hotspot_on=False,缓存与重组分支
|
||||
# --hotspot-sites:缓存 .ll / .stub.ll+.text.ll 可能不含热点计数/计时 IR,
|
||||
# 启用时一律重译,保证每个模块都嵌入 internal 计数器、计时器与
|
||||
# @llvm.global_ctors 自注册。未启用时 hotspot_on=False,缓存与重组分支
|
||||
# 行为与改动前完全一致(零影响)。
|
||||
hotspot_on: bool = bool(self.func_hotspot_file or self.hotspot_sites_file)
|
||||
hotspot_on: bool = bool(self.hotspot_sites_file)
|
||||
for i, src_path in enumerate(py_files, 1):
|
||||
rel = os.path.relpath(src_path, self.src_root)
|
||||
# 复用 parse_python_file 的 AST 缓存(get_file_dependencies 已 parse 过)
|
||||
@@ -1039,7 +1030,6 @@ class Phase2Translator:
|
||||
self.sha1_map, self.sig_files, self.stub_files,
|
||||
self.include_py_map, self.slice_level,
|
||||
shared_pickle_path, self.struct_sha1_map,
|
||||
func_hotspot_file=self.func_hotspot_file,
|
||||
hotspot_sites_file=self.hotspot_sites_file,
|
||||
hotspot_sites_all=self.hotspot_sites_all,
|
||||
hotspot_callees=self.hotspot_callees,
|
||||
@@ -1317,7 +1307,7 @@ class Phase2Translator:
|
||||
|
||||
if stripped.startswith('@') and ' global ' in stripped and 'external global' not in stripped:
|
||||
text_lines.append(line)
|
||||
# LLVM 保留全局(如 --func-hotspot 的 @llvm.global_ctors;名字含点故
|
||||
# LLVM 保留全局(如 --hotspot-sites 的 @llvm.global_ctors;名字含点故
|
||||
# 最终 IR 保留引号)是 appending 定义,禁止改写为 "external global"
|
||||
# 存根(否则 .ll 重组后 llc 报错)
|
||||
if re.match(r'@("?)llvm\.', stripped):
|
||||
@@ -1583,15 +1573,9 @@ class Phase2Translator:
|
||||
trans.translator._shared_class_methods = self._shared_class_methods
|
||||
trans.translator._shared_cross_module_novtable = self._shared_cross_module_novtable
|
||||
|
||||
# 函数热点统计(--func-hotspot,Projectrans 多模块):
|
||||
# 各模块处理器统一以追加方式写最终 <path>;注册策略为本模块
|
||||
# @llvm.global_ctors 自注册(见 BaseGen._InstallFuncHotspotModuleLocal)。
|
||||
# self.func_hotspot_file 为 None 时不设置任何属性 → 与未启用时逐字节一致(零影响)。
|
||||
if self.func_hotspot_file:
|
||||
trans.translator.FuncHotspotFile = self.func_hotspot_file
|
||||
trans.translator.FuncHotspotModuleLocal = True
|
||||
# 调用点热点统计(--hotspot-sites,Projectrans 多模块):同上,注册策略为
|
||||
# 本模块 ctor 自注册(见 BaseGen._InstallHotspotSitesModuleLocal);
|
||||
# 调用点热点统计与每函数计时(--hotspot-sites,Projectrans 多模块):
|
||||
# 各模块处理器统一以追加方式写最终 <path>,注册策略为本模块
|
||||
# @llvm.global_ctors 自注册(见 BaseGen._InstallHotspotSitesModuleLocal);
|
||||
# self.hotspot_sites_file 为 None 时不设置任何属性 → 与未启用时逐字节一致。
|
||||
if self.hotspot_sites_file:
|
||||
trans.translator.HotspotSitesFile = self.hotspot_sites_file
|
||||
@@ -2878,7 +2862,6 @@ class Phase2Translator:
|
||||
self.include_py_map, self.slice_level,
|
||||
shared_pickle_path, self.struct_sha1_map,
|
||||
include_ModuleSha1Map,
|
||||
func_hotspot_file=self.func_hotspot_file,
|
||||
hotspot_sites_file=self.hotspot_sites_file,
|
||||
hotspot_sites_all=self.hotspot_sites_all,
|
||||
hotspot_callees=self.hotspot_callees
|
||||
@@ -2898,7 +2881,6 @@ class Phase2Translator:
|
||||
self.include_py_map, self.slice_level,
|
||||
shared_pickle_path, self.struct_sha1_map,
|
||||
include_ModuleSha1Map,
|
||||
func_hotspot_file=self.func_hotspot_file,
|
||||
hotspot_sites_file=self.hotspot_sites_file,
|
||||
hotspot_sites_all=self.hotspot_sites_all,
|
||||
hotspot_callees=self.hotspot_callees
|
||||
|
||||
Reference in new issue
Block a user