Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Separate compilation and expression narrowing in nargo interface #4100

Merged
merged 3 commits into from
Jan 23, 2024
Merged
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
4 changes: 2 additions & 2 deletions compiler/noirc_driver/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub enum ContractFunctionType {
Unconstrained,
}

#[derive(Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CompiledContract {
pub noir_version: String,

Expand All @@ -51,7 +51,7 @@ pub struct CompiledContract {
/// A contract function unlike a regular Noir program
/// however can have additional properties.
/// One of these being a function type.
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ContractFunction {
pub name: String,

Expand Down
5 changes: 3 additions & 2 deletions compiler/wasm/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ pub fn compile(
})?
.0;

let optimized_contract = nargo::ops::optimize_contract(compiled_contract, expression_width);
let optimized_contract =
nargo::ops::transform_contract(compiled_contract, expression_width);

let compile_output = generate_contract_artifact(optimized_contract);
Ok(JsCompileResult::new(compile_output))
Expand All @@ -205,7 +206,7 @@ pub fn compile(
})?
.0;

let optimized_program = nargo::ops::optimize_program(compiled_program, expression_width);
let optimized_program = nargo::ops::transform_program(compiled_program, expression_width);

let compile_output = generate_program_artifact(optimized_program);
Ok(JsCompileResult::new(compile_output))
Expand Down
4 changes: 2 additions & 2 deletions compiler/wasm/src/compile_new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl CompilerContext {
})?
.0;

let optimized_program = nargo::ops::optimize_program(compiled_program, np_language);
let optimized_program = nargo::ops::transform_program(compiled_program, np_language);

let compile_output = generate_program_artifact(optimized_program);
Ok(JsCompileResult::new(compile_output))
Expand All @@ -134,7 +134,7 @@ impl CompilerContext {
})?
.0;

let optimized_contract = nargo::ops::optimize_contract(compiled_contract, np_language);
let optimized_contract = nargo::ops::transform_contract(compiled_contract, np_language);

let compile_output = generate_contract_artifact(optimized_contract);
Ok(JsCompileResult::new(compile_output))
Expand Down
20 changes: 13 additions & 7 deletions tooling/lsp/src/requests/profile_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,26 +64,32 @@ fn on_profile_run_request_inner(
&workspace_file_manager,
&parsed_files,
&workspace,
expression_width,
&CompileOptions::default(),
)
.map_err(|err| ResponseError::new(ErrorCode::REQUEST_FAILED, err))?;

let mut opcodes_counts: HashMap<Location, OpCodesCount> = HashMap::new();
let mut file_map: BTreeMap<FileId, DebugFile> = BTreeMap::new();
for compiled_program in &compiled_programs {
for compiled_program in compiled_programs {
let compiled_program =
nargo::ops::transform_program(compiled_program, expression_width);

let span_opcodes = compiled_program.debug.count_span_opcodes();
let debug_artifact: DebugArtifact = compiled_program.clone().into();
opcodes_counts.extend(span_opcodes);
file_map.extend(debug_artifact.file_map);
}

for compiled_contract in &compiled_contracts {
let functions = &compiled_contract.functions;
let debug_artifact: DebugArtifact = compiled_contract.clone().into();
for compiled_contract in compiled_contracts {
let compiled_contract =
nargo::ops::transform_contract(compiled_contract, expression_width);

let function_debug_info: Vec<_> =
compiled_contract.functions.iter().map(|func| &func.debug).cloned().collect();
let debug_artifact: DebugArtifact = compiled_contract.into();
file_map.extend(debug_artifact.file_map);
for contract_function in functions {
let span_opcodes = contract_function.debug.count_span_opcodes();
for contract_function_debug in function_debug_info {
let span_opcodes = contract_function_debug.count_span_opcodes();
opcodes_counts.extend(span_opcodes);
}
}
Expand Down
12 changes: 6 additions & 6 deletions tooling/nargo/src/artifacts/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,18 +126,18 @@
}
}

impl From<&CompiledContract> for DebugArtifact {
fn from(compiled_artifact: &CompiledContract) -> Self {
impl From<CompiledContract> for DebugArtifact {
fn from(compiled_artifact: CompiledContract) -> Self {
let all_functions_debug: Vec<DebugInfo> = compiled_artifact
.functions
.iter()
.map(|contract_function| contract_function.debug.clone())
.into_iter()
.map(|contract_function| contract_function.debug)
.collect();

DebugArtifact {
debug_symbols: all_functions_debug,
file_map: compiled_artifact.file_map.clone(),
warnings: compiled_artifact.warnings.clone(),
file_map: compiled_artifact.file_map,
warnings: compiled_artifact.warnings,
}
}
}
Expand Down Expand Up @@ -194,7 +194,7 @@
// For example, given the snippet:
// ```
// permute(
// consts::x5_2_config(),

Check warning on line 197 in tooling/nargo/src/artifacts/debug.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (consts)
// state);
// ```
// We want location_in_line to return the range
Expand All @@ -203,7 +203,7 @@
fn location_in_line_stops_at_end_of_line() {
let source_code = r##"pub fn main(mut state: [Field; 2]) -> [Field; 2] {
state = permute(
consts::x5_2_config(),

Check warning on line 206 in tooling/nargo/src/artifacts/debug.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (consts)
state);

state
Expand All @@ -219,7 +219,7 @@
// Location of
// ```
// permute(
// consts::x5_2_config(),

Check warning on line 222 in tooling/nargo/src/artifacts/debug.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (consts)
// state)
// ```
let loc = Location::new(Span::inclusive(63, 116), file_id);
Expand Down
35 changes: 4 additions & 31 deletions tooling/nargo/src/ops/compile.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use acvm::ExpressionWidth;
use fm::FileManager;
use noirc_driver::{CompilationResult, CompileOptions, CompiledContract, CompiledProgram};
use noirc_frontend::hir::ParsedFiles;
Expand All @@ -18,7 +17,6 @@ pub fn compile_workspace(
file_manager: &FileManager,
parsed_files: &ParsedFiles,
workspace: &Workspace,
expression_width: ExpressionWidth,
compile_options: &CompileOptions,
) -> Result<(Vec<CompiledProgram>, Vec<CompiledContract>), CompileError> {
let (binary_packages, contract_packages): (Vec<_>, Vec<_>) = workspace
Expand All @@ -30,22 +28,11 @@ pub fn compile_workspace(
// Compile all of the packages in parallel.
let program_results: Vec<CompilationResult<CompiledProgram>> = binary_packages
.par_iter()
.map(|package| {
compile_program(
file_manager,
parsed_files,
package,
compile_options,
expression_width,
None,
)
})
.map(|package| compile_program(file_manager, parsed_files, package, compile_options, None))
.collect();
let contract_results: Vec<CompilationResult<CompiledContract>> = contract_packages
.par_iter()
.map(|package| {
compile_contract(file_manager, parsed_files, package, compile_options, expression_width)
})
.map(|package| compile_contract(file_manager, parsed_files, package, compile_options))
.collect();

// Report any warnings/errors which were encountered during compilation.
Expand Down Expand Up @@ -80,34 +67,20 @@ pub fn compile_program(
parsed_files: &ParsedFiles,
package: &Package,
compile_options: &CompileOptions,
expression_width: ExpressionWidth,
cached_program: Option<CompiledProgram>,
) -> CompilationResult<CompiledProgram> {
let (mut context, crate_id) = prepare_package(file_manager, parsed_files, package);

let (program, warnings) =
noirc_driver::compile_main(&mut context, crate_id, compile_options, cached_program)?;

// Apply backend specific optimizations.
let optimized_program = crate::ops::optimize_program(program, expression_width);

Ok((optimized_program, warnings))
noirc_driver::compile_main(&mut context, crate_id, compile_options, cached_program)
}

pub fn compile_contract(
file_manager: &FileManager,
parsed_files: &ParsedFiles,
package: &Package,
compile_options: &CompileOptions,
expression_width: ExpressionWidth,
) -> CompilationResult<CompiledContract> {
let (mut context, crate_id) = prepare_package(file_manager, parsed_files, package);
let (contract, warnings) =
noirc_driver::compile_contract(&mut context, crate_id, compile_options)?;

let optimized_contract = crate::ops::optimize_contract(contract, expression_width);

Ok((optimized_contract, warnings))
noirc_driver::compile_contract(&mut context, crate_id, compile_options)
}

pub(crate) fn report_errors<T>(
Expand Down
3 changes: 3 additions & 0 deletions tooling/nargo/src/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ pub use self::compile::{compile_contract, compile_program, compile_workspace};
pub use self::execute::execute_circuit;
pub use self::foreign_calls::{DefaultForeignCallExecutor, ForeignCallExecutor};
pub use self::optimize::{optimize_contract, optimize_program};
pub use self::transform::{transform_contract, transform_program};

pub use self::test::{run_test, TestStatus};

mod compile;
mod execute;
mod foreign_calls;
mod optimize;
mod test;
mod transform;
18 changes: 4 additions & 14 deletions tooling/nargo/src/ops/optimize.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
use acvm::ExpressionWidth;
use iter_extended::vecmap;
use noirc_driver::{CompiledContract, CompiledProgram};

pub fn optimize_program(
mut program: CompiledProgram,
expression_width: ExpressionWidth,
) -> CompiledProgram {
let (optimized_circuit, location_map) =
acvm::compiler::compile(program.circuit, expression_width);

pub fn optimize_program(mut program: CompiledProgram) -> CompiledProgram {
let (optimized_circuit, location_map) = acvm::compiler::optimize(program.circuit);
program.circuit = optimized_circuit;
program.debug.update_acir(location_map);
program
}

pub fn optimize_contract(
contract: CompiledContract,
expression_width: ExpressionWidth,
) -> CompiledContract {
pub fn optimize_contract(contract: CompiledContract) -> CompiledContract {
let functions = vecmap(contract.functions, |mut func| {
let (optimized_bytecode, location_map) =
acvm::compiler::compile(func.bytecode, expression_width);
let (optimized_bytecode, location_map) = acvm::compiler::optimize(func.bytecode);
func.bytecode = optimized_bytecode;
func.debug.update_acir(location_map);
func
Expand Down
30 changes: 30 additions & 0 deletions tooling/nargo/src/ops/transform.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use acvm::ExpressionWidth;
use iter_extended::vecmap;
use noirc_driver::{CompiledContract, CompiledProgram};

pub fn transform_program(
mut program: CompiledProgram,
expression_width: ExpressionWidth,
) -> CompiledProgram {
let (optimized_circuit, location_map) =
acvm::compiler::compile(program.circuit, expression_width);

program.circuit = optimized_circuit;
program.debug.update_acir(location_map);
program
}

pub fn transform_contract(
contract: CompiledContract,
expression_width: ExpressionWidth,
) -> CompiledContract {
let functions = vecmap(contract.functions, |mut func| {
let (optimized_bytecode, location_map) =
acvm::compiler::compile(func.bytecode, expression_width);
func.bytecode = optimized_bytecode;
func.debug.update_acir(location_map);
func
});

CompiledContract { functions, ..contract }
}
3 changes: 2 additions & 1 deletion tooling/nargo_cli/src/cli/codegen_verifier_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ pub(crate) fn run(
&parsed_files,
package,
&args.compile_options,
expression_width,
None,
);

Expand All @@ -64,6 +63,8 @@ pub(crate) fn run(
args.compile_options.silence_warnings,
)?;

let program = nargo::ops::transform_program(program, expression_width);

let smart_contract_string = backend.eth_contract(&program.circuit)?;

let contract_dir = workspace.contracts_directory_path(package);
Expand Down
19 changes: 4 additions & 15 deletions tooling/nargo_cli/src/cli/compile_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use std::path::Path;

use acvm::ExpressionWidth;

use fm::FileManager;
use nargo::artifacts::program::ProgramArtifact;
use nargo::errors::CompileError;
Expand Down Expand Up @@ -68,7 +66,6 @@ pub(crate) fn run(
&workspace_file_manager,
&parsed_files,
&workspace,
expression_width,
&args.compile_options,
)?;

Expand All @@ -81,9 +78,11 @@ pub(crate) fn run(
// Save build artifacts to disk.
let only_acir = args.compile_options.only_acir;
for (package, program) in binary_packages.into_iter().zip(compiled_program) {
let program = nargo::ops::transform_program(program, expression_width);
save_program(program.clone(), &package, &workspace.target_directory_path(), only_acir);
}
for (package, contract) in contract_packages.into_iter().zip(compiled_contracts) {
let contract = nargo::ops::transform_contract(contract, expression_width);
save_contract(contract, &package, &circuit_dir);
}

Expand All @@ -94,7 +93,6 @@ pub(super) fn compile_workspace(
file_manager: &FileManager,
parsed_files: &ParsedFiles,
workspace: &Workspace,
expression_width: ExpressionWidth,
compile_options: &CompileOptions,
) -> Result<(Vec<CompiledProgram>, Vec<CompiledContract>), CliError> {
let (binary_packages, contract_packages): (Vec<_>, Vec<_>) = workspace
Expand All @@ -114,21 +112,12 @@ pub(super) fn compile_workspace(
.filter(|p| p.noir_version == NOIR_ARTIFACT_VERSION_STRING)
.map(|p| p.into());

compile_program(
file_manager,
parsed_files,
package,
compile_options,
expression_width,
cached_program,
)
compile_program(file_manager, parsed_files, package, compile_options, cached_program)
})
.collect();
let contract_results: Vec<CompilationResult<CompiledContract>> = contract_packages
.par_iter()
.map(|package| {
compile_contract(file_manager, parsed_files, package, compile_options, expression_width)
})
.map(|package| compile_contract(file_manager, parsed_files, package, compile_options))
.collect();

// Report any warnings/errors which were encountered during compilation.
Expand Down
12 changes: 4 additions & 8 deletions tooling/nargo_cli/src/cli/dap_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,8 @@ fn load_and_compile_project(
let parsed_files = parse_all(&workspace_file_manager);

let compile_options = CompileOptions::default();
let compilation_result = compile_program(
&workspace_file_manager,
&parsed_files,
package,
&compile_options,
expression_width,
None,
);
let compilation_result =
compile_program(&workspace_file_manager, &parsed_files, package, &compile_options, None);

let compiled_program = report_errors(
compilation_result,
Expand All @@ -91,6 +85,8 @@ fn load_and_compile_project(
)
.map_err(|_| LoadError("Failed to compile project"))?;

let compiled_program = nargo::ops::transform_program(compiled_program, expression_width);

let (inputs_map, _) =
read_inputs_from_file(&package.root_dir, prover_name, Format::Toml, &compiled_program.abi)
.map_err(|_| LoadError("Failed to read program inputs"))?;
Expand Down
3 changes: 2 additions & 1 deletion tooling/nargo_cli/src/cli/debug_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ pub(crate) fn run(
&parsed_files,
package,
&args.compile_options,
expression_width,
None,
);

Expand All @@ -83,6 +82,8 @@ pub(crate) fn run(
args.compile_options.silence_warnings,
)?;

let compiled_program = nargo::ops::transform_program(compiled_program, expression_width);

run_async(package, compiled_program, &args.prover_name, &args.witness_name, target_dir)
}

Expand Down
Loading