Optimization passes¶
LLVM gives you the opportunity to fine-tune optimization passes. Optimization passes are managed by a pass manager. There are two kinds of pass managers:
FunctionPassManager
, for optimizations that work on single functions.ModulePassManager
, for optimizations that work on whole modules.
llvmlite provides bindings for LLVM’s New and Legacy pass managers, which have slightly different APIs and behaviour. The differences between them and the motivations for the New Pass Manager are outlined in the LLVM Blog post on the New Pass Manager.
In a future version of llvmlite, likely coinciding with a minimum LLVM version requirement of 17, support for the Legacy Pass Manager will be removed. It is recommended that new code using llvmlite uses the New Pass Manager, and existing code using the Legacy Pass Manager be updated to use the New Pass Manager.
New Pass Manager APIs¶
To manage the optimization attributes we first need to instantiate a
PipelineTuningOptions
instance:
- class llvmlite.binding.PipelineTuningOptions(speed_level=2, size_level=0)¶
Creates a new PipelineTuningOptions object.
The following writable attributes are available, whose default values depend on the initial setting of the speed and size optimization levels:
- loop_interleaving¶
Enable loop interleaving.
- loop_vectorization¶
Enable loop vectorization.
- slp_vectorization¶
Enable SLP vectorization, which uses a different algorithm to loop vectorization. Both may be enabled at the same time.
- loop_unrolling¶
Enable loop unrolling.
- speed_level¶
The level of optimization for speed, as an integer between 0 and 3.
- size_level¶
The level of optimization for size, as an integer between 0 and 2.
We also need a PassBuilder
object to manage the respective function
and module pass managers:
- class llvmlite.binding.PassBuilder(target_machine, pipeline_tuning_options)¶
A pass builder that uses the given
TargetMachine
andPipelineTuningOptions
instances.- getModulePassManager()¶
Return a populated
ModulePassManager
object based on PTO settings.
- getFunctionPassManager()¶
Return a populated
FunctionPassManager
object based on PTO settings.
The ModulePassManager
and FunctionPassManager
classes
implement the module and function pass managers:
- class llvmlite.binding.ModulePassManager¶
A pass manager for running optimization passes on an LLVM module.
- add_verifier()¶
Add the Module Verifier pass.
- class llvmlite.binding.FunctionPassManager¶
A pass manager for running optimization passes on an LLVM function.
These can be created with passes populated by using the
PassBuilder.getModulePassManager()
and
PassBuilder.getFunctionPassManager()
methods, or they can be instantiated
unpopulated, then passes can be added using the add_*
methods.
To instantiate the unpopulated instances, use:
- llvmlite.binding.create_new_module_pass_manager()¶
Create an unpopulated
ModulePassManager
instance.
and
- llvmlite.binding.create_new_function_pass_manager()¶
Create an unpopulated
FunctionPassManager
instance.
The add_*
methods supported by both pass manager classes are:
- add_aa_eval_pass()¶
Add the Exhaustive Alias Analysis Precision Evaluator pass.
- add_loop_unroll_pass()¶
Add the Loop Unroll pass.
- add_loop_rotate_pass()¶
Add the Loop Rotate pass.
- add_instruction_combine_pass()¶
Add the Combine Redundant Instructions pass.
- add_jump_threading_pass()¶
Add the Jump Threading pass.
- add_simplify_cfg_pass()¶
Add the Simplify CFG pass.
- add_refprune_pass()¶
Add the Reference pruning pass.
Legacy Pass Manager APIs¶
To instantiate either of these pass managers, you first need to
create and configure a PassManagerBuilder
.
- class llvmlite.binding.PassManagerBuilder¶
Create a new pass manager builder. This object centralizes optimization settings.
The
populate
method is available:- populate(pm)¶
Populate the pass manager pm with the optimization passes configured in this pass manager builder.
The following writable attributes are available:
- disable_unroll_loops¶
If
True
, disable loop unrolling.
- inlining_threshold¶
The integer threshold for inlining one function into another. The higher the number, the more likely that inlining will occur. This attribute is write-only.
- loop_vectorize¶
If
True
, allow vectorizing loops.
- opt_level¶
The general optimization level, as an integer between 0 and 3.
- size_level¶
Whether and how much to optimize for size, as an integer between 0 and 2.
- slp_vectorize¶
If
True
, enable the SLP vectorizer, which uses a different algorithm than the loop vectorizer. Both may be enabled at the same time.
- class llvmlite.binding.PassManager¶
The base class for pass managers. Use individual
add_*
methods orPassManagerBuilder.populate()
to add optimization passes.- add_constant_merge_pass()¶
- add_dead_arg_elimination_pass()¶
- add_function_attrs_pass()¶
- add_function_inlining_pass(self)¶
- add_global_dce_pass()¶
- add_global_optimizer_pass()¶
- add_ipsccp_pass()¶
- add_dead_code_elimination_pass()¶
- add_cfg_simplification_pass()¶
- add_gvn_pass()¶
- add_instruction_combining_pass()¶
- add_licm_pass()¶
- add_sccp_pass()¶
- add_sroa_pass()¶
See scalarrepl pass documentation.
While the scalarrepl pass documentation describes the transformation performed by the pass added by this function, the pass corresponds to the
opt -sroa
command-line option and not toopt -scalarrepl
.
- add_type_based_alias_analysis_pass()¶
- add_basic_alias_analysis_pass()¶
- add_instruction_namer_pass()¶
- add_refprune_pass()¶
Add the Reference pruning pass.
- class llvmlite.binding.ModulePassManager
Create a new pass manager to run optimization passes on a module.
The
run
method is available:- run(module)
Run optimization passes on the module, a
ModuleRef
instance.Returns
True
if the optimizations made any modification to the module. Otherwise returnsFalse
.
- class llvmlite.binding.FunctionPassManager(module)
Create a new pass manager to run optimization passes on a function of the given module, a
ModuleRef
instance.The following methods are available: