Optimization
This section covers optimization passes and utilities provided by Lotus. These passes are useful for preparing code for analysis or for improving performance. They complement the code transformations available in Transforms.
Headers: include/Optimization
Implementation: lib/Optimization
ModuleOptimizer
File: lib/Optimization/Pipeline/ModuleOptimizer.cpp, include/Optimization/Pipeline/ModuleOptimizer.h
Provides a simple interface for applying standard LLVM optimization pipelines (O0, O1, O2, or O3) to an entire module.
Usage:
#include <Optimization/Pipeline/ModuleOptimizer.h>
llvm::Module *M = ...;
// Apply O2 optimizations
llvm_utils::optimiseModule(M, llvm::OptimizationLevel::O2);
When to use:
Apply standard LLVM optimizations before running analyses
Prepare code for verification or further transformation
Test analysis tools on optimized code
AInliner (Aggressive Inliner)
File: lib/Optimization/Scalar/AggressiveInliner.cpp
An aggressive inliner that attempts to inline as many function calls as possible. This pass is tuned for analysis-friendly IR where maximum inlining may be beneficial.
Features:
Inlines function calls aggressively
Supports exclusion list via
-ainline-noinlinecommand-line optionOperates at the module level
Command-line options:
-ainline-noinline="func1,func2" # Functions to exclude from inlining
When to use:
Reduce inter-procedural complexity for analysis
Improve precision of intra-procedural analyses
Prepare code where maximum inlining is desired
Limitations:
May significantly increase code size
Use with caution on large codebases
LICM (Loop Invariant Code Motion)
File: lib/Optimization/Scalar/LICM.cpp, include/Optimization/Scalar/LICM.h
Loop Invariant Code Motion pass taken from LLVM 14. This pass moves loop-invariant code out of loops to improve performance.
Features:
Hoists loop-invariant instructions to loop preheader
Sinks code to exit blocks when safe
Promotes must-aliased memory locations to registers
Uses alias analysis for precise memory operations
When to use:
Optimize loops by moving invariant computations outside
Evaluate alias analysis precision (LICM relies on alias analysis)
Improve code before analysis or verification
Note: This is the LLVM 14 version of LICM, used internally by Lotus for evaluating alias analysis algorithms.
SWPrefetching (Software Prefetching)
See SWPrefetching (Software Prefetching) for details on the profile-guided software prefetching pass.
MemorySSA Optimizations
Interprocedural optimizations that use MemorySSA instrumentation (ShadowMem):
IPDeadStoreElimination: removes stores (and some global initializers) whose shadow.mem def-use chains never reach a load. Traverses into callees/callers via shadow.mem.arg.* and shadow.mem.in/out.IPRedundantLoadElimination: within a block, removes repeated loads when the MemorySSA version (TLVar) and pointer operand are identical and no memory side effects intervene.IPStoreToLoadForwarding: replaces loads with the unique reaching store value by following MemorySSA def-use chains across calls/phis. Rewrites when exactly one non-conflicting value is found.IPStoreSinking: sinks stores (and their shadow.mem.store) forward within a block to just before the first observed use when instructions in between are side-effect free.
All implemented under lib/Optimization/IPO and default to singleton regions
unless configured otherwise.
See Interprocedural MemorySSA Optimizations for the dedicated page for the lib/Optimization/IPO/ subtree.
Integration with Analysis
These optimization passes can be used to prepare code for analysis:
#include <Optimization/Pipeline/ModuleOptimizer.h>
#include <Optimization/Prefetch/Prefetch.h>
llvm::Module &M = ...;
// Apply standard optimizations
llvm_utils::optimiseModule(&M, llvm::OptimizationLevel::O1);
// Then run analyses
// ...
Typical pipeline:
Apply optimizations (ModuleOptimizer, AInliner, etc.)
Run alias analysis or other static analyses
Perform verification or bug detection