use std::ffi::c_void;
use inkwell_internals::llvm_versions;
use super::{
FunctionAnalysisManager, FunctionPassManager, ModuleAnalysisManager, ModulePassManager,
};
pub struct PassBuilder {
inner: *mut c_void,
}
impl PassBuilder {
#[doc(hidden)]
pub unsafe fn from_raw(pass_builder: *mut c_void) -> Self {
Self {
inner: pass_builder,
}
}
pub fn add_module_pipeline_parsing_callback<T>(&mut self, cb: T)
where
T: Fn(&str, &mut ModulePassManager) -> PipelineParsing + 'static,
{
let cb = Box::new(cb);
extern "C" fn callback_deleter<T>(cb: *const c_void) {
drop(unsafe { Box::<T>::from_raw(cb as *mut _) })
}
extern "C" fn callback_entrypoint<T>(
cb: *const c_void,
name_ptr: *const u8,
name_len: usize,
manager: *mut c_void,
) -> bool
where
T: Fn(&str, &mut ModulePassManager) -> PipelineParsing + 'static,
{
let cb = unsafe { Box::<T>::from_raw(cb as *mut _) };
let name = unsafe { std::slice::from_raw_parts(name_ptr, name_len) };
let name = unsafe { std::str::from_utf8_unchecked(name) };
let mut manager = unsafe { ModulePassManager::from_raw(manager) };
let res = cb(name, &mut manager);
Box::into_raw(cb);
matches!(res, PipelineParsing::Parsed)
}
unsafe {
super::passBuilderAddModulePipelineParsingCallback(
self.inner,
Box::into_raw(cb).cast(),
callback_deleter::<T>,
callback_entrypoint::<T>,
)
}
}
pub fn add_function_pipeline_parsing_callback<T>(&mut self, cb: T)
where
T: Fn(&str, &mut FunctionPassManager) -> PipelineParsing + 'static,
{
let cb = Box::new(cb);
extern "C" fn callback_deleter<T>(cb: *const c_void) {
drop(unsafe { Box::<T>::from_raw(cb as *mut _) })
}
extern "C" fn callback_entrypoint<T>(
cb: *const c_void,
name_ptr: *const u8,
name_len: usize,
manager: *mut c_void,
) -> bool
where
T: Fn(&str, &mut FunctionPassManager) -> PipelineParsing + 'static,
{
let cb = unsafe { Box::<T>::from_raw(cb as *mut _) };
let name = unsafe { std::slice::from_raw_parts(name_ptr, name_len) };
let name = unsafe { std::str::from_utf8_unchecked(name) };
let mut manager = unsafe { FunctionPassManager::from_raw(manager) };
let res = cb(name, &mut manager);
Box::into_raw(cb);
matches!(res, PipelineParsing::Parsed)
}
unsafe {
super::passBuilderAddFunctionPipelineParsingCallback(
self.inner,
Box::into_raw(cb).cast(),
callback_deleter::<T>,
callback_entrypoint::<T>,
)
}
}
pub fn add_module_analysis_registration_callback<T>(&mut self, cb: T)
where
T: Fn(&mut ModuleAnalysisManager) + 'static,
{
let cb = Box::new(cb);
extern "C" fn callback_deleter<T>(cb: *const c_void) {
drop(unsafe { Box::<T>::from_raw(cb as *mut _) })
}
extern "C" fn callback_entrypoint<T>(cb: *const c_void, manager: *mut c_void)
where
T: Fn(&mut ModuleAnalysisManager) + 'static,
{
let cb = unsafe { Box::<T>::from_raw(cb as *mut _) };
let mut manager = unsafe { ModuleAnalysisManager::from_raw(manager, None) };
cb(&mut manager);
Box::into_raw(cb);
}
unsafe {
super::passBuilderAddModuleAnalysisRegistrationCallback(
self.inner,
Box::into_raw(cb).cast(),
callback_deleter::<T>,
callback_entrypoint::<T>,
)
}
}
pub fn add_function_analysis_registration_callback<T>(&mut self, cb: T)
where
T: Fn(&mut FunctionAnalysisManager) + 'static,
{
let cb = Box::new(cb);
extern "C" fn callback_deleter<T>(cb: *const c_void) {
drop(unsafe { Box::<T>::from_raw(cb as *mut _) })
}
extern "C" fn callback_entrypoint<T>(cb: *const c_void, manager: *mut c_void)
where
T: Fn(&mut FunctionAnalysisManager) + 'static,
{
let cb = unsafe { Box::<T>::from_raw(cb as *mut _) };
let mut manager = unsafe { FunctionAnalysisManager::from_raw(manager, None) };
cb(&mut manager);
Box::into_raw(cb);
}
unsafe {
super::passBuilderAddFunctionAnalysisRegistrationCallback(
self.inner,
Box::into_raw(cb).cast(),
callback_deleter::<T>,
callback_entrypoint::<T>,
)
}
}
pub fn add_peephole_ep_callback<T>(&mut self, cb: T)
where
T: Fn(&mut FunctionPassManager, OptimizationLevel) + 'static,
{
let cb = Box::new(cb);
extern "C" fn callback_deleter<T>(cb: *const c_void) {
drop(unsafe { Box::<T>::from_raw(cb as *mut _) })
}
extern "C" fn callback_entrypoint<T>(
cb: *const c_void,
manager: *mut c_void,
opt: OptimizationLevel,
) where
T: Fn(&mut FunctionPassManager, OptimizationLevel) + 'static,
{
let cb = unsafe { Box::<T>::from_raw(cb as *mut _) };
let mut manager = unsafe { FunctionPassManager::from_raw(manager) };
cb(&mut manager, opt);
Box::into_raw(cb);
}
unsafe {
super::passBuilderAddPeepholeEPCallback(
self.inner,
Box::into_raw(cb).cast(),
callback_deleter::<T>,
callback_entrypoint::<T>,
)
}
}
pub fn add_scalar_optimizer_late_ep_callback<T>(&mut self, cb: T)
where
T: Fn(&mut FunctionPassManager, OptimizationLevel) + 'static,
{
let cb = Box::new(cb);
extern "C" fn callback_deleter<T>(cb: *const c_void) {
drop(unsafe { Box::<T>::from_raw(cb as *mut _) })
}
extern "C" fn callback_entrypoint<T>(
cb: *const c_void,
manager: *mut c_void,
opt: OptimizationLevel,
) where
T: Fn(&mut FunctionPassManager, OptimizationLevel) + 'static,
{
let cb = unsafe { Box::<T>::from_raw(cb as *mut _) };
let mut manager = unsafe { FunctionPassManager::from_raw(manager) };
cb(&mut manager, opt);
Box::into_raw(cb);
}
unsafe {
super::passBuilderAddScalarOptimizerLateEPCallback(
self.inner,
Box::into_raw(cb).cast(),
callback_deleter::<T>,
callback_entrypoint::<T>,
)
}
}
pub fn add_vectorizer_start_ep_callback<T>(&mut self, cb: T)
where
T: Fn(&mut FunctionPassManager, OptimizationLevel) + 'static,
{
let cb = Box::new(cb);
extern "C" fn callback_deleter<T>(cb: *const c_void) {
drop(unsafe { Box::<T>::from_raw(cb as *mut _) })
}
extern "C" fn callback_entrypoint<T>(
cb: *const c_void,
manager: *mut c_void,
opt: OptimizationLevel,
) where
T: Fn(&mut FunctionPassManager, OptimizationLevel) + 'static,
{
let cb = unsafe { Box::<T>::from_raw(cb as *mut _) };
let mut manager = unsafe { FunctionPassManager::from_raw(manager) };
cb(&mut manager, opt);
Box::into_raw(cb);
}
unsafe {
super::passBuilderAddVectorizerStartEPCallback(
self.inner,
Box::into_raw(cb).cast(),
callback_deleter::<T>,
callback_entrypoint::<T>,
)
}
}
#[llvm_versions(12.0..=latest)]
pub fn add_pipeline_start_ep_callback<T>(&mut self, cb: T)
where
T: Fn(&mut ModulePassManager, OptimizationLevel) + 'static,
{
let cb = Box::new(cb);
extern "C" fn callback_deleter<T>(cb: *const c_void) {
drop(unsafe { Box::<T>::from_raw(cb as *mut _) })
}
extern "C" fn callback_entrypoint<T>(
cb: *const c_void,
manager: *mut c_void,
opt: OptimizationLevel,
) where
T: Fn(&mut ModulePassManager, OptimizationLevel) + 'static,
{
let cb = unsafe { Box::<T>::from_raw(cb as *mut _) };
let mut manager = unsafe { ModulePassManager::from_raw(manager) };
cb(&mut manager, opt);
Box::into_raw(cb);
}
unsafe {
super::passBuilderAddPipelineStartEPCallback(
self.inner,
Box::into_raw(cb).cast(),
callback_deleter::<T>,
callback_entrypoint::<T>,
)
}
}
#[llvm_versions(12.0..=latest)]
pub fn add_pipeline_early_simplification_ep_callback<T>(&mut self, cb: T)
where
T: Fn(&mut ModulePassManager, OptimizationLevel) + 'static,
{
let cb = Box::new(cb);
extern "C" fn callback_deleter<T>(cb: *const c_void) {
drop(unsafe { Box::<T>::from_raw(cb as *mut _) })
}
extern "C" fn callback_entrypoint<T>(
cb: *const c_void,
manager: *mut c_void,
opt: OptimizationLevel,
) where
T: Fn(&mut ModulePassManager, OptimizationLevel) + 'static,
{
let cb = unsafe { Box::<T>::from_raw(cb as *mut _) };
let mut manager = unsafe { ModulePassManager::from_raw(manager) };
cb(&mut manager, opt);
Box::into_raw(cb);
}
unsafe {
super::passBuilderAddPipelineEarlySimplificationEPCallback(
self.inner,
Box::into_raw(cb).cast(),
callback_deleter::<T>,
callback_entrypoint::<T>,
)
}
}
#[llvm_versions(11.0..=latest)]
pub fn add_optimizer_last_ep_callback<T>(&mut self, cb: T)
where
T: Fn(&mut ModulePassManager, OptimizationLevel) + 'static,
{
let cb = Box::new(cb);
extern "C" fn callback_deleter<T>(cb: *const c_void) {
drop(unsafe { Box::<T>::from_raw(cb as *mut _) })
}
extern "C" fn callback_entrypoint<T>(
cb: *const c_void,
manager: *mut c_void,
opt: OptimizationLevel,
) where
T: Fn(&mut ModulePassManager, OptimizationLevel) + 'static,
{
let cb = unsafe { Box::<T>::from_raw(cb as *mut _) };
let mut manager = unsafe { ModulePassManager::from_raw(manager) };
cb(&mut manager, opt);
Box::into_raw(cb);
}
unsafe {
super::passBuilderAddOptimizerLastEPCallback(
self.inner,
Box::into_raw(cb).cast(),
callback_deleter::<T>,
callback_entrypoint::<T>,
)
}
}
#[llvm_versions(15.0..=latest)]
pub fn add_full_lto_early_ep_callback<T>(&mut self, cb: T)
where
T: Fn(&mut ModulePassManager, OptimizationLevel) + 'static,
{
let cb = Box::new(cb);
extern "C" fn callback_deleter<T>(cb: *const c_void) {
drop(unsafe { Box::<T>::from_raw(cb as *mut _) })
}
extern "C" fn callback_entrypoint<T>(
cb: *const c_void,
manager: *mut c_void,
opt: OptimizationLevel,
) where
T: Fn(&mut ModulePassManager, OptimizationLevel) + 'static,
{
let cb = unsafe { Box::<T>::from_raw(cb as *mut _) };
let mut manager = unsafe { ModulePassManager::from_raw(manager) };
cb(&mut manager, opt);
Box::into_raw(cb);
}
unsafe {
super::passBuilderAddFullLinkTimeOptimizationEarlyEPCallback(
self.inner,
Box::into_raw(cb).cast(),
callback_deleter::<T>,
callback_entrypoint::<T>,
)
}
}
#[llvm_versions(15.0..=latest)]
pub fn add_full_lto_last_ep_callback<T>(&mut self, cb: T)
where
T: Fn(&mut ModulePassManager, OptimizationLevel) + 'static,
{
let cb = Box::new(cb);
extern "C" fn callback_deleter<T>(cb: *const c_void) {
drop(unsafe { Box::<T>::from_raw(cb as *mut _) })
}
extern "C" fn callback_entrypoint<T>(
cb: *const c_void,
manager: *mut c_void,
opt: OptimizationLevel,
) where
T: Fn(&mut ModulePassManager, OptimizationLevel) + 'static,
{
let cb = unsafe { Box::<T>::from_raw(cb as *mut _) };
let mut manager = unsafe { ModulePassManager::from_raw(manager) };
cb(&mut manager, opt);
Box::into_raw(cb);
}
unsafe {
super::passBuilderAddFullLinkTimeOptimizationLastEPCallback(
self.inner,
Box::into_raw(cb).cast(),
callback_deleter::<T>,
callback_entrypoint::<T>,
)
}
}
#[llvm_versions(15.0..=latest)]
pub fn add_optimizer_early_ep_callback<T>(&mut self, cb: T)
where
T: Fn(&mut ModulePassManager, OptimizationLevel) + 'static,
{
let cb = Box::new(cb);
extern "C" fn callback_deleter<T>(cb: *const c_void) {
drop(unsafe { Box::<T>::from_raw(cb as *mut _) })
}
extern "C" fn callback_entrypoint<T>(
cb: *const c_void,
manager: *mut c_void,
opt: OptimizationLevel,
) where
T: Fn(&mut ModulePassManager, OptimizationLevel) + 'static,
{
let cb = unsafe { Box::<T>::from_raw(cb as *mut _) };
let mut manager = unsafe { ModulePassManager::from_raw(manager) };
cb(&mut manager, opt);
Box::into_raw(cb);
}
unsafe {
super::passBuilderAddOptimizerEarlyEPCallback(
self.inner,
Box::into_raw(cb).cast(),
callback_deleter::<T>,
callback_entrypoint::<T>,
)
}
}
}
#[derive(Clone, Copy)]
pub enum PipelineParsing {
Parsed,
NotParsed,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub enum OptimizationLevel {
O0,
O1,
O2,
O3,
Os,
Oz,
}