优化遍数

LLVM 提供了微调优化遍数的机会。优化遍数由遍数管理器管理。有两种遍数管理器:

llvmlite 为 LLVM 的遍数管理器提供了绑定,它们具有略有不同的 API 和行为。它们之间的差异以及新遍数管理器的动机在LLVM 博客关于新遍数管理器的文章中有所概述。

在 llvmlite 的未来版本中,可能与 LLVM 最低版本要求 17 同时,将移除对旧遍数管理器的支持。建议使用 llvmlite 的新代码使用新遍数管理器,并更新使用旧遍数管理器的现有代码以使用新遍数管理器。

新遍数管理器API

为了管理优化属性,我们首先需要实例化一个PipelineTuningOptions实例

class llvmlite.binding.PipelineTuningOptions(speed_level=2, size_level=0)

创建一个新的 PipelineTuningOptions 对象。

以下是可用的可写属性,其默认值取决于速度和大小优化级别的初始设置

  • loop_interleaving

    启用循环交错。

  • loop_vectorization

    启用循环向量化。

  • slp_vectorization

    启用 SLP 向量化,它使用与循环向量化不同的算法。两者可以同时启用。

  • loop_unrolling

    启用循环展开。

  • speed_level

    速度优化级别,一个介于 0 和 3 之间的整数。

  • size_level

    大小优化级别,一个介于 0 和 2 之间的整数。

我们还需要一个PassBuilder对象来管理相应的函数和模块遍数管理器

class llvmlite.binding.PassBuilder(target_machine, pipeline_tuning_options)

一个遍数构建器,使用给定的 TargetMachinePipelineTuningOptions 实例。

getModulePassManager()

根据 PTO 设置返回一个已填充的 ModulePassManager 对象。

getFunctionPassManager()

根据 PTO 设置返回一个已填充的 FunctionPassManager 对象。

start_pass_timing()

启用遍数计时器。

finish_pass_timing()

返回一个包含 LLVM 生成的计时报告的字符串,并禁用遍数计时器。

ModulePassManagerFunctionPassManager 类实现了模块和函数遍数管理器

class llvmlite.binding.ModulePassManager

一个用于在 LLVM 模块上运行优化遍数的遍数管理器。

add_verifier()

添加模块验证器 (Module Verifier) 遍数。

run(module, passbuilder)

在*模块*(一个 ModuleRef 实例)上运行优化遍数。

class llvmlite.binding.FunctionPassManager

一个用于在 LLVM 函数上运行优化遍数的遍数管理器。

run(function, passbuilder)

在*函数*(一个 ValueRef 实例)上运行优化遍数。

可以通过使用 PassBuilder.getModulePassManager()PassBuilder.getFunctionPassManager() 方法来创建已填充遍数的这些管理器,或者实例化未填充的管理器,然后使用 add_* 方法添加遍数。

要实例化未填充的实例,请使用

llvmlite.binding.create_new_module_pass_manager()

创建一个未填充的 ModulePassManager 实例。

llvmlite.binding.create_new_function_pass_manager()

创建一个未填充的 FunctionPassManager 实例。

这两个遍数管理器类都支持的 add_* 方法有

add_aa_eval_pass()

添加穷举别名分析精度评估器 (Exhaustive Alias Analysis Precision Evaluator) 遍数。

add_loop_unroll_pass()

添加循环展开 (Loop Unroll) 遍数。

add_loop_rotate_pass()

添加循环旋转 (Loop Rotate) 遍数。

add_instruction_combine_pass()

添加组合冗余指令 (Combine Redundant Instructions) 遍数。

add_jump_threading_pass()

添加跳转穿线 (Jump Threading) 遍数。

add_simplify_cfg_pass()

添加简化控制流图 (Simplify CFG) 遍数。

add_refprune_pass()

添加引用剪枝 (Reference pruning) 遍数。

旧遍数管理器API

要实例化这些遍数管理器中的任何一个,您首先需要创建并配置一个 PassManagerBuilder

class llvmlite.binding.PassManagerBuilder

创建一个新的遍数管理器构建器。此对象集中管理优化设置。

populate 方法可用

populate(pm)

使用此遍数管理器构建器中配置的优化遍数填充遍数管理器 *pm*。

以下是可用的可写属性

  • disable_unroll_loops

    如果为 True,则禁用循环展开。

  • inlining_threshold

    将一个函数内联到另一个函数中的整数阈值。数值越高,内联发生的可能性越大。此属性只写。

  • loop_vectorize

    如果为 True,则允许循环向量化。

  • opt_level

    通用优化级别,一个介于 0 和 3 之间的整数。

  • size_level

    是否以及如何对大小进行优化,一个介于 0 和 2 之间的整数。

  • slp_vectorize

    如果为 True,则启用 SLP 向量化器,它使用与循环向量化器不同的算法。两者可以同时启用。

class llvmlite.binding.PassManager

遍数管理器的基类。使用各个 add_* 方法或 PassManagerBuilder.populate() 来添加优化遍数。

class llvmlite.binding.ModulePassManager

创建一个新的遍数管理器,用于在模块上运行优化遍数。

run 方法可用

run(module)

在*模块*(一个 ModuleRef 实例)上运行优化遍数。

如果优化对模块进行了任何修改,则返回 True。否则返回 False

class llvmlite.binding.FunctionPassManager(module)

创建一个新的遍数管理器,用于在给定*模块*(一个 ModuleRef 实例)的一个函数上运行优化遍数。

以下方法可用

  • finalize()

    运行所有优化遍数的终结器。

  • initialize()

    运行所有优化遍数的初始化器。

  • run(function)

    在*函数*(一个 ValueRef 实例)上运行优化遍数。

    如果优化对模块进行了任何修改,则返回 True。否则返回 False