Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions compiler/src/compiler/analysis/instrumenter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2621,7 +2621,9 @@ mod tests {
});
entry.set_terminator(Terminator::Return(vec![result]));

InstructionLowering::witness_integer_ops().run(&mut ssa, &AnalysisStore::new());
InstructionLowering::witness_integer_ops()
.run(&mut ssa, &AnalysisStore::new())
.unwrap();
let flow = FlowAnalysis::run(&ssa);
let type_info = Types::new().run(&ssa, &flow);
let costs = CostEstimator::new().run(&ssa, &type_info);
Expand Down Expand Up @@ -2655,7 +2657,9 @@ mod tests {
});
entry.set_terminator(Terminator::Return(vec![result]));

InstructionLowering::witness_integer_ops().run(&mut ssa, &AnalysisStore::new());
InstructionLowering::witness_integer_ops()
.run(&mut ssa, &AnalysisStore::new())
.unwrap();
let flow = FlowAnalysis::run(&ssa);
let type_info = Types::new().run(&ssa, &flow);
let costs = CostEstimator::new().run(&ssa, &type_info);
Expand Down
7 changes: 5 additions & 2 deletions compiler/src/compiler/lowering/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ fn unit_bodies_and_empty_structs_have_one_typed_result_until_tuple_elision() {
let expected = TypeConverter::new().convert_type(&return_type);
let mut ssa = lower(vec![function(0, body, return_type)]);
assert_return_shape(&ssa, &[expected.clone()]);
PassManager::new(name.into(), false, vec![Box::new(ElideTuples::new())]).run(&mut ssa);
PassManager::new(name.into(), false, vec![Box::new(ElideTuples::new())])
.run(&mut ssa)
.unwrap();
assert_return_shape(&ssa, &after);
}
}
Expand Down Expand Up @@ -349,7 +351,8 @@ fn direct_and_indirect_unit_calls_match_their_signatures() {
Box::new(ElideTuples::new()),
],
)
.run(&mut ssa);
.run(&mut ssa)
.unwrap();
assert_return_shape(&ssa, &[]);
for (_, function) in ssa.iter_functions() {
for (_, block) in function.get_blocks() {
Expand Down
29 changes: 19 additions & 10 deletions compiler/src/compiler/pass_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ use std::{

use crate::{
collections::HashMap,
compiler::ssa::{
DefaultSSAAnnotator, Instruction, SSA, SSAType,
hlssa::{Constant, OpCode, Type},
compiler::{
diagnostic::Diagnostic,
ssa::{
DefaultSSAAnnotator, Instruction, SSA, SSAType,
hlssa::{Constant, OpCode, Type},
},
},
};

Expand Down Expand Up @@ -179,6 +182,8 @@ impl AnalysisStore {
// Pass trait — parametric
// ---------------------------------------------------------------------------

pub type PassResult = Result<(), Vec<Diagnostic>>;

pub trait Pass<
Op: Instruction = OpCode,
Ty: SSAType = Type,
Expand All @@ -189,7 +194,7 @@ pub trait Pass<
fn needs(&self) -> Vec<AnalysisId> {
vec![]
}
fn run(&self, ssa: &mut SSA<Op, Ty, C>, store: &AnalysisStore);
fn run(&self, ssa: &mut SSA<Op, Ty, C>, store: &AnalysisStore) -> PassResult;
fn preserves(&self) -> Vec<AnalysisId> {
vec![]
}
Expand Down Expand Up @@ -260,7 +265,7 @@ impl<Op: Instruction, Ty: SSAType, C: Clone + Debug + Eq + Hash + 'static> PassM
}

#[tracing::instrument(skip_all, name = "PassManager::run", fields(phase = %self.phase_label))]
pub fn run(&mut self, ssa: &mut SSA<Op, Ty, C>) {
pub fn run(&mut self, ssa: &mut SSA<Op, Ty, C>) -> PassResult {
if let Some(debug_output_dir) = &self.debug_output_dir {
if debug_output_dir.exists() {
fs::remove_dir_all(debug_output_dir).unwrap();
Expand All @@ -269,11 +274,14 @@ impl<Op: Instruction, Ty: SSAType, C: Clone + Debug + Eq + Hash + 'static> PassM
}

let passes = std::mem::take(&mut self.passes);
for (i, pass) in passes.iter().enumerate() {
self.run_pass(ssa, pass.as_ref(), i);
}
let outcome = passes
.iter()
.enumerate()
.try_for_each(|(i, pass)| self.run_pass(ssa, pass.as_ref(), i));
self.passes = passes;
outcome?;
self.output_final_debug_info(ssa);
Ok(())
}

#[tracing::instrument(skip_all, fields(pass = %pass.name()))]
Expand All @@ -282,17 +290,18 @@ impl<Op: Instruction, Ty: SSAType, C: Clone + Debug + Eq + Hash + 'static> PassM
ssa: &mut SSA<Op, Ty, C>,
pass: &dyn Pass<Op, Ty, C>,
pass_index: usize,
) {
) -> PassResult {
// Ensure all needed analyses are computed (in dependency order)
let ordered = topo_sort(pass.needs(), &self.analyses);
for id in ordered {
(id.compute_and_store)(ssa as &dyn Any, &mut self.analyses);
}

self.output_debug_info(ssa, pass_index, pass.name());
pass.run(ssa, &self.analyses);
pass.run(ssa, &self.analyses)?;
self.analyses.apply_preserved(&pass.preserves());
self.output_pass_ssa_snapshot(ssa, pass_index, pass.name());
Ok(())
}

/// When `MAVROS_DUMP_PASS_SSA` names a directory, write the SSA text after every pass to
Expand Down
5 changes: 3 additions & 2 deletions compiler/src/compiler/passes/arg_promotion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ use crate::{
points_to::{PointerUse, PointsTo, object::AbstractObject},
types::{FunctionTypeInfo, TypeInfo},
},
pass_manager::{Analysis, AnalysisId, AnalysisStore, Pass},
pass_manager::{Analysis, AnalysisId, AnalysisStore, Pass, PassResult},
passes::shared::value_replacements::{ReplaceScope, ValueReplacements},
ssa::{
BlockId, FunctionId, SourceLocation, Terminator, ValueId,
Expand Down Expand Up @@ -120,8 +120,9 @@ impl Pass for ArgPromotion {
vec![TypeInfo::id(), PointsTo::id()]
}

fn run(&self, ssa: &mut HLSSA, store: &AnalysisStore) {
fn run(&self, ssa: &mut HLSSA, store: &AnalysisStore) -> PassResult {
self.do_run(ssa, store.get::<TypeInfo>(), store.get::<PointsTo>());
Ok(())
}

fn preserves(&self) -> Vec<AnalysisId> {
Expand Down
5 changes: 3 additions & 2 deletions compiler/src/compiler/passes/array_boundary_expansion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ use crate::{
collections::{HashMap, HashSet},
compiler::{
analysis::{points_to::PointsTo, types::TypeInfo},
pass_manager::{Analysis, AnalysisId, AnalysisStore, Pass},
pass_manager::{Analysis, AnalysisId, AnalysisStore, Pass, PassResult},
ssa::{
BlockId, FunctionId, SourceLocation, Terminator, ValueId,
hlssa::{
Expand Down Expand Up @@ -129,8 +129,9 @@ impl Pass for ArrayBoundaryExpansion {
vec![TypeInfo::id(), PointsTo::id()]
}

fn run(&self, ssa: &mut HLSSA, store: &AnalysisStore) {
fn run(&self, ssa: &mut HLSSA, store: &AnalysisStore) -> PassResult {
self.do_run(ssa, store.get::<TypeInfo>(), store.get::<PointsTo>());
Ok(())
}

fn preserves(&self) -> Vec<AnalysisId> {
Expand Down
5 changes: 3 additions & 2 deletions compiler/src/compiler/passes/array_sroa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ use crate::{
points_to::PointsTo,
types::{FunctionTypeInfo, TypeInfo},
},
pass_manager::{Analysis, AnalysisId, AnalysisStore, Pass},
pass_manager::{Analysis, AnalysisId, AnalysisStore, Pass, PassResult},
ssa::{
BlockId, FunctionId, Instruction, Terminator, ValueId,
hlssa::{Constant, HLSSA, OpCode, Type, TypeExpr},
Expand Down Expand Up @@ -85,13 +85,14 @@ impl Pass for ArraySroa {
vec![PointsTo::id(), TypeInfo::id(), FlowAnalysis::id()]
}

fn run(&self, ssa: &mut HLSSA, store: &AnalysisStore) {
fn run(&self, ssa: &mut HLSSA, store: &AnalysisStore) -> PassResult {
self.do_run(
ssa,
store.get::<FlowAnalysis>(),
store.get::<TypeInfo>(),
store.get::<PointsTo>(),
);
Ok(())
}

fn preserves(&self) -> Vec<AnalysisId> {
Expand Down
11 changes: 7 additions & 4 deletions compiler/src/compiler/passes/assert_constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use std::{cell::RefCell, collections::BTreeSet, rc::Rc};

use crate::compiler::{
analysis::witness_taint_inference::WitnessTaintInference,
pass_manager::{AnalysisStore, Pass},
pass_manager::{AnalysisStore, Pass, PassResult},
ssa::{
SourceLocation,
hlssa::{CallTarget, HLSSA, OpCode},
Expand Down Expand Up @@ -48,7 +48,7 @@ impl Pass for AssertConstantValidation {
"assert_constant_validation"
}

fn run(&self, ssa: &mut HLSSA, _store: &AnalysisStore) {
fn run(&self, ssa: &mut HLSSA, _store: &AnalysisStore) -> PassResult {
let mut failures = BTreeSet::new();
let mut functions_with_markers = Vec::new();

Expand Down Expand Up @@ -112,6 +112,7 @@ impl Pass for AssertConstantValidation {
}

*self.failures.borrow_mut() = Some(failures);
Ok(())
}
}

Expand Down Expand Up @@ -155,7 +156,8 @@ mod tests {
Rc::clone(&failures),
))],
)
.run(ssa);
.run(ssa)
.unwrap();
let failures = failures.borrow_mut().take().unwrap();
if failures.is_empty() {
Ok(())
Expand Down Expand Up @@ -397,6 +399,7 @@ mod tests {
failures,
))],
)
.run(&mut ssa);
.run(&mut ssa)
.unwrap();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
compiler::{
Field,
analysis::flow_analysis::{CFG, FlowAnalysis},
pass_manager::{AnalysisId, AnalysisStore, Pass},
pass_manager::{AnalysisId, AnalysisStore, Pass, PassResult},
passes::shared::{availability::can_replace, value_replacements::ValueReplacements},
ssa::{
BlockId, ProgramPoint, SSAConstantsSnapshot, ValueId,
Expand Down Expand Up @@ -42,8 +42,9 @@ impl Pass for CSE {
vec![FlowAnalysis::id()]
}

fn run(&self, ssa: &mut HLSSA, store: &AnalysisStore) {
fn run(&self, ssa: &mut HLSSA, store: &AnalysisStore) -> PassResult {
self.do_run(ssa, store.get::<FlowAnalysis>());
Ok(())
}

fn preserves(&self) -> Vec<AnalysisId> {
Expand Down
5 changes: 3 additions & 2 deletions compiler/src/compiler/passes/dead_code_elimination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
types::{FunctionTypeInfo, TypeInfo, Types},
value_range_analysis::{ValueRangeAnalysis, ValueRanges},
},
pass_manager::{AnalysisId, AnalysisStore, Pass},
pass_manager::{AnalysisId, AnalysisStore, Pass, PassResult},
passes::shared::{
divmod_guard::{
divisor_checked_by_its_lowering, divmod_can_fail, divmod_provably_defined,
Expand Down Expand Up @@ -183,8 +183,9 @@ impl Pass for DCE {
vec![FlowAnalysis::id()]
}

fn run(&self, ssa: &mut HLSSA, store: &AnalysisStore) {
fn run(&self, ssa: &mut HLSSA, store: &AnalysisStore) -> PassResult {
self.do_run(ssa, store.get::<FlowAnalysis>());
Ok(())
}
}

Expand Down
5 changes: 3 additions & 2 deletions compiler/src/compiler/passes/deduplicate_phis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::{
collections::HashMap,
compiler::{
pass_manager::{AnalysisId, AnalysisStore, Pass},
pass_manager::{AnalysisId, AnalysisStore, Pass, PassResult},
ssa::{BlockId, Terminator, ValueId, hlssa::HLSSA},
},
};
Expand All @@ -19,8 +19,9 @@ impl Pass for DeduplicatePhis {
vec![]
}

fn run(&self, ssa: &mut HLSSA, _store: &AnalysisStore) {
fn run(&self, ssa: &mut HLSSA, _store: &AnalysisStore) -> PassResult {
self.do_run(ssa);
Ok(())
}
}

Expand Down
5 changes: 3 additions & 2 deletions compiler/src/compiler/passes/defunctionalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::{
flow_analysis::FlowAnalysis,
types::{TypeInfo, Types},
},
pass_manager::{AnalysisStore, Pass},
pass_manager::{AnalysisStore, Pass, PassResult},
passes::{
remove_unreachable_blocks::remove_unreachable_blocks,
shared::value_replacements::ValueReplacements,
Expand Down Expand Up @@ -53,8 +53,9 @@ impl Pass for Defunctionalize {
"defunctionalize"
}

fn run(&self, ssa: &mut HLSSA, _store: &AnalysisStore) {
fn run(&self, ssa: &mut HLSSA, _store: &AnalysisStore) -> PassResult {
run_defunctionalize(ssa);
Ok(())
}
}

Expand Down
5 changes: 3 additions & 2 deletions compiler/src/compiler/passes/elide_tuples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use crate::{
collections::{HashMap, HashSet},
compiler::{
analysis::{flow_analysis::FlowAnalysis, types::TypeInfo},
pass_manager::{Analysis, AnalysisId, AnalysisStore, Pass},
pass_manager::{Analysis, AnalysisId, AnalysisStore, Pass, PassResult},
ssa::{
BlockId, FunctionId, Instruction, Located, Terminator, ValueId,
hlssa::{HLSSA, OpCode, Type, TypeExpr},
Expand All @@ -64,7 +64,7 @@ impl Pass for ElideTuples {
vec![TypeInfo::id(), FlowAnalysis::id()]
}

fn run(&self, ssa: &mut HLSSA, store: &AnalysisStore) {
fn run(&self, ssa: &mut HLSSA, store: &AnalysisStore) -> PassResult {
let old_global_types: Vec<Type> = ssa.get_global_types().to_vec();
let mut global_offsets: Vec<usize> = Vec::with_capacity(old_global_types.len());
let mut acc = 0usize;
Expand Down Expand Up @@ -98,6 +98,7 @@ impl Pass for ElideTuples {
// Verify the tuple-free invariant on every build: one linear pass, and the
// guarantee it enforces is relied on by every subsequent pass.
verify_tuple_free(ssa);
Ok(())
}

fn preserves(&self) -> Vec<AnalysisId> {
Expand Down
5 changes: 3 additions & 2 deletions compiler/src/compiler/passes/fix_double_jumps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
collections::HashMap,
compiler::{
analysis::flow_analysis::FlowAnalysis,
pass_manager::{AnalysisId, AnalysisStore, Pass},
pass_manager::{AnalysisId, AnalysisStore, Pass, PassResult},
passes::shared::value_replacements::{ReplaceScope, ValueReplacements},
ssa::{BlockId, Terminator, hlssa::HLSSA},
},
Expand All @@ -24,8 +24,9 @@ impl Pass for FixDoubleJumps {
vec![FlowAnalysis::id()]
}

fn run(&self, ssa: &mut HLSSA, store: &AnalysisStore) {
fn run(&self, ssa: &mut HLSSA, store: &AnalysisStore) -> PassResult {
self.do_run(ssa, store.get::<FlowAnalysis>());
Ok(())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,9 @@ mod tests {
.get_entry_mut()
.set_terminator(Terminator::Return(vec![result]));

InstructionLowering::operand_shapes().run(&mut ssa, &AnalysisStore::new());
InstructionLowering::operand_shapes()
.run(&mut ssa, &AnalysisStore::new())
.unwrap();

let mut widths = Vec::new();
for (_, block) in ssa.get_unique_entrypoint().get_blocks() {
Expand Down
Loading
Loading