Skip to content

Commit 06e9b0e

Browse files
wrwgbors-diem
authored andcommitted
[move-to-yul] Setup experiments.
This PR sets up experiments for code generation and wires them to the test infra. This will be needed for the upcoming control flow graph optimizations, and down the road also for other things. A new module `experiments.rs` is added which declares constants for experiments. An experiment can be activated on the command line with `--experiment=<name>`. In a baseline tests, one can add the comment ``` // experiment: <name> ``` ... to the source. The test is then run both with and without the experiment, producing different baseline files. A first experiment is used to supress generation of source info in baseline tests by default. This is useful because a lot of useless diffs are created if source positions only slightly shift. Source info will now only be generated during tests if `--experiment=capture-source-info` is set. Only one of our tests has this on, in order to ensure source info keeps being tested. Closes: #88
1 parent b5146b4 commit 06e9b0e

27 files changed

+1413
-891
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) The Diem Core Contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
/// Container for experiments in the compiler. Those can be activated
5+
/// via the `--experiment=<name>` flag.
6+
///
7+
/// One can activate an experiment in a test source by using a comment as such:
8+
/// ```
9+
/// // experiment: <name>
10+
/// ```
11+
/// This can be repeated an arbitrary number of times. The test will then be run for
12+
/// the default configuration and for each of the named experiments separately (if it is a
13+
/// baseline test, a different baseline file will be generated each time).
14+
///
15+
/// Each new experiment should have a description and explicit note about its retention.
16+
///
17+
/// - Permanent: the experiment is available indefinitely
18+
/// - Temporary: the experiment is intended to be removed after some time. Please document
19+
/// the condition under which it can be removed.
20+
pub struct Experiment();
21+
22+
impl Experiment {
23+
/// Capture source information in baseline generation when running a test. By default,
24+
/// during tests this is off.
25+
/// Retention: permanent
26+
pub const CAPTURE_SOURCE_INFO: &'static str = "capture-source-info";
27+
}

language/evm/move-to-yul/src/functions.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -216,17 +216,19 @@ impl<'a> FunctionGenerator<'a> {
216216
bc.display(target, &BTreeMap::default())
217217
);
218218
let print_loc = || {
219-
let loc = target.get_bytecode_loc(bc.get_attr_id());
220-
emitln!(
221-
ctx.writer,
222-
"/// @src {}:{}:{}",
223-
ctx.file_id_map
224-
.get(&loc.file_id())
225-
.expect("file id defined")
226-
.0,
227-
loc.span().start(),
228-
loc.span().end()
229-
);
219+
if ctx.options.generate_source_info() {
220+
let loc = target.get_bytecode_loc(bc.get_attr_id());
221+
emitln!(
222+
ctx.writer,
223+
"/// @src {}:{}:{}",
224+
ctx.file_id_map
225+
.get(&loc.file_id())
226+
.expect("file id defined")
227+
.0,
228+
loc.span().start(),
229+
loc.span().end()
230+
);
231+
}
230232
};
231233
let get_block = |l| label_map.get(l).expect("label has corresponding block");
232234
// Need to make a clone below to avoid cascading borrow problems. We don't want the

language/evm/move-to-yul/src/generator.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -189,22 +189,24 @@ impl Generator {
189189
ctx.options.version(),
190190
);
191191
emitln!(ctx.writer);
192-
let mut use_src_emitted = false;
193-
for (file_no, file_path) in ctx
194-
.file_id_map
195-
.values()
196-
.sorted_by(|(n1, _), (n2, _)| n1.cmp(n2))
197-
{
198-
let use_str = format!("{}:\"{}\"", file_no, file_path);
199-
if !use_src_emitted {
200-
emitln!(ctx.writer, "/// @use-src {}", use_str);
201-
use_src_emitted = true;
202-
} else {
203-
emitln!(ctx.writer, "/// , {}", use_str)
192+
if ctx.options.generate_source_info() {
193+
let mut use_src_emitted = false;
194+
for (file_no, file_path) in ctx
195+
.file_id_map
196+
.values()
197+
.sorted_by(|(n1, _), (n2, _)| n1.cmp(n2))
198+
{
199+
let use_str = format!("{}:\"{}\"", file_no, file_path);
200+
if !use_src_emitted {
201+
emitln!(ctx.writer, "/// @use-src {}", use_str);
202+
use_src_emitted = true;
203+
} else {
204+
emitln!(ctx.writer, "/// , {}", use_str)
205+
}
204206
}
207+
emitln!(ctx.writer);
205208
}
206209
emitln!(ctx.writer);
207-
emitln!(ctx.writer);
208210
}
209211

210212
/// Generate optional creator (contract constructor).

language/evm/move-to-yul/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
mod attributes;
77
mod context;
88
mod evm_transformation;
9+
mod experiments;
910
mod functions;
1011
pub mod generator;
1112
mod native_functions;
1213
pub mod options;
1314
mod yul_functions;
14-
// mod object;
1515

1616
use crate::{generator::Generator, options::Options};
1717
use anyhow::anyhow;
Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// Copyright (c) The Diem Core Contributors
22
// SPDX-License-Identifier: Apache-2.0
33

4+
use crate::experiments::Experiment;
45
use codespan_reporting::diagnostic::Severity;
5-
use move_command_line_common::env::read_env_var;
66
use structopt::StructOpt;
77

8+
/// Options for a run of the compiler.
89
#[derive(StructOpt, Debug)]
910
#[structopt(name = "move-to-yul", about = "Move Solidity Generator")]
1011
pub struct Options {
@@ -16,37 +17,49 @@ pub struct Options {
1617
pub named_address_mapping: Vec<String>,
1718
/// Output file name.
1819
#[structopt(short)]
19-
#[structopt(long)]
20+
#[structopt(long, default_value = "output.yul")]
2021
pub output: String,
2122
/// Solc executable
22-
#[structopt(long)]
23+
#[structopt(long, env = "SOLC_EXE", default_value = "solc")]
2324
pub solc_exe: String,
2425
/// Whether to dump bytecode to a file.
2526
#[structopt(long = "dump-bytecode")]
2627
pub dump_bytecode: bool,
28+
/// Whether we generate code for tests.
29+
#[structopt(long)]
30+
pub testing: bool,
31+
/// Active experiments.
32+
#[structopt(short)]
33+
#[structopt(long = "experiment")]
34+
pub experiments: Vec<String>,
2735
/// Sources to compile (positional arg)
2836
pub sources: Vec<String>,
2937
}
3038

3139
impl Default for Options {
3240
fn default() -> Self {
33-
Self {
34-
dependencies: vec![],
35-
named_address_mapping: vec![],
36-
output: "output.yul".to_string(),
37-
solc_exe: read_env_var("SOLC_EXE"),
38-
dump_bytecode: false,
39-
sources: vec![],
40-
}
41+
Options::from_iter(std::iter::empty::<String>())
4142
}
4243
}
4344

4445
impl Options {
46+
/// Returns the least severity of diagnosis which shall be reported.
4547
pub fn report_severity(&self) -> Severity {
4648
Severity::Warning
4749
}
4850

51+
/// Returns the version of the tool.
4952
pub fn version(&self) -> &str {
5053
"0.0"
5154
}
55+
56+
/// Returns true if an experiment is on.
57+
pub fn experiment_on(&self, name: &str) -> bool {
58+
self.experiments.iter().any(|s| s == name)
59+
}
60+
61+
/// Returns true if source info should be generated during tests.
62+
pub fn generate_source_info(&self) -> bool {
63+
!self.testing || self.experiment_on(Experiment::CAPTURE_SOURCE_INFO)
64+
}
5265
}

0 commit comments

Comments
 (0)