diff --git a/cranelift/module/src/backend.rs b/cranelift/module/src/backend.rs index a72adf00cd3..9d12fa17a97 100644 --- a/cranelift/module/src/backend.rs +++ b/cranelift/module/src/backend.rs @@ -44,28 +44,34 @@ where /// Return the `TargetIsa` to compile for. fn isa(&self) -> &dyn TargetIsa; + /// Get all declarations in this module. + fn declarations(&self) -> &ModuleDeclarations; + /// Declare a function. - fn declare_function(&mut self, id: FuncId, name: &str, linkage: Linkage); + fn declare_function( + &mut self, + name: &str, + linkage: Linkage, + signature: &ir::Signature, + ) -> ModuleResult; /// Declare a data object. fn declare_data( &mut self, - id: DataId, name: &str, linkage: Linkage, writable: bool, tls: bool, align: Option, - ); + ) -> ModuleResult; /// Define a function, producing the function body from the given `Context`. /// /// Functions must be declared before being defined. fn define_function( &mut self, - id: FuncId, + func: FuncId, ctx: &mut Context, - declarations: &ModuleDeclarations, trap_sink: &mut TS, ) -> ModuleResult where @@ -78,7 +84,6 @@ where &mut self, id: FuncId, bytes: &[u8], - declarations: &ModuleDeclarations, ) -> ModuleResult; /// Define a zero-initialized data object of the given size. @@ -88,12 +93,11 @@ where &mut self, id: DataId, data_ctx: &DataContext, - declarations: &ModuleDeclarations, ) -> ModuleResult<()>; /// Consume this `Backend` and return a result. Some implementations may /// provide additional functionality through this result. - fn finish(self, declarations: ModuleDeclarations) -> Self::Product; + fn finish(self) -> Self::Product; } /// Default names for `ir::LibCall`s. A function by this name is imported into the object as diff --git a/cranelift/module/src/module.rs b/cranelift/module/src/module.rs index 62050142bb4..239ceb4d1f5 100644 --- a/cranelift/module/src/module.rs +++ b/cranelift/module/src/module.rs @@ -327,7 +327,6 @@ pub struct Module where B: Backend, { - declarations: ModuleDeclarations, backend: B, } @@ -344,11 +343,6 @@ where /// Create a new `Module`. pub fn new(backend_builder: B::Builder) -> Self { Self { - declarations: ModuleDeclarations { - names: HashMap::new(), - functions: PrimaryMap::new(), - data_objects: PrimaryMap::new(), - }, backend: B::new(backend_builder), } } @@ -356,7 +350,7 @@ where /// Get the module identifier for a given name, if that name /// has been declared. pub fn get_name(&self, name: &str) -> Option { - self.declarations.names.get(name).cloned() + self.backend.declarations().get_name(name) } /// Return the target information needed by frontends to produce Cranelift IR @@ -406,16 +400,7 @@ where linkage: Linkage, signature: &ir::Signature, ) -> ModuleResult { - let (id, decl) = self - .declarations - .declare_function(name, linkage, signature)?; - self.backend.declare_function(id, name, decl.linkage); - Ok(id) - } - - /// An iterator over functions that have been declared in this module. - pub fn declared_functions(&self) -> core::slice::Iter<'_, FunctionDeclaration> { - self.declarations.functions.values() + self.backend.declare_function(name, linkage, signature) } /// Declare a data object in this module. @@ -427,12 +412,8 @@ where tls: bool, align: Option, // An alignment bigger than 128 is unlikely ) -> ModuleResult { - let (id, decl) = self - .declarations - .declare_data(name, linkage, writable, tls, align)?; self.backend - .declare_data(id, name, decl.linkage, decl.writable, decl.tls, decl.align); - Ok(id) + .declare_data(name, linkage, writable, tls, align) } /// Use this when you're building the IR of a function to reference a function. @@ -440,7 +421,7 @@ where /// TODO: Coalesce redundant decls and signatures. /// TODO: Look into ways to reduce the risk of using a FuncRef in the wrong function. pub fn declare_func_in_func(&self, func: FuncId, in_func: &mut ir::Function) -> ir::FuncRef { - let decl = &self.declarations.functions[func]; + let decl = &self.backend.declarations().functions[func]; let signature = in_func.import_signature(decl.signature.clone()); let colocated = decl.linkage.is_final(); in_func.import_function(ir::ExtFuncData { @@ -454,7 +435,7 @@ where /// /// TODO: Same as above. pub fn declare_data_in_func(&self, data: DataId, func: &mut ir::Function) -> ir::GlobalValue { - let decl = &self.declarations.data_objects[data]; + let decl = &self.backend.declarations().data_objects[data]; let colocated = decl.linkage.is_final(); func.create_global_value(ir::GlobalValueData::Symbol { name: ir::ExternalName::user(1, data.as_u32()), @@ -488,8 +469,7 @@ where where TS: binemit::TrapSink, { - self.backend - .define_function(func, ctx, &self.declarations, trap_sink) + self.backend.define_function(func, ctx, trap_sink) } /// Define a function, taking the function body from the given `bytes`. @@ -504,13 +484,12 @@ where func: FuncId, bytes: &[u8], ) -> ModuleResult { - self.backend - .define_function_bytes(func, bytes, &self.declarations) + self.backend.define_function_bytes(func, bytes) } /// Define a data object, producing the data contents from the given `DataContext`. pub fn define_data(&mut self, data: DataId, data_ctx: &DataContext) -> ModuleResult<()> { - self.backend.define_data(data, data_ctx, &self.declarations) + self.backend.define_data(data, data_ctx) } /// Return the target isa @@ -522,6 +501,6 @@ where /// implementations may provide additional functionality available after /// a `Module` is complete. pub fn finish(self) -> B::Product { - self.backend.finish(self.declarations) + self.backend.finish() } } diff --git a/cranelift/object/src/backend.rs b/cranelift/object/src/backend.rs index 4a372a8be5a..c0bb4c46a5f 100644 --- a/cranelift/object/src/backend.rs +++ b/cranelift/object/src/backend.rs @@ -114,6 +114,7 @@ impl ObjectBuilder { pub struct ObjectBackend { isa: Box, object: Object, + declarations: ModuleDeclarations, functions: SecondaryMap>, data_objects: SecondaryMap>, relocs: Vec, @@ -135,6 +136,7 @@ impl Backend for ObjectBackend { Self { isa: builder.isa, object, + declarations: ModuleDeclarations::default(), functions: SecondaryMap::new(), data_objects: SecondaryMap::new(), relocs: Vec::new(), @@ -149,8 +151,21 @@ impl Backend for ObjectBackend { &*self.isa } - fn declare_function(&mut self, id: FuncId, name: &str, linkage: Linkage) { - let (scope, weak) = translate_linkage(linkage); + fn declarations(&self) -> &ModuleDeclarations { + &self.declarations + } + + fn declare_function( + &mut self, + name: &str, + linkage: Linkage, + signature: &ir::Signature, + ) -> ModuleResult { + let (id, decl) = self + .declarations + .declare_function(name, linkage, signature)?; + + let (scope, weak) = translate_linkage(decl.linkage); if let Some((function, _defined)) = self.functions[id] { let symbol = self.object.symbol_mut(function); @@ -169,23 +184,28 @@ impl Backend for ObjectBackend { }); self.functions[id] = Some((symbol_id, false)); } + + Ok(id) } fn declare_data( &mut self, - id: DataId, name: &str, linkage: Linkage, - _writable: bool, + writable: bool, tls: bool, - _align: Option, - ) { - let kind = if tls { + align: Option, + ) -> ModuleResult { + let (id, decl) = self + .declarations + .declare_data(name, linkage, writable, tls, align)?; + + let kind = if decl.tls { SymbolKind::Tls } else { SymbolKind::Data }; - let (scope, weak) = translate_linkage(linkage); + let (scope, weak) = translate_linkage(decl.linkage); if let Some((data, _defined)) = self.data_objects[id] { let symbol = self.object.symbol_mut(data); @@ -205,13 +225,14 @@ impl Backend for ObjectBackend { }); self.data_objects[id] = Some((symbol_id, false)); } + + Ok(id) } fn define_function( &mut self, func_id: FuncId, ctx: &mut cranelift_codegen::Context, - declarations: &ModuleDeclarations, trap_sink: &mut TS, ) -> ModuleResult where @@ -227,7 +248,7 @@ impl Backend for ObjectBackend { .. } = ctx.compile(self.isa())?; - let decl = declarations.get_function_decl(func_id); + let decl = self.declarations.get_function_decl(func_id); if !decl.linkage.is_definable() { return Err(ModuleError::InvalidImportDefinition(decl.name.clone())); } @@ -286,11 +307,10 @@ impl Backend for ObjectBackend { &mut self, func_id: FuncId, bytes: &[u8], - declarations: &ModuleDeclarations, ) -> ModuleResult { info!("defining function {} with bytes", func_id); - let decl = declarations.get_function_decl(func_id); + let decl = self.declarations.get_function_decl(func_id); if !decl.linkage.is_definable() { return Err(ModuleError::InvalidImportDefinition(decl.name.clone())); } @@ -326,13 +346,8 @@ impl Backend for ObjectBackend { Ok(ModuleCompiledFunction { size: total_size }) } - fn define_data( - &mut self, - data_id: DataId, - data_ctx: &DataContext, - declarations: &ModuleDeclarations, - ) -> ModuleResult<()> { - let decl = declarations.get_data_decl(data_id); + fn define_data(&mut self, data_id: DataId, data_ctx: &DataContext) -> ModuleResult<()> { + let decl = self.declarations.get_data_decl(data_id); if !decl.linkage.is_definable() { return Err(ModuleError::InvalidImportDefinition(decl.name.clone())); } @@ -438,7 +453,7 @@ impl Backend for ObjectBackend { Ok(()) } - fn finish(mut self, declarations: ModuleDeclarations) -> ObjectProduct { + fn finish(mut self) -> ObjectProduct { let symbol_relocs = mem::take(&mut self.relocs); for symbol in symbol_relocs { for &RelocRecord { @@ -450,7 +465,7 @@ impl Backend for ObjectBackend { addend, } in &symbol.relocs { - let target_symbol = self.get_symbol(&declarations, name); + let target_symbol = self.get_symbol(name); self.object .add_relocation( symbol.section, @@ -487,18 +502,14 @@ impl Backend for ObjectBackend { impl ObjectBackend { // This should only be called during finish because it creates // symbols for missing libcalls. - fn get_symbol( - &mut self, - declarations: &ModuleDeclarations, - name: &ir::ExternalName, - ) -> SymbolId { + fn get_symbol(&mut self, name: &ir::ExternalName) -> SymbolId { match *name { ir::ExternalName::User { .. } => { - if declarations.is_function(name) { - let id = declarations.get_function_id(name); + if self.declarations.is_function(name) { + let id = self.declarations.get_function_id(name); self.functions[id].unwrap().0 } else { - let id = declarations.get_data_id(name); + let id = self.declarations.get_data_id(name); self.data_objects[id].unwrap().0 } } diff --git a/cranelift/simplejit/src/backend.rs b/cranelift/simplejit/src/backend.rs index a5429a42973..fcfd72c3b49 100644 --- a/cranelift/simplejit/src/backend.rs +++ b/cranelift/simplejit/src/backend.rs @@ -127,6 +127,7 @@ pub struct SimpleJITBackend { symbols: HashMap, libcall_names: Box String>, memory: SimpleJITMemoryHandle, + declarations: ModuleDeclarations, functions: SecondaryMap>, data_objects: SecondaryMap>, functions_to_finalize: Vec, @@ -224,24 +225,20 @@ impl SimpleJITBackend { } } - fn get_definition( - &self, - declarations: &ModuleDeclarations, - name: &ir::ExternalName, - ) -> *const u8 { + fn get_definition(&self, name: &ir::ExternalName) -> *const u8 { match *name { ir::ExternalName::User { .. } => { - if declarations.is_function(name) { - let func_id = declarations.get_function_id(name); + if self.declarations.is_function(name) { + let func_id = self.declarations.get_function_id(name); match &self.functions[func_id] { Some(compiled) => compiled.code, - None => self.lookup_symbol(&declarations.get_function_decl(func_id).name), + None => self.lookup_symbol(&self.declarations.get_function_decl(func_id).name), } } else { - let data_id = declarations.get_data_id(name); + let data_id = self.declarations.get_data_id(name); match &self.data_objects[data_id] { Some(compiled) => compiled.storage, - None => self.lookup_symbol(&declarations.get_data_decl(data_id).name), + None => self.lookup_symbol(&self.declarations.get_data_decl(data_id).name), } } } @@ -270,7 +267,7 @@ impl SimpleJITBackend { } } - fn finalize_function(&mut self, id: FuncId, declarations: &ModuleDeclarations) { + fn finalize_function(&mut self, id: FuncId) { use std::ptr::write_unaligned; let func = self.functions[id] @@ -287,7 +284,7 @@ impl SimpleJITBackend { let ptr = func.code; debug_assert!((offset as usize) < func.size); let at = unsafe { ptr.offset(offset as isize) }; - let base = self.get_definition(declarations, name); + let base = self.get_definition(name); // TODO: Handle overflow. let what = unsafe { base.offset(addend as isize) }; match reloc { @@ -318,7 +315,7 @@ impl SimpleJITBackend { } } - fn finalize_data(&mut self, id: DataId, declarations: &ModuleDeclarations) { + fn finalize_data(&mut self, id: DataId) { use std::ptr::write_unaligned; let data = self.data_objects[id] @@ -335,7 +332,7 @@ impl SimpleJITBackend { let ptr = data.storage; debug_assert!((offset as usize) < data.size); let at = unsafe { ptr.offset(offset as isize) }; - let base = self.get_definition(declarations, name); + let base = self.get_definition(name); // TODO: Handle overflow. let what = unsafe { base.offset(addend as isize) }; match reloc { @@ -384,6 +381,7 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { symbols: builder.symbols, libcall_names: builder.libcall_names, memory, + declarations: ModuleDeclarations::default(), functions: SecondaryMap::new(), data_objects: SecondaryMap::new(), functions_to_finalize: Vec::new(), @@ -395,28 +393,41 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { &*self.isa } - fn declare_function(&mut self, _id: FuncId, _name: &str, _linkage: Linkage) { - // Nothing to do. + fn declarations(&self) -> &ModuleDeclarations { + &self.declarations + } + + fn declare_function( + &mut self, + name: &str, + linkage: Linkage, + signature: &ir::Signature, + ) -> ModuleResult { + let (id, _decl) = self + .declarations + .declare_function(name, linkage, signature)?; + Ok(id) } fn declare_data( &mut self, - _id: DataId, - _name: &str, - _linkage: Linkage, - _writable: bool, + name: &str, + linkage: Linkage, + writable: bool, tls: bool, - _align: Option, - ) { + align: Option, + ) -> ModuleResult { assert!(!tls, "SimpleJIT doesn't yet support TLS"); - // Nothing to do. + let (id, _decl) = self + .declarations + .declare_data(name, linkage, writable, tls, align)?; + Ok(id) } fn define_function( &mut self, id: FuncId, ctx: &mut cranelift_codegen::Context, - declarations: &ModuleDeclarations, trap_sink: &mut TS, ) -> ModuleResult where @@ -428,7 +439,7 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { .. } = ctx.compile(self.isa())?; - let decl = declarations.get_function_decl(id); + let decl = self.declarations.get_function_decl(id); if !decl.linkage.is_definable() { return Err(ModuleError::InvalidImportDefinition(decl.name.clone())); } @@ -472,9 +483,8 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { &mut self, id: FuncId, bytes: &[u8], - declarations: &ModuleDeclarations, ) -> ModuleResult { - let decl = declarations.get_function_decl(id); + let decl = self.declarations.get_function_decl(id); if !decl.linkage.is_definable() { return Err(ModuleError::InvalidImportDefinition(decl.name.clone())); } @@ -511,13 +521,8 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { Ok(ModuleCompiledFunction { size: total_size }) } - fn define_data( - &mut self, - id: DataId, - data: &DataContext, - declarations: &ModuleDeclarations, - ) -> ModuleResult<()> { - let decl = declarations.get_data_decl(id); + fn define_data(&mut self, id: DataId, data: &DataContext) -> ModuleResult<()> { + let decl = self.declarations.get_data_decl(id); if !decl.linkage.is_definable() { return Err(ModuleError::InvalidImportDefinition(decl.name.clone())); } @@ -604,16 +609,16 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { /// /// This method does not need to be called when access to the memory /// handle is not required. - fn finish(mut self, declarations: ModuleDeclarations) -> Self::Product { + fn finish(mut self) -> Self::Product { for func in std::mem::take(&mut self.functions_to_finalize) { - let decl = declarations.get_function_decl(func); + let decl = self.declarations.get_function_decl(func); debug_assert!(decl.linkage.is_definable()); - self.finalize_function(func, &declarations); + self.finalize_function(func); } for data in std::mem::take(&mut self.data_objects_to_finalize) { - let decl = declarations.get_data_decl(data); + let decl = self.declarations.get_data_decl(data); debug_assert!(decl.linkage.is_definable()); - self.finalize_data(data, &declarations); + self.finalize_data(data); } // Now that we're done patching, prepare the memory for execution! @@ -622,7 +627,7 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { SimpleJITProduct { memory: self.memory, - declarations, + declarations: self.declarations, functions: self.functions, data_objects: self.data_objects, }