Page 26 - 《软件学报》2025年第12期
P. 26

沈莉 等: swJulia: 面向新一代神威超级计算机的         Julia 语言编译系统                               5407


                 Prologue 和  Epilogue 以实现  Caller-Saved  寄存器的保留及恢复. Resolver 的执行过程主要包括    3  个阶段: 首先, 其
                 开辟一块栈空间用于保存当前上下文的              Caller-Saved  寄存器, 并且为  Reentry  函数准备参数. 在  ORCJIT  具体实现
                 中, Reentry  根据  Trampoline 来匹配被  JIT  编译的目标函数, 因此需要通过$ra-32   计算出  Callee 的  Trampoline 入口
                 地址. 然后, 其调用    Reentry  实施  Callee 函数的  JIT  编译, 并使用  Callee 函数的实际加载地址更新   TargetAddr 中的
                 内容. 最后, 其从栈上恢复被保留的          Caller-Saved  寄存器, 从$t11  中恢复被保留的  Callee 函数返回地址, 并且通过
                 寄存器间接转移跳转到        Callee 函数的实际入口地址开始执行.
                    如图   3  所示, 当  Callee  函数被首次调用时, ORCJIT   的执行路径依次经过         1-2-3-4-5-6-7-8. 而在后续调用
                 Callee 函数时, 无需再重复复杂的      Stub  解析与函数编译流程, 执行路径简化为          1-2'. 通过提供面向   SW26010Pro  的
                 ORCJIT  以及惰性编译等功能, 本文有效支撑了          Julia 在  MPE  上的动态运行, 并且为充分利用硬件特性开展针对性
                 的编译优化奠定了基础.


                            LLLazyJITBuilder  …         Stub manager     …      Trampoline manager

                               Add module                Materialize               Materialize
                               IR module             StubsBlockWorkingMem    TrampolineBlockWorkingMem
                                                    …                         …
                         JIT Entry:
                                                1                             Trampoline:
                         Caller:                    Stub:                      MV $ra, $t11
                           …                          MV TargetAddr, $pv  2
                           MV Stub, $pv               LD $pv, 0($pv)           MV Resolver, $pv  32 B
                                                                               …
                           CALL ($pc→$ra), $pv   2′   JMP $pv                  CALL($pc→$ra), $pv
                           …                        …                         …
                         …
                                                           Update
                         Callee:                                                      3
                           …
                                                Emit  //JIT Compile Callee      ResolverWorkingMem
                           RET $ra                  Reentry:
                                                     …                        …
                                  8
                                                     //Update TargetAddr
                                                     …                        Resolver:
                           //Restore regs            MV Callee, $v0            //Preserve regs
                           LD $v0,0($sp)             RET $ra                   MV $sp-456, $sp
                           LD $a0,8($sp)                                       ST $v0, 0($sp)
                           …                           6         5             ST $a0, 8($sp)
                           MV $sp+456, $sp                                     …
                                                     // Call Reentry
                           //Jump to Callee                                    //Prepare Reentry args
                           MV $t11, $ra        7     MV Reentry, $pv     4     MV ctx, $a0
                           MV $v0, $pv               CALL ($pc→$ra), $pv       MV $ra-32, $a1
                           JMP $pv                   …                         …
                                         图 3 SW26010Pro  后端中  ORCJIT  惰性编译流程

                  2.2   LLVM.jl
                           [12]
                    LLVM.jl  是一个在    Julia 环境中为集成   LLVM  工具而设计的第三方库. 该库通过为           LLVM API 提供高级封
                 装, 充分利用   Julia 强大的外部函数接口      (foreign function interface, FFI), 实现与底层运行时和加速计算库的高效交
                 互. 借助  LLVM.jl, Julia 开发者能够更加便捷地利用      LLVM  的先进功能, 例如目标代码优化和平台代码生成, 进而
                 提升  Julia 代码的性能及其跨平台兼容性.
                    在  SW26010Pro  平台上, 我们基于   LLVM.jl 提供了面向    SW26010Pro  的优化编译器    swLLVM  及二进制工具
                 链的交互接口封装, 同时还针对          Julia 的动态特性增加了相应的编译优化支持. 如第            1.2  节所述, 由于  SW26010Pro
                 的  CPE  全面支持  GPC  方案, 使得动态库间的从核函数跳转成为可能. 动态程序访存行为复杂性的增加对片上存
                 储空间   LDM  的有效管理提出了更高的要求.
   21   22   23   24   25   26   27   28   29   30   31