Skip to content
Merged
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
3 changes: 3 additions & 0 deletions bench/library_boundary/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ a 256-function, high-CFG fixture with three expression-valued branches per funct
interface bytes, so inference cost and summary-size growth are recorded together.
- `import-validation`: semantic-import milliseconds per iteration, including the complete type-shape
walk, borrow/growth fixed points, dependency-cycle check, and provenance-root validation.
- `mir-global-type-validation`: whole-program MIR-lowering milliseconds per iteration for a trivial
body plus 512 concrete nominal roots, isolating the global type-domain/root/cycle preflight and
its required metadata copies.
- `mir-continuation-lowering`: L2b-a2-ac whole-program MIR-lowering milliseconds per iteration and
the fixture's total basic-block count, tracking the O(1) required-child continuation protocol.

Expand Down
44 changes: 44 additions & 0 deletions bench/library_boundary/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ fn mir_continuation_fixture() -> String {
source
}

fn mir_global_type_fixture() -> String {
let mut source = String::new();
for index in 0..512 {
source.push_str(&format!("Record_{index:04} {{ value: i64 }}\n"));
}
source.push_str("fn main() -> i32 = 0\n");
source
}

fn import_validation_fixture() -> InterfaceSummary {
let parameter = ITypeParam {
name: "T".to_string(),
Expand Down Expand Up @@ -232,6 +241,41 @@ fn run_provenance() {
let milliseconds = elapsed.as_secs_f64() * 1_000.0 / iterations as f64;
println!("import-validation\t{milliseconds:.3}\tms/import");

let global_type_source = mir_global_type_fixture();
let mut source_map = align_span::SourceMap::new();
let checked = align_driver::check(
&mut source_map,
"mir-global-type.align",
&global_type_source,
);
assert!(
!checked.diags.has_errors(),
"MIR global-type fixture must check"
);
let mir = align_driver::lower_to_mir(&checked.hir);
assert_eq!(
mir.structs
.iter()
.filter(|definition| definition.source_name.starts_with("Record_"))
.count(),
512,
"fixture must retain every concrete nominal root"
);

let mut iterations = 0_u64;
let start = Instant::now();
while start.elapsed() < minimum {
let mir = align_driver::lower_to_mir(black_box(&checked.hir));
black_box(mir);
iterations += 1;
}
let elapsed = start.elapsed();
let milliseconds = elapsed.as_secs_f64() * 1_000.0 / iterations as f64;
println!(
"mir-global-type-validation\t{milliseconds:.3}\tms/lower\t{}\ttypes",
checked.hir.structs.len()
);

let continuation_source = mir_continuation_fixture();
let mut source_map = align_span::SourceMap::new();
let checked = align_driver::check(
Expand Down
28 changes: 28 additions & 0 deletions crates/align_mir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ use std::collections::VecDeque;
use std::rc::Rc;

pub mod print;
mod validate_hir;

#[cfg(test)]
mod validate_hir_tests;

/// A byte-offset → (line, col) index over every source file, built once from the [`SourceMap`] and
/// threaded (via [`Rc`]) into lowering so each MIR statement can record the 1-based source
Expand Down Expand Up @@ -1537,6 +1541,30 @@ pub fn lower_program_per_unit_located(program: &hir::Program, sm: &SourceMap) ->
// base of the deep `lower_fn`/`lower_expr` recursion (`expr_depth` stack margin).
#[inline]
fn lower_program_impl(program: &hir::Program, lines: Option<Rc<SourceLines>>, per_unit: bool) -> Program {
if !validate_hir::global_type_metadata_is_valid(program) {
return empty_program();
}
lower_program_unchecked(program, lines, per_unit)
}

fn empty_program() -> Program {
Program {
fns: Vec::new(),
externs: Vec::new(),
imported_fns: Vec::new(),
link_libs: Vec::new(),
structs: Vec::new(),
enums: Vec::new(),
tagged_types: Vec::new(),
tuples: Vec::new(),
}
}

fn lower_program_unchecked(
program: &hir::Program,
lines: Option<Rc<SourceLines>>,
per_unit: bool,
) -> Program {
// Function signature facts are immutable during MIR lowering. Materialize the shared table once
// so lowering F functions does not deep-clone all T entries F times.
let fn_types: Rc<[hir::FnTy]> = program.fn_types.clone().into();
Expand Down
Loading
Loading