Page 32 - 《软件学报》2026年第6期
P. 32

屈晟 等: 面向  RISC-V  指令集多样性的兼容性感知多层级构建方法                                           2351


                 Linux  系统上的  ELF  目标文件); 真正二进制目标代码的生成移到了链接时进行.
                    在跨平台能力方面, LLVM IR       具备天然的平台无关性        [23,24] . 各类语言的函数调用约定、数据对齐规则等, 在
                 IR  层均以统一的形式表示, 便于后端针对不同目标架构生成对应汇编指令. IR                      中的函数调用一般表现为         call 指
                 令, 返回值则由    ret 指令处理, 参数传递通过显式声明完成. 这种统一抽象大大降低了编译器在前端与后端之间的
                 适配成本. 在实际使用中, LLVM IR       既可以作为内存中的中间数据结构存在于编译器内部, 也可被序列化为二进
                 制位码文件    (.bc) 或文本格式   (.ll) 文件. 这种二进制-文本双表示机制既有利于高效存储与传输, 也便于开发者调
                 试与静态分析.
                    得益于其良好的抽象层次和平台独立性, LLVM IR              成为现代编译器体系结构中实现多语言前端+多架构后端
                 解耦的核心桥梁      [25,26] . 只需实现一个将新语言转换为     LLVM IR  的前端模块, 或将    LLVM IR  转换为新硬件架构指
                 令的后端模块, 便可在现有基础上快速支持新场景, 极大提升编译器的可复用性和可扩展性. 在软件跨平台部署的
                 实际应用中, LLVM IR    也展现出强大的能力       [27,28] . 例如, 可将应用程序预编译为平台无关的        IR  文件, 部署至各终
                 端后再由本地工具根据硬件平台生成本地机器码, 从而实现“一次构建, 多端适配”的部署模式. 对于像                              RISC-V  这
                 样指令集与微架构高度可定制的生态, LLVM IR             的这一特性尤为重要. LLVM IR       作为  LLVM  体系的核心中间表
                 示语言, 既承载了语言语义的信息表达, 又支撑了跨平台优化与部署能力.
                    当前, LLVM IR  正处于快速发展与演进阶段, 导致在不同             LLVM  版本之间存在潜在兼容性问题, 限制了其在
                 支持多版本工具链且快速迭代演进的操作系统发行版中的全面应用, 如                        Fedora、Debian  等. 本文面向操作系统发
                 行版的研发需求, 通过记录编译和链接阶段执行的命令, 将                  LLVM  限制在同一大版本, 以确保可以成功将            LLVM
                 IR  转换为目标代码.
                  2.3   目标代码适配技术
                    在指令集扩展与微架构多样性日益增强的背景下, 如何在保持软件可移植性的同时提升目标平台的运行效
                 率, 成为构建系统设计的重要问题. 为此, 研究者和工程实践者提出两种主流机制: 间接函数支持                            (IFUNC) 与多库
                 支持  (Multilib). 二者分别在运行时与构建时提供了跨平台优化的路径, 在                x86、AArch64  等平台已有广泛应用,
                 在  RISC-V  等新兴架构中也逐步显示出其优势与局限性.
                    (1) IFUNC: 链接阶段的动态函数分发机制
                    IFUNC [29,30] 是一种基于运行时符号分发的函数多实现机制, 它通过链接器和动态加载器的配合, 实现对函数
                 符号的延迟解析. 开发者可为同一接口函数提供多个                 ISA  优化版本并编译链接到同一个动态链接库文件, 同时注
                 册一个解析器函数用于在程序加载时选择最适合的平台实现. IFUNC                       的技术核心是将符号类型标记为             STT_
                 GNU_IFUNC, 链接器保留相应重定位信息, 加载器在运行时调用解析函数获得最终函数地址, 填入                            GOT  表中以
                 支持高效跳转. 该机制允许开发者为同一个              API 提供多个   ISA  优化版本  (如基于不同     SIMD  扩展的  memcpy), 通
                 过  cpu_features 或  getauxval() 等硬件探测方法在加载时做出最优选择. 它兼具运行时灵活性与调用开销最小化的
                 优势, 并已被广泛应用于       glibc、OpenSSL、OpenBLAS  等系统库中用以适配如        AVX、NEON、RISC-V Vector 等
                 指令扩展   [31] .
                    然而, IFUNC  机制仍面临以下挑战: 一方面, 它对编译器和动态链接器功能有较强依赖, 部分新兴平台                           (如早
                 期的  RISC-V  发行版) 对  STT_GNU_IFUNC  类型支持不完整; 另一方面, 其函数选择逻辑需开发者手动维护, 适配
                 策略缺乏自动化与可扩展性, 限制了在大规模软件系统中的应用                    [2,5] .
                    (2) Multilib: 构建阶段的多版本库并行布局
                    Multilib  是另一种面向多平台构建优化的机制, 它通过在构建阶段生成并部署多个库版本, 支持目标平台在链
                 接时选择最合适的库变体. 每个变体针对不同的                ISA  组合或  ABI 配置  (如  32  位/64  位、硬/软浮点、压缩指令支
                 持等) 进行独立构建与打包. 链接器在构建系统的辅助下根据目标参数选择匹配的目录与文件路径完成链接                                  [29,32] .
                 Multilib  在许多主流架构的发行版中已被广泛应用, 并通过如             GCC  的--with-multilib-list 配置参数得到工具链级支
                 持. 研究者指出, Multilib  能够支持多个架构与       ABI 的并存构建, 满足面向通用平台的软件兼容需求, 是嵌入式与
   27   28   29   30   31   32   33   34   35   36   37