Skip to content

Commit

Permalink
Merge pull request #80 from Chia-Network/20240406-assign-cse-fuzz
Browse files Browse the repository at this point in the history
fix for ability to lift a CSE out of an assign form when it depends on bindings in the assign and fuzz infra for testing
  • Loading branch information
prozacchiwawa authored May 1, 2024
2 parents 78e8362 + a729573 commit e9ff608
Show file tree
Hide file tree
Showing 15 changed files with 852 additions and 17 deletions.
12 changes: 12 additions & 0 deletions resources/tests/cse-bad-letstar.clsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
(mod (blob)
(include *standard-cl-23*)

(defun test-f (blob)
(let*
((first (list 1 2 3))
(copies (list (r first) (r first))))
(c (r first) copies)
)
)
(test-f blob)
)
12 changes: 12 additions & 0 deletions resources/tests/cse-bad.clsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
(mod (blob)
(include *standard-cl-23*)

(defun test-f (blob)
(assign
first (list 1 2 3)
copies (list (r first) (r first))
(c (r first) copies)
)
)
(test-f blob)
)
15 changes: 15 additions & 0 deletions resources/tests/cse-overlap.clsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
(mod (Q)
(include *standard-cl-23*)

(defun F (X)
(assign
A1 (r (r X))
A2 (c A1 (r X))
A3 (c A2 (r (r X)))
A4 (assign B1 (c A1 (r (r X))) (list B1 (r (r X))))
(list A1 A2 A3 A4)
)
)

(F (list Q 99 100 101 102))
)
25 changes: 25 additions & 0 deletions resources/tests/cse-tricky-basic.clsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
(mod (move)
(include *standard-cl-23*)

(defun fhi (ha ca) (sha256 ha ca))
(defun nfh (ha ca) (fhi ha ca))

(defun testf1 (ca)
(assign-lambda
fc (+ ca 1)
sc (* ca 11)
(assign-lambda
tango 121
(if (= ca 13)
(nfh fc sc)
(if (= ca 15)
(fhi fc sc)
tango
)
)
)
)
)

(testf1 move)
)
14 changes: 13 additions & 1 deletion src/compiler/compiler.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use num_bigint::ToBigInt;
use std::borrow::Borrow;
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::fs;
use std::path::PathBuf;
use std::rc::Rc;
Expand All @@ -22,6 +22,8 @@ use crate::compiler::srcloc::Srcloc;
use crate::compiler::{BasicCompileContext, CompileContextWrapper};
use crate::util::Number;

pub const FUZZ_TEST_PRE_CSE_MERGE_FIX_FLAG: usize = 1;

lazy_static! {
pub static ref STANDARD_MACROS: String = {
indoc! {"(
Expand Down Expand Up @@ -84,6 +86,7 @@ pub struct DefaultCompilerOpts {
pub start_env: Option<Rc<SExp>>,
pub disassembly_ver: Option<usize>,
pub prim_map: Rc<HashMap<Vec<u8>, Rc<SExp>>>,
pub diag_flags: Rc<HashSet<usize>>,
pub dialect: AcceptedDialect,
}

Expand Down Expand Up @@ -208,6 +211,9 @@ impl CompilerOpts for DefaultCompilerOpts {
fn get_search_paths(&self) -> Vec<String> {
self.include_dirs.clone()
}
fn diag_flags(&self) -> Rc<HashSet<usize>> {
self.diag_flags.clone()
}

fn set_dialect(&self, dialect: AcceptedDialect) -> Rc<dyn CompilerOpts> {
let mut copy = self.clone();
Expand Down Expand Up @@ -264,6 +270,11 @@ impl CompilerOpts for DefaultCompilerOpts {
copy.prim_map = prims;
Rc::new(copy)
}
fn set_diag_flags(&self, flags: Rc<HashSet<usize>>) -> Rc<dyn CompilerOpts> {
let mut copy = self.clone();
copy.diag_flags = flags;
Rc::new(copy)
}

fn read_new_file(
&self,
Expand Down Expand Up @@ -330,6 +341,7 @@ impl DefaultCompilerOpts {
dialect: AcceptedDialect::default(),
prim_map: create_prim_map(),
disassembly_ver: None,
diag_flags: Rc::new(HashSet::default()),
}
}
}
Expand Down
17 changes: 17 additions & 0 deletions src/compiler/comptypes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,9 @@ pub trait CompilerOpts {
fn prim_map(&self) -> Rc<HashMap<Vec<u8>, Rc<SExp>>>;
/// Specifies the search paths we're carrying.
fn get_search_paths(&self) -> Vec<String>;
/// Specifies flags that were passed down to various consumers. This is
/// open ended for various purposes, such as diagnostics.
fn diag_flags(&self) -> Rc<HashSet<usize>>;

/// Set the dialect.
fn set_dialect(&self, dialect: AcceptedDialect) -> Rc<dyn CompilerOpts>;
Expand All @@ -444,6 +447,8 @@ pub trait CompilerOpts {
fn set_start_env(&self, start_env: Option<Rc<SExp>>) -> Rc<dyn CompilerOpts>;
/// Set the primitive map in use so we can add custom primitives.
fn set_prim_map(&self, new_map: Rc<HashMap<Vec<u8>, Rc<SExp>>>) -> Rc<dyn CompilerOpts>;
/// Set the flags this CompilerOpts holds. Consumers can examine these.
fn set_diag_flags(&self, new_flags: Rc<HashSet<usize>>) -> Rc<dyn CompilerOpts>;

/// Using the search paths list we have, try to read a file by name,
/// Returning the expanded path to the file and its content.
Expand Down Expand Up @@ -516,6 +521,9 @@ pub trait HasCompilerOptsDelegation {
fn override_get_search_paths(&self) -> Vec<String> {
self.compiler_opts().get_search_paths()
}
fn override_diag_flags(&self) -> Rc<HashSet<usize>> {
self.compiler_opts().diag_flags()
}

fn override_set_dialect(&self, dialect: AcceptedDialect) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_dialect(dialect))
Expand Down Expand Up @@ -547,6 +555,9 @@ pub trait HasCompilerOptsDelegation {
fn override_set_start_env(&self, start_env: Option<Rc<SExp>>) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_start_env(start_env))
}
fn override_set_diag_flags(&self, flags: Rc<HashSet<usize>>) -> Rc<dyn CompilerOpts> {
self.update_compiler_opts(|o| o.set_diag_flags(flags))
}
fn override_set_prim_map(
&self,
new_map: Rc<HashMap<Vec<u8>, Rc<SExp>>>,
Expand Down Expand Up @@ -610,6 +621,9 @@ impl<T: HasCompilerOptsDelegation> CompilerOpts for T {
fn get_search_paths(&self) -> Vec<String> {
self.override_get_search_paths()
}
fn diag_flags(&self) -> Rc<HashSet<usize>> {
self.override_diag_flags()
}

fn set_dialect(&self, dialect: AcceptedDialect) -> Rc<dyn CompilerOpts> {
self.override_set_dialect(dialect)
Expand Down Expand Up @@ -644,6 +658,9 @@ impl<T: HasCompilerOptsDelegation> CompilerOpts for T {
fn set_prim_map(&self, new_map: Rc<HashMap<Vec<u8>, Rc<SExp>>>) -> Rc<dyn CompilerOpts> {
self.override_set_prim_map(new_map)
}
fn set_diag_flags(&self, new_flags: Rc<HashSet<usize>>) -> Rc<dyn CompilerOpts> {
self.override_set_diag_flags(new_flags)
}
fn read_new_file(
&self,
inc_from: String,
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/frontend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fn collect_used_names_binding(body: &Binding) -> Vec<Vec<u8>> {
collect_used_names_bodyform(body.body.borrow())
}

fn collect_used_names_bodyform(body: &BodyForm) -> Vec<Vec<u8>> {
pub fn collect_used_names_bodyform(body: &BodyForm) -> Vec<Vec<u8>> {
match body {
BodyForm::Let(_, letdata) => {
let mut result = Vec::new();
Expand Down
25 changes: 23 additions & 2 deletions src/compiler/optimize/above22.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use clvmr::allocator::Allocator;

use crate::classic::clvm_tools::stages::stage_0::TRunProgram;

#[cfg(any(test, feature = "fuzz"))]
use crate::compiler::compiler::FUZZ_TEST_PRE_CSE_MERGE_FIX_FLAG;
use crate::compiler::comptypes::{
BodyForm, CompileErr, CompileForm, CompilerOpts, DefunData, HelperForm, PrimaryCodegen,
};
Expand All @@ -25,6 +27,18 @@ use crate::compiler::StartOfCodegenOptimization;
#[derive(Default, Clone)]
pub struct Strategy23 {}

#[cfg(any(test, feature = "fuzz"))]
fn enable_cse_merge_fix_so_can_be_disabled_for_tests(opts: Rc<dyn CompilerOpts>) -> bool {
!opts
.diag_flags()
.contains(&FUZZ_TEST_PRE_CSE_MERGE_FIX_FLAG)
}

#[cfg(not(any(test, feature = "fuzz")))]
fn enable_cse_merge_fix_so_can_be_disabled_for_tests(_opts: Rc<dyn CompilerOpts>) -> bool {
true
}

impl Strategy23 {
pub fn new() -> Self {
Strategy23 {}
Expand All @@ -36,13 +50,20 @@ impl Optimization for Strategy23 {
&mut self,
_allocator: &mut Allocator,
_runner: Rc<dyn TRunProgram>,
_opts: Rc<dyn CompilerOpts>,
opts: Rc<dyn CompilerOpts>,
mut p0: CompileForm,
) -> Result<CompileForm, CompileErr> {
let mut rebuilt_helpers = Vec::new();
let enable_merge_disable_for_tests =
enable_cse_merge_fix_so_can_be_disabled_for_tests(opts.clone());
for h in p0.helpers.iter() {
if let HelperForm::Defun(inline, d) = h {
let function_body = cse_optimize_bodyform(&h.loc(), h.name(), d.body.borrow())?;
let function_body = cse_optimize_bodyform(
&h.loc(),
h.name(),
enable_merge_disable_for_tests,
d.body.borrow(),
)?;
// Ok we've got a body that is now a let stack.
let new_helper = HelperForm::Defun(
*inline,
Expand Down
Loading

0 comments on commit e9ff608

Please sign in to comment.