use std::sync::Arc;
use analyssa::scheduling::{PassScheduler as AnalyssaPassScheduler, PipelineConfig};
use crate::{
analysis::CilTarget,
compiler::{
context::CompilerContext,
pass::{PassPhase, SsaPass},
state::ProcessingState,
},
CilObject, Error, Result,
};
pub struct PassScheduler {
inner: AnalyssaPassScheduler<CilTarget, CompilerContext>,
}
impl Default for PassScheduler {
fn default() -> Self {
Self::new(5, 2, 15)
}
}
impl PassScheduler {
#[must_use]
pub fn new(
max_iterations: usize,
stable_iterations: usize,
max_phase_iterations: usize,
) -> Self {
let config = PipelineConfig {
max_iterations,
stable_iterations,
max_phase_iterations,
..PipelineConfig::default()
};
Self {
inner: AnalyssaPassScheduler::empty(config),
}
}
#[must_use]
pub fn pass_count(&self) -> usize {
self.inner.pass_count()
}
#[must_use]
pub fn normalize_count(&self) -> usize {
self.inner.normalize_count()
}
pub fn add(&mut self, pass: Box<dyn SsaPass<CilTarget, CompilerContext>>, phase: PassPhase) {
match phase {
PassPhase::Normalize => self.inner.add_normalize(pass),
other => self.inner.add_at_layer(pass, other.as_layer()),
}
}
pub fn run_pipeline(
&mut self,
ctx: &CompilerContext,
assembly: &Arc<CilObject>,
_state: Option<&ProcessingState>,
) -> Result<usize> {
ctx.set_assembly(assembly.clone());
let result = self
.inner
.run_pipeline(ctx)
.map_err(|e| Error::SsaError(e.0));
ctx.clear_assembly();
result
}
}