Skip to content
Draft
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
29 changes: 16 additions & 13 deletions crates/cli/src/commands/evm_opt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use clap::ValueHint;
use solar_codegen::backend::evm::ir;
use solar_config::CompileOpts;
use solar_interface::Session;
use solar_sema::CompilerRef;
use std::{path::Path, process::ExitCode};

#[derive(clap::Args)]
Expand Down Expand Up @@ -69,17 +69,18 @@ fn print_module(module: &ir::Module, name: &str, after: &str) {
print!("{}", module.to_text());
}

fn run_pipeline(sess: &Session, module: &mut ir::Module, name: &str, args: &EvmOptArgs) {
fn run_pipeline(
compiler: &CompilerRef<'_>,
module: &mut ir::Module,
name: &str,
args: &EvmOptArgs,
) {
let sess = compiler.sess();
let dcx = &sess.dcx;
let options = ir::PassOptions {
time_passes: sess.opts.unstable.time_passes,
evm_version: sess.opts.evm_version,
optimization: sess.opts.optimization,
};
let pipeline_label = selected_pass_list_label(&args.passes, ",");
for (index, &pass) in args.passes.iter().enumerate() {
if let Some(pass) = pass {
ir::run_pass(module, pass, options);
ir::run_pass(compiler.gcx(), module, pass);
}
if args.print_after_each || index + 1 == args.passes.len() {
ir::validate(dcx, module);
Expand All @@ -92,25 +93,27 @@ fn run_pipeline(sess: &Session, module: &mut ir::Module, name: &str, args: &EvmO
}
}

fn process_evmir(sess: &Session, args: &EvmOptArgs) -> solar_interface::Result {
fn process_evmir(compiler: &mut CompilerRef<'_>, args: &EvmOptArgs) -> solar_interface::Result {
let sess = compiler.sess();
let source = sess
.source_map()
.load_file(Path::new(&args.input))
.map_err(|e| sess.dcx.err(format!("failed to read {}: {e}", args.input)).emit())?;
let mut module = ir::Module::parse(sess, &source)?;
ir::validate(&sess.dcx, &module);
if sess.dcx.has_errors().is_ok() {
run_pipeline(sess, &mut module, &args.input, args);
run_pipeline(compiler, &mut module, &args.input, args);
}
Ok(())
}

pub(crate) fn run(args: EvmOptArgs, mut opts: CompileOpts) -> ExitCode {
opts.input.push(args.input.clone());
let ext = Path::new(&args.input).extension().and_then(|s| s.to_str()).unwrap_or("");
let result = super::compile::run_session_with(opts, |sess| match ext {
"evmir" => process_evmir(sess, &args),
_ => Err(sess
let result = super::compile::run_compiler_with(opts, |compiler| match ext {
"evmir" => process_evmir(compiler, &args),
_ => Err(compiler
.sess()
.dcx
.err(format!("unsupported input file extension `.{ext}` (expected .evmir)"))
.emit()),
Expand Down
28 changes: 12 additions & 16 deletions crates/cli/src/commands/mir_opt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@ use solar_codegen::{
lower,
mir::{Module, validate},
pass::{
DEFAULT_CLEANUP_PIPELINE, DEFAULT_PIPELINE, PASS_REGISTRY, PassInfo, PipelineOptions,
lookup_pass, run_default_pipeline, run_pass,
DEFAULT_CLEANUP_PIPELINE, DEFAULT_PIPELINE, PASS_REGISTRY, PassInfo, lookup_pass,
run_default_pipeline, run_pass,
},
};
use solar_config::CompileOpts;
use solar_data_structures::fmt::{self, FmtIteratorExt};
use solar_interface::Session;
use solar_sema::CompilerRef;
use solar_sema::{CompilerRef, Gcx};
use std::{ops::ControlFlow, path::Path, process::ExitCode};

fn after_help() -> String {
Expand Down Expand Up @@ -129,25 +128,20 @@ fn print_module(module: &Module, name: &str, after: &str) {

/// Runs the pass pipeline on a single module and emits output.
/// Used for both .sol contracts and .mir input.
fn run_pipeline(module: &mut Module, name: &str, args: &MirOptArgs, time_passes: bool) {
fn run_pipeline(gcx: Gcx<'_>, module: &mut Module, name: &str, args: &MirOptArgs) {
if args.pipeline_default {
let mut options = PipelineOptions::default();
options.print_after_each = args.print_after_each;
options.time_passes = time_passes;
run_default_pipeline(module, options);
run_default_pipeline(gcx, module);
if !args.print_after_each {
print_module(module, name, "pipeline-default");
}
return;
}

let passes = args.selected_passes();
let mut options = PipelineOptions::default();
options.time_passes = time_passes;
let pipeline_label = args.pipeline_label(&passes);
for (index, &pass) in passes.iter().enumerate() {
if let Some(pass) = pass {
run_pass(module, pass, options);
run_pass(gcx, module, pass);
}
if args.print_after_each || index + 1 == passes.len() {
let label = if args.print_after_each { pass_label(pass) } else { &pipeline_label };
Expand All @@ -157,7 +151,8 @@ fn run_pipeline(module: &mut Module, name: &str, args: &MirOptArgs, time_passes:
}

/// Process a `.mir` input: read file, parse, run passes, print.
fn process_mir(sess: &Session, args: &MirOptArgs) -> solar_interface::Result {
fn process_mir(compiler: &mut CompilerRef<'_>, args: &MirOptArgs) -> solar_interface::Result {
let sess = compiler.sess();
let source = sess
.source_map()
.load_file(Path::new(&args.input))
Expand All @@ -167,7 +162,7 @@ fn process_mir(sess: &Session, args: &MirOptArgs) -> solar_interface::Result {
// diagnostic instead of tripping the post-pass validator ICE.
validate(&sess.dcx, &module);
if sess.dcx.has_errors().is_ok() {
run_pipeline(&mut module, &args.input, args, sess.opts.unstable.time_passes);
run_pipeline(compiler.gcx(), &mut module, &args.input, args);
}
Ok(())
}
Expand All @@ -191,19 +186,20 @@ fn process_sol(compiler: &mut CompilerRef<'_>, args: &MirOptArgs) -> solar_inter
}
let mut module = lower::lower_contract(gcx, id);
let name = gcx.contract_fully_qualified_name(id).to_string();
run_pipeline(&mut module, &name, args, gcx.sess.opts.unstable.time_passes);
run_pipeline(gcx, &mut module, &name, args);
}
Ok(())
}

/// Entry point for the `mir-opt` subcommand.
pub(super) fn run(args: MirOptArgs, mut opts: CompileOpts) -> ExitCode {
opts.input.push(args.input.clone());
opts.unstable.mir_print_after_each = args.print_after_each;
// Dispatch on input file extension.
let ext = Path::new(&args.input).extension().and_then(|s| s.to_str()).unwrap_or("");
let result = match ext {
"sol" => super::compile::run_compiler_with(opts, |compiler| process_sol(compiler, &args)),
"mir" => super::compile::run_session_with(opts, |sess| process_mir(sess, &args)),
"mir" => super::compile::run_compiler_with(opts, |compiler| process_mir(compiler, &args)),
_ => super::compile::run_session_with(opts, |sess| {
Err(sess
.dcx
Expand Down
7 changes: 3 additions & 4 deletions crates/cli/src/emit.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use alloy_json_abi::AbiItem;
use alloy_primitives::Bytes;
use solar_codegen::{Backend, EvmCodegen, EvmCodegenConfig, backend::evm::ir, lower};
use solar_codegen::{Backend, EvmCodegen, backend::evm::ir, lower};
use solar_config::{CompilerOutput, Dump, DumpKind};
use solar_data_structures::{bit_set::DenseBitSet, map::FxHashMap};
use solar_interface::Result;
Expand Down Expand Up @@ -345,9 +345,8 @@ fn ensure_contract_bytecode(

let mut module = lower::lower_contract_with_bytecodes(gcx, contract_id, all_bytecodes);
gcx.dcx().has_errors()?;
let mut config = EvmCodegenConfig::from(gcx);
config.capture_evm_ir = capture_evm_ir;
let mut codegen = EvmCodegen::new(config);
let mut codegen = EvmCodegen::new(gcx);
codegen.set_capture_evm_ir(capture_evm_ir);
let artifact = codegen.lower_module(&mut module);
all_bytecodes.insert(contract_id, artifact.deployment.clone());
artifacts.insert(
Expand Down
Loading
Loading