midenc_compile/stages/
codegen.rs1use alloc::{boxed::Box, collections::BTreeMap, sync::Arc, vec::Vec};
2
3use miden_assembly::{ast::Module, Library};
4use miden_mast_package::Package;
5use midenc_codegen_masm::{
6 self as masm,
7 intrinsics::{
8 I32_INTRINSICS_MODULE_NAME, I64_INTRINSICS_MODULE_NAME, MEM_INTRINSICS_MODULE_NAME,
9 },
10 MasmComponent, ToMasmComponent,
11};
12use midenc_hir::{interner::Symbol, pass::AnalysisManager};
13use midenc_session::OutputType;
14
15use super::*;
16
17pub struct CodegenOutput {
18 pub component: Arc<MasmComponent>,
19 pub link_libraries: Vec<Arc<Library>>,
20 pub link_packages: BTreeMap<Symbol, Arc<Package>>,
21 pub account_component_metadata_bytes: Option<Vec<u8>>,
23}
24
25pub struct CodegenStage;
27
28impl Stage for CodegenStage {
29 type Input = LinkOutput;
30 type Output = CodegenOutput;
31
32 fn enabled(&self, context: &Context) -> bool {
33 context.session().should_codegen()
34 }
35
36 fn run(
37 &mut self,
38 linker_output: Self::Input,
39 context: Rc<Context>,
40 ) -> CompilerResult<Self::Output> {
41 let LinkOutput {
42 component,
43 masm: masm_modules,
44 mast: link_libraries,
45 packages: link_packages,
46 ..
47 } = linker_output;
48
49 log::debug!("lowering hir program to masm");
50
51 let analysis_manager = AnalysisManager::new(component.as_operation_ref(), None);
52 let mut masm_component =
53 component.borrow().to_masm_component(analysis_manager).map(Box::new)?;
54
55 let session = context.session();
56 if session.should_emit(OutputType::Masm) {
57 for module in masm_component.modules.iter() {
58 session.emit(OutputMode::Text, module).into_diagnostic()?;
59 }
60 }
61
62 for intrinsics_module in required_intrinsics_modules(session) {
64 log::debug!(
65 "adding required intrinsic module '{}' to masm program",
66 intrinsics_module.path()
67 );
68 masm_component.modules.push(intrinsics_module);
69 }
70
71 for module in masm_modules {
73 log::debug!("adding external masm module '{}' to masm program", module.path());
74 masm_component.modules.push(module);
75 }
76
77 Ok(CodegenOutput {
78 component: Arc::from(masm_component),
79 link_libraries,
80 link_packages,
81 account_component_metadata_bytes: linker_output.account_component_metadata_bytes,
82 })
83 }
84}
85
86fn required_intrinsics_modules(session: &Session) -> impl IntoIterator<Item = Arc<Module>> {
87 [
88 masm::intrinsics::load(MEM_INTRINSICS_MODULE_NAME, &session.source_manager)
89 .map(Arc::from)
90 .expect("undefined intrinsics module"),
91 masm::intrinsics::load(I32_INTRINSICS_MODULE_NAME, &session.source_manager)
92 .map(Arc::from)
93 .expect("undefined intrinsics module"),
94 masm::intrinsics::load(I64_INTRINSICS_MODULE_NAME, &session.source_manager)
95 .map(Arc::from)
96 .expect("undefined intrinsics module"),
97 ]
98}