|
| 1 | +use std::collections::HashMap; |
| 2 | + |
1 | 3 | use acvm::Language; |
2 | 4 | use backend_interface::BackendError; |
3 | 5 | use clap::Args; |
4 | 6 | use iter_extended::vecmap; |
5 | | -use nargo::package::Package; |
| 7 | +use nargo::{artifacts::debug::DebugArtifact, package::Package}; |
6 | 8 | use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; |
7 | 9 | use noirc_driver::{ |
8 | 10 | CompileOptions, CompiledContract, CompiledProgram, NOIR_ARTIFACT_VERSION_STRING, |
9 | 11 | }; |
| 12 | +use noirc_errors::{debug_info::OpCodesCount, Location}; |
10 | 13 | use noirc_frontend::graph::CrateName; |
11 | 14 | use prettytable::{row, table, Row}; |
12 | 15 | use rayon::prelude::*; |
@@ -36,6 +39,9 @@ pub(crate) struct InfoCommand { |
36 | 39 | #[clap(long, hide = true)] |
37 | 40 | json: bool, |
38 | 41 |
|
| 42 | + #[clap(long, hide = true)] |
| 43 | + profile_info: bool, |
| 44 | + |
39 | 45 | #[clap(flatten)] |
40 | 46 | compile_options: CompileOptions, |
41 | 47 | } |
@@ -71,6 +77,23 @@ pub(crate) fn run( |
71 | 77 | &args.compile_options, |
72 | 78 | )?; |
73 | 79 |
|
| 80 | + if args.profile_info { |
| 81 | + for compiled_program in &compiled_programs { |
| 82 | + let span_opcodes = compiled_program.debug.count_span_opcodes(); |
| 83 | + let debug_artifact: DebugArtifact = compiled_program.clone().into(); |
| 84 | + print_span_opcodes(&span_opcodes, &debug_artifact); |
| 85 | + } |
| 86 | + |
| 87 | + for compiled_contract in &compiled_contracts { |
| 88 | + let debug_artifact: DebugArtifact = compiled_contract.clone().into(); |
| 89 | + let functions = &compiled_contract.functions; |
| 90 | + for contract_function in functions { |
| 91 | + let span_opcodes = contract_function.debug.count_span_opcodes(); |
| 92 | + print_span_opcodes(&span_opcodes, &debug_artifact); |
| 93 | + } |
| 94 | + } |
| 95 | + } |
| 96 | + |
74 | 97 | let program_info = binary_packages |
75 | 98 | .into_par_iter() |
76 | 99 | .zip(compiled_programs) |
@@ -121,6 +144,55 @@ pub(crate) fn run( |
121 | 144 | Ok(()) |
122 | 145 | } |
123 | 146 |
|
| 147 | +/// Provides profiling information on |
| 148 | +/// |
| 149 | +/// Number of OpCodes in relation to Noir source file |
| 150 | +/// and line number information |
| 151 | +fn print_span_opcodes( |
| 152 | + span_opcodes_map: &HashMap<&Location, OpCodesCount>, |
| 153 | + debug_artifact: &DebugArtifact, |
| 154 | +) { |
| 155 | + let mut pairs: Vec<(&&Location, &OpCodesCount)> = span_opcodes_map.iter().collect(); |
| 156 | + |
| 157 | + pairs.sort_by(|a, b| { |
| 158 | + a.1.acir_size.cmp(&b.1.acir_size).then_with(|| a.1.brillig_size.cmp(&b.1.brillig_size)) |
| 159 | + }); |
| 160 | + |
| 161 | + for (location, opcodes_count) in pairs { |
| 162 | + let debug_file = debug_artifact.file_map.get(&location.file).unwrap(); |
| 163 | + |
| 164 | + let start_byte = byte_index(&debug_file.source, location.span.start() + 1); |
| 165 | + let end_byte = byte_index(&debug_file.source, location.span.end() + 1); |
| 166 | + let range = start_byte..end_byte; |
| 167 | + let span_content = &debug_file.source[range]; |
| 168 | + let line = debug_artifact.location_line_index(**location).unwrap() + 1; |
| 169 | + println!( |
| 170 | + "Ln. {}: {} (ACIR:{}, Brillig:{} opcode|s) in file: {}", |
| 171 | + line, |
| 172 | + span_content, |
| 173 | + opcodes_count.acir_size, |
| 174 | + opcodes_count.brillig_size, |
| 175 | + debug_file.path.to_str().unwrap() |
| 176 | + ); |
| 177 | + } |
| 178 | +} |
| 179 | +fn byte_index(string: &str, index: u32) -> usize { |
| 180 | + let mut byte_index = 0; |
| 181 | + let mut char_index = 0; |
| 182 | + |
| 183 | + #[allow(clippy::explicit_counter_loop)] |
| 184 | + for (byte_offset, _) in string.char_indices() { |
| 185 | + if char_index == index { |
| 186 | + return byte_index; |
| 187 | + } |
| 188 | + |
| 189 | + byte_index = byte_offset; |
| 190 | + char_index += 1; |
| 191 | + } |
| 192 | + |
| 193 | + byte_index |
| 194 | +} |
| 195 | + |
124 | 196 | #[derive(Debug, Default, Serialize)] |
125 | 197 | struct InfoReport { |
126 | 198 | programs: Vec<ProgramInfo>, |
|
0 commit comments