aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/llvm/pass_manager.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/llvm/pass_manager.rs')
-rw-r--r--src/llvm/pass_manager.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/llvm/pass_manager.rs b/src/llvm/pass_manager.rs
new file mode 100644
index 0000000..1551875
--- /dev/null
+++ b/src/llvm/pass_manager.rs
@@ -0,0 +1,75 @@
+use llvm_sys::{
+ core::{
+ LLVMCreateFunctionPassManagerForModule, LLVMDisposePassManager,
+ LLVMInitializeFunctionPassManager, LLVMRunFunctionPassManager,
+ },
+ prelude::LLVMPassManagerRef,
+ transforms::{
+ instcombine::LLVMAddInstructionCombiningPass,
+ scalar::{LLVMAddCFGSimplificationPass, LLVMAddNewGVNPass, LLVMAddReassociatePass},
+ },
+};
+
+use std::marker::PhantomData;
+
+use super::{FnValue, Module};
+
+/// Wrapper for a LLVM Function PassManager (legacy).
+pub struct FunctionPassManager<'llvm> {
+ fpm: LLVMPassManagerRef,
+ _ctx: PhantomData<&'llvm ()>,
+}
+
+impl<'llvm> FunctionPassManager<'llvm> {
+ /// Create a new Function PassManager with the following optimization passes
+ /// - InstructionCombiningPass
+ /// - ReassociatePass
+ /// - NewGVNPass
+ /// - CFGSimplificationPass
+ ///
+ /// The list of selected optimization passes is taken from the tutorial chapter [LLVM
+ /// Optimization Passes](https://llvm.org/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.html#id3).
+ pub fn with_ctx(module: &'llvm Module) -> FunctionPassManager<'llvm> {
+ let fpm = unsafe {
+ // Borrows module reference.
+ LLVMCreateFunctionPassManagerForModule(module.module())
+ };
+ assert!(!fpm.is_null());
+
+ unsafe {
+ // Do simple "peephole" optimizations and bit-twiddling optzns.
+ LLVMAddInstructionCombiningPass(fpm);
+ // Reassociate expressions.
+ LLVMAddReassociatePass(fpm);
+ // Eliminate Common SubExpressions.
+ LLVMAddNewGVNPass(fpm);
+ // Simplify the control flow graph (deleting unreachable blocks, etc).
+ LLVMAddCFGSimplificationPass(fpm);
+
+ let fail = LLVMInitializeFunctionPassManager(fpm);
+ assert_eq!(fail, 0);
+ }
+
+ FunctionPassManager {
+ fpm,
+ _ctx: PhantomData,
+ }
+ }
+
+ /// Run the optimization passes registered with the Function PassManager on the function
+ /// referenced by `fn_value`.
+ pub fn run(&'llvm self, fn_value: FnValue<'llvm>) {
+ unsafe {
+ // Returns 1 if any of the passes modified the function, false otherwise.
+ LLVMRunFunctionPassManager(self.fpm, fn_value.value_ref());
+ }
+ }
+}
+
+impl Drop for FunctionPassManager<'_> {
+ fn drop(&mut self) {
+ unsafe {
+ LLVMDisposePassManager(self.fpm);
+ }
+ }
+}