diff --git a/lib/environ/Cargo.toml b/lib/environ/Cargo.toml index 8c2842bcce..9c0b9a3531 100644 --- a/lib/environ/Cargo.toml +++ b/lib/environ/Cargo.toml @@ -19,6 +19,7 @@ cast = { version = "0.2.2", default-features = false } failure = { version = "0.1.3", default-features = false } failure_derive = { version = "0.1.3", default-features = false } indexmap = "1.0.2" +rayon = "1.0" [features] default = ["std"] diff --git a/lib/environ/src/cranelift.rs b/lib/environ/src/cranelift.rs index 7cc35a9aac..47b23cf0d5 100644 --- a/lib/environ/src/cranelift.rs +++ b/lib/environ/src/cranelift.rs @@ -13,6 +13,7 @@ use cranelift_codegen::isa; use cranelift_codegen::Context; use cranelift_entity::PrimaryMap; use cranelift_wasm::{DefinedFuncIndex, FuncIndex, FuncTranslator}; +use rayon::prelude::{IntoParallelRefIterator, ParallelIterator}; use std::vec::Vec; /// Implementation of a relocation sink that just saves all the information for later @@ -89,30 +90,40 @@ pub fn compile_module<'data, 'module>( ) -> Result<(Compilation, Relocations), CompileError> { let mut functions = PrimaryMap::with_capacity(function_body_inputs.len()); let mut relocations = PrimaryMap::with_capacity(function_body_inputs.len()); - for (i, input) in function_body_inputs.into_iter() { - let func_index = module.func_index(i); - let mut context = Context::new(); - context.func.name = get_func_name(func_index); - context.func.signature = module.signatures[module.functions[func_index]].clone(); - let mut trans = FuncTranslator::new(); - trans - .translate( - input, - &mut context.func, - &mut FuncEnvironment::new(isa.frontend_config(), module), - ) - .map_err(CompileError::Wasm)?; + function_body_inputs + .into_iter() + .collect::>() + .par_iter() + .map(|(i, input)| { + let func_index = module.func_index(*i); + let mut context = Context::new(); + context.func.name = get_func_name(func_index); + context.func.signature = module.signatures[module.functions[func_index]].clone(); - let mut code_buf: Vec = Vec::new(); - let mut reloc_sink = RelocSink::new(); - let mut trap_sink = binemit::NullTrapSink {}; - context - .compile_and_emit(isa, &mut code_buf, &mut reloc_sink, &mut trap_sink) - .map_err(CompileError::Codegen)?; - functions.push(code_buf); - relocations.push(reloc_sink.func_relocs); - } + let mut trans = FuncTranslator::new(); + trans + .translate( + input, + &mut context.func, + &mut FuncEnvironment::new(isa.frontend_config(), module), + ) + .map_err(CompileError::Wasm)?; + + let mut code_buf: Vec = Vec::new(); + let mut reloc_sink = RelocSink::new(); + let mut trap_sink = binemit::NullTrapSink {}; + context + .compile_and_emit(isa, &mut code_buf, &mut reloc_sink, &mut trap_sink) + .map_err(CompileError::Codegen)?; + Ok((code_buf, reloc_sink.func_relocs)) + }) + .collect::, CompileError>>()? + .into_iter() + .for_each(|(function, relocs)| { + functions.push(function); + relocations.push(relocs); + }); // TODO: Reorganize where we create the Vec for the resolved imports. Ok((Compilation::new(functions), relocations))