diff --git a/solx-core/src/project/contract/mod.rs b/solx-core/src/project/contract/mod.rs index 69a66142..bbafa365 100644 --- a/solx-core/src/project/contract/mod.rs +++ b/solx-core/src/project/contract/mod.rs @@ -86,6 +86,31 @@ impl Contract { } } + /// + /// Returns an estimated compilation cost for LPT scheduling. + /// + /// Used to sort contracts by descending cost before parallel dispatch, + /// so that large contracts begin compiling first. + /// + pub fn estimated_compilation_cost(&self) -> usize { + match &self.ir { + Some(IR::Yul(_)) => self.yul.as_ref().map_or(0, String::len), + Some(IR::EVMLegacyAssembly(evmla)) => { + let deploy = evmla.assembly.code.as_ref().map_or(0, Vec::len); + let runtime = evmla + .runtime_code + .as_ref() + .and_then(|runtime| runtime.assembly.code.as_ref()) + .map_or(0, Vec::len); + deploy + runtime + } + Some(IR::LLVMIR(llvm_ir)) => llvm_ir.source.len(), + #[cfg(feature = "mlir")] + Some(IR::MLIR(mlir)) => mlir.source.len(), + None => 0, + } + } + /// /// Returns the contract identifier, which is: /// - the Yul object identifier for Yul diff --git a/solx-core/src/project/mod.rs b/solx-core/src/project/mod.rs index ddb33877..531af83c 100644 --- a/solx-core/src/project/mod.rs +++ b/solx-core/src/project/mod.rs @@ -10,6 +10,7 @@ use std::sync::Arc; use std::sync::Mutex; use rayon::iter::IntoParallelIterator; +use rayon::iter::ParallelBridge; use rayon::iter::ParallelIterator; use crate::build::Build as EVMBuild; @@ -344,7 +345,7 @@ impl Project { None, None, None, - None, + Some(source_code), #[cfg(feature = "mlir")] None, ); @@ -506,9 +507,15 @@ impl Project { llvm_options: Vec, output_config: Option, ) -> anyhow::Result { - let results = self - .contracts - .into_par_iter() + let mut contracts: Vec<(String, Contract)> = self.contracts.into_iter().collect(); + contracts.sort_unstable_by(|(_, left), (_, right)| { + right + .estimated_compilation_cost() + .cmp(&left.estimated_compilation_cost()) + }); + let results = contracts + .into_iter() + .par_bridge() .map(|(path, mut contract)| { let contract_name = contract.name.clone();