Skip to content

Commit 5f6bfbc

Browse files
committed
Extract program
1 parent 11d7933 commit 5f6bfbc

File tree

4 files changed

+187
-232
lines changed

4 files changed

+187
-232
lines changed

cli-openvm/src/main.rs

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use metrics_util::{debugging::DebuggingRecorder, layers::Layer};
44
use openvm_sdk::StdIn;
55
use openvm_stark_sdk::bench::serialize_metric_snapshot;
66
use powdr_autoprecompiles::pgo::{pgo_config, PgoType};
7-
use powdr_openvm::{default_powdr_openvm_config, CompiledProgram, GuestOptions};
7+
use powdr_openvm::{compile_openvm, default_powdr_openvm_config, CompiledProgram, GuestOptions};
88

99
#[cfg(feature = "metrics")]
1010
use openvm_stark_sdk::metrics_tracing::TimingMetricsLayer;
@@ -140,14 +140,13 @@ fn run_command(command: Commands) {
140140
if let Some(apc_candidates_dir) = apc_candidates_dir {
141141
powdr_config = powdr_config.with_apc_candidates_dir(apc_candidates_dir);
142142
}
143-
let execution_profile = powdr_openvm::execution_profile_from_guest(
144-
&guest,
145-
guest_opts.clone(),
146-
stdin_from(input),
147-
);
143+
let guest_program = compile_openvm(&guest, guest_opts.clone()).unwrap();
144+
let execution_profile =
145+
powdr_openvm::execution_profile_from_guest(&guest_program, stdin_from(input));
146+
148147
let pgo_config = pgo_config(pgo, max_columns, execution_profile);
149148
let program =
150-
powdr_openvm::compile_guest(&guest, guest_opts, powdr_config, pgo_config).unwrap();
149+
powdr_openvm::compile_exe(guest_program, powdr_config, pgo_config).unwrap();
151150
write_program_to_file(program, &format!("{guest}_compiled.cbor")).unwrap();
152151
}
153152

@@ -165,16 +164,13 @@ fn run_command(command: Commands) {
165164
if let Some(apc_candidates_dir) = apc_candidates_dir {
166165
powdr_config = powdr_config.with_apc_candidates_dir(apc_candidates_dir);
167166
}
168-
let execution_profile = powdr_openvm::execution_profile_from_guest(
169-
&guest,
170-
guest_opts.clone(),
171-
stdin_from(input),
172-
);
167+
let guest_program = compile_openvm(&guest, guest_opts.clone()).unwrap();
168+
let execution_profile =
169+
powdr_openvm::execution_profile_from_guest(&guest_program, stdin_from(input));
173170
let pgo_config = pgo_config(pgo, max_columns, execution_profile);
174171
let compile_and_exec = || {
175172
let program =
176-
powdr_openvm::compile_guest(&guest, guest_opts, powdr_config, pgo_config)
177-
.unwrap();
173+
powdr_openvm::compile_exe(guest_program, powdr_config, pgo_config).unwrap();
178174
powdr_openvm::execute(program, stdin_from(input)).unwrap();
179175
};
180176
if let Some(metrics_path) = metrics {
@@ -203,16 +199,14 @@ fn run_command(command: Commands) {
203199
if let Some(apc_candidates_dir) = apc_candidates_dir {
204200
powdr_config = powdr_config.with_apc_candidates_dir(apc_candidates_dir);
205201
}
206-
let execution_profile = powdr_openvm::execution_profile_from_guest(
207-
&guest,
208-
guest_opts.clone(),
209-
stdin_from(input),
210-
);
202+
let guest_program = compile_openvm(&guest, guest_opts).unwrap();
203+
204+
let execution_profile =
205+
powdr_openvm::execution_profile_from_guest(&guest_program, stdin_from(input));
211206
let pgo_config = pgo_config(pgo, max_columns, execution_profile);
212207
let compile_and_prove = || {
213208
let program =
214-
powdr_openvm::compile_guest(&guest, guest_opts, powdr_config, pgo_config)
215-
.unwrap();
209+
powdr_openvm::compile_exe(guest_program, powdr_config, pgo_config).unwrap();
216210
powdr_openvm::prove(&program, mock, recursion, stdin_from(input), None).unwrap()
217211
};
218212
if let Some(metrics_path) = metrics {

openvm/src/customize_exe.rs

Lines changed: 14 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::{BTreeSet, HashMap};
1+
use std::collections::HashMap;
22

33
use std::fmt::Display;
44
use std::hash::Hash;
@@ -10,7 +10,6 @@ use crate::bus_map::OpenVmBusType;
1010
use crate::extraction_utils::{get_air_metrics, AirWidthsDiff, OriginalAirs, OriginalVmConfig};
1111
use crate::instruction_formatter::openvm_instruction_formatter;
1212
use crate::memory_bus_interaction::OpenVmMemoryBusInteraction;
13-
use crate::opcode::branch_opcodes_bigint_set;
1413
use crate::powdr_extension::chip::PowdrAir;
1514
use crate::utils::UnsupportedOpenVmReferenceError;
1615
use crate::OriginalCompiledProgram;
@@ -27,7 +26,7 @@ use openvm_stark_sdk::p3_baby_bear::BabyBear;
2726
use powdr_autoprecompiles::adapter::{
2827
Adapter, AdapterApc, AdapterApcWithStats, AdapterVmConfig, ApcWithStats, PgoAdapter,
2928
};
30-
use powdr_autoprecompiles::blocks::{collect_basic_blocks, BasicBlock, Instruction, Program};
29+
use powdr_autoprecompiles::blocks::{BasicBlock, Instruction, Program};
3130
use powdr_autoprecompiles::evaluation::{evaluate_apc, EvaluationResult};
3231
use powdr_autoprecompiles::expression::try_convert;
3332
use powdr_autoprecompiles::pgo::{ApcCandidateJsonExport, Candidate, KnapsackItem};
@@ -78,7 +77,7 @@ impl<'a> Adapter for BabyBearOpenVmApcAdapter<'a> {
7877

7978
/// A newtype wrapper around `OpenVmProgram` to implement the `Program` trait.
8079
/// This is necessary because we cannot implement a foreign trait for a foreign type.
81-
pub struct Prog<'a, F>(&'a OpenVmProgram<F>);
80+
pub struct Prog<'a, F>(pub &'a OpenVmProgram<F>);
8281

8382
impl<'a, F> From<&'a OpenVmProgram<F>> for Prog<'a, F> {
8483
fn from(program: &'a OpenVmProgram<F>) -> Self {
@@ -140,30 +139,20 @@ impl<'a, F: PrimeField32> Program<Instr<F>> for Prog<'a, F> {
140139
}
141140

142141
pub fn customize<'a, P: PgoAdapter<Adapter = BabyBearOpenVmApcAdapter<'a>>>(
143-
OriginalCompiledProgram {
144-
exe,
145-
vm_config,
146-
elf,
147-
}: OriginalCompiledProgram,
142+
original_program: OriginalCompiledProgram,
148143
config: PowdrConfig,
149144
pgo: P,
150145
) -> CompiledProgram {
151-
let labels = elf.text_labels();
152-
let debug_info = elf.debug_info();
153-
let original_config = OriginalVmConfig::new(vm_config.clone());
146+
let original_config = OriginalVmConfig::new(original_program.vm_config.clone());
154147
let airs = original_config.airs(config.degree_bound.identities).expect("Failed to convert the AIR of an OpenVM instruction, even after filtering by the blacklist!");
155148
let bus_map = original_config.bus_map();
156149

157-
let jumpdest_set = add_extra_targets(
158-
&exe.program,
159-
labels.clone(),
160-
exe.program.pc_base,
161-
DEFAULT_PC_STEP,
162-
);
163-
164-
let program = Prog(&exe.program);
165-
166-
let range_tuple_checker_sizes = vm_config.sdk.rv32m.unwrap().range_tuple_checker_sizes;
150+
let range_tuple_checker_sizes = original_program
151+
.vm_config
152+
.sdk
153+
.rv32m
154+
.unwrap()
155+
.range_tuple_checker_sizes;
167156
let vm_config = VmConfig {
168157
instruction_handler: &airs,
169158
bus_interaction_handler: OpenVmBusInteractionHandler::new(
@@ -173,13 +162,9 @@ pub fn customize<'a, P: PgoAdapter<Adapter = BabyBearOpenVmApcAdapter<'a>>>(
173162
bus_map: bus_map.clone(),
174163
};
175164

176-
// Convert the jump destinations to u64 for compatibility with the `collect_basic_blocks` function.
177-
let jumpdest_set = jumpdest_set
178-
.iter()
179-
.map(|&x| x as u64)
180-
.collect::<BTreeSet<_>>();
181-
182-
let blocks = collect_basic_blocks::<BabyBearOpenVmApcAdapter>(&program, &jumpdest_set, &airs);
165+
let blocks = original_program.collect_basic_blocks(config.degree_bound.identities);
166+
let exe = original_program.exe;
167+
let debug_info = original_program.elf.debug_info();
183168
tracing::info!(
184169
"Got {} basic blocks from `collect_basic_blocks`",
185170
blocks.len()
@@ -264,36 +249,6 @@ pub fn customize<'a, P: PgoAdapter<Adapter = BabyBearOpenVmApcAdapter<'a>>>(
264249
}
265250
}
266251

267-
/// Besides the base RISCV-V branching instructions, the bigint extension adds two more branching
268-
/// instruction classes over BranchEqual and BranchLessThan.
269-
/// Those instructions have the form <INSTR rs0 rs1 target_offset ...>, where target_offset is the
270-
/// relative jump we're interested in.
271-
/// This means that for a given program address A containing the instruction above,
272-
/// we add A + target_offset as a target as well.
273-
fn add_extra_targets<F: PrimeField32>(
274-
program: &OpenVmProgram<F>,
275-
mut labels: BTreeSet<u32>,
276-
base_pc: u32,
277-
pc_step: u32,
278-
) -> BTreeSet<u32> {
279-
let branch_opcodes_bigint = branch_opcodes_bigint_set();
280-
let new_labels = program
281-
.instructions_and_debug_infos
282-
.iter()
283-
.enumerate()
284-
.filter_map(|(i, instr)| {
285-
let instr = instr.as_ref().unwrap().0.clone();
286-
let adjusted_pc = base_pc + (i as u32) * pc_step;
287-
let op = instr.opcode;
288-
branch_opcodes_bigint
289-
.contains(&op)
290-
.then_some(adjusted_pc + instr.c.as_canonical_u32())
291-
});
292-
labels.extend(new_labels);
293-
294-
labels
295-
}
296-
297252
pub fn openvm_bus_interaction_to_powdr<F: PrimeField32>(
298253
interaction: &SymbolicInteraction<F>,
299254
columns: &[Arc<String>],

0 commit comments

Comments
 (0)