Skip to content

Commit

Permalink
Merge branch 'master' into xunilrj/make-bytes-own-buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
IGI-111 authored Jul 1, 2024
2 parents 1856980 + d922748 commit fcb18c9
Show file tree
Hide file tree
Showing 11 changed files with 48 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ impl AbstractInstructionSet {
pub(crate) fn optimize(self, data_section: &DataSection) -> AbstractInstructionSet {
self.const_indexing_aggregates_function(data_section)
.dce()
.simplify_cfg()
.remove_sequential_jumps()
.remove_redundant_moves()
.remove_unused_ops()
Expand Down
44 changes: 42 additions & 2 deletions sway-core/src/asm_generation/fuel/optimizations.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::collections::BTreeSet;
use std::collections::{BTreeSet, HashMap};

use either::Either;
use rustc_hash::{FxHashMap, FxHashSet};

use crate::{
asm_generation::fuel::compiler_constants,
asm_lang::{ControlFlowOp, VirtualImmediate12, VirtualOp, VirtualRegister},
asm_lang::{ControlFlowOp, Label, VirtualImmediate12, VirtualOp, VirtualRegister},
};

use super::{
Expand Down Expand Up @@ -269,4 +269,44 @@ impl AbstractInstructionSet {

self
}

// Remove unreachable instructions.
pub(crate) fn simplify_cfg(mut self) -> AbstractInstructionSet {
let ops = &self.ops;

if ops.is_empty() {
return self;
}

// Keep track of a map between jump labels and op indices. Useful to compute op successors.
let mut label_to_index: HashMap<Label, usize> = HashMap::default();
for (idx, op) in ops.iter().enumerate() {
if let Either::Right(ControlFlowOp::Label(op_label)) = op.opcode {
label_to_index.insert(op_label, idx);
}
}

let mut reachables = vec![false; ops.len()];
let mut worklist = vec![0];
while let Some(op_idx) = worklist.pop() {
assert!(!reachables[op_idx]);
reachables[op_idx] = true;
let op = &ops[op_idx];
for s in &op.successors(op_idx, ops, &label_to_index) {
if !reachables[*s] {
worklist.push(*s);
}
}
}

let reachable_ops = self
.ops
.into_iter()
.enumerate()
.filter_map(|(idx, op)| if reachables[idx] { Some(op) } else { None })
.collect();
self.ops = reachable_ops;

self
}
}
4 changes: 0 additions & 4 deletions sway-core/src/ir_generation/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,12 +465,8 @@ impl<'eng> FnCompiler<'eng> {
selector,
type_binding: _,
call_path_typeid: _,
deferred_monomorphization,
..
} => {
if *deferred_monomorphization {
return Err(CompileError::Internal("Trying to compile a deferred function application with deferred monomorphization", name.span()));
}
if let Some(metadata) = selector {
self.compile_contract_call_encoding_v0(
context,
Expand Down
13 changes: 1 addition & 12 deletions sway-core/src/language/ty/expression/expression_variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ pub enum TyExpressionVariant {
type_binding: Option<TypeBinding<()>>,
/// In case it is a method should contain a TypeId to either an enum, struct or a type alias.
call_path_typeid: Option<TypeId>,
/// This tracks whether monomorphization has been deferred between compiler stages.
deferred_monomorphization: bool,
contract_call_params: IndexMap<String, TyExpression>,
contract_caller: Option<Box<TyExpression>>,
},
Expand Down Expand Up @@ -447,7 +445,6 @@ impl HashWithEngines for TyExpressionVariant {
selector: _,
type_binding: _,
call_path_typeid: _,
deferred_monomorphization: _,
..
} => {
call_path.hash(state);
Expand Down Expand Up @@ -1123,15 +1120,7 @@ impl TypeCheckFinalization for TyExpressionVariant {
handler.scope(|handler| {
match self {
TyExpressionVariant::Literal(_) => {}
TyExpressionVariant::FunctionApplication {
arguments,
deferred_monomorphization,
..
} => {
// If the function application was deferred we need to monomorphize it here.
// But at the moment monomorphization is fully resolved before type check finalization.
assert!(!(*deferred_monomorphization));

TyExpressionVariant::FunctionApplication { arguments, .. } => {
for (_, arg) in arguments.iter_mut() {
let _ = arg.type_check_finalize(handler, ctx);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -459,11 +459,6 @@ impl TyImplTrait {
IsExtendingExistingImpl::No,
)?;

// Now lets do a partial type check of the body of the functions (while deferring full
// monomorphization of function applications). We will use this tree to perform type check
// analysis (mainly dependency analysis), and re-type check the items ordered by dependency.
let mut defer_ctx = ctx.by_ref().with_defer_monomorphization();

let new_items = &impl_trait.items;
for (item, new_item) in items.clone().into_iter().zip(new_items) {
match (item, new_item) {
Expand All @@ -473,7 +468,7 @@ impl TyImplTrait {
(*decl_engine.get_function(decl_ref.id())).clone();
let new_ty_fn_decl = match ty::TyFunctionDecl::type_check_body(
handler,
defer_ctx.by_ref(),
ctx.by_ref(),
&fn_decl,
&mut ty_fn_decl,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ impl ty::TyExpression {
selector: None,
type_binding: None,
call_path_typeid: None,
deferred_monomorphization: false,
contract_call_params: IndexMap::new(),
contract_caller: None,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ pub(crate) fn instantiate_function_application(
selector: None,
type_binding: Some(call_path_binding.strip_inner()),
call_path_typeid: None,
deferred_monomorphization: false,
contract_call_params: IndexMap::new(),
contract_caller: None,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -699,9 +699,7 @@ pub(crate) fn type_check_method_application(
.ok();

if let Some(decl_mapping) = decl_mapping {
if !ctx.defer_monomorphization() {
method.replace_decls(&decl_mapping, handler, &mut ctx)?;
}
method.replace_decls(&decl_mapping, handler, &mut ctx)?;
}

let method_sig = TyFunctionSig::from_fn_decl(&method);
Expand All @@ -712,7 +710,6 @@ pub(crate) fn type_check_method_application(
if method_sig.is_concrete(engines)
&& method.is_type_check_finalized
&& !method.is_trait_method_dummy
&& !ctx.defer_monomorphization()
{
ctx.engines()
.qe()
Expand All @@ -727,7 +724,6 @@ pub(crate) fn type_check_method_application(
selector,
type_binding: Some(method_name_binding.strip_inner()),
call_path_typeid: Some(call_path_typeid),
deferred_monomorphization: ctx.defer_monomorphization(),
contract_call_params: contract_call_params_map,
contract_caller: None,
};
Expand Down
24 changes: 0 additions & 24 deletions sway-core/src/semantic_analysis/type_check_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,6 @@ pub struct TypeCheckContext<'a> {
/// body).
disallow_functions: bool,

/// Indicates when semantic analysis should be deferred for function/method applications.
/// This is currently used to perform the final type checking and monomorphization in the
/// case of impl trait methods after the initial type checked AST is constructed, and
/// after we perform a dependency analysis on the tree.
defer_monomorphization: bool,

/// Indicates when semantic analysis is type checking storage declaration.
storage_declaration: bool,

Expand Down Expand Up @@ -127,7 +121,6 @@ impl<'a> TypeCheckContext<'a> {
purity: Purity::default(),
kind: TreeType::Contract,
disallow_functions: false,
defer_monomorphization: false,
storage_declaration: false,
experimental,
}
Expand Down Expand Up @@ -169,7 +162,6 @@ impl<'a> TypeCheckContext<'a> {
purity: Purity::default(),
kind: TreeType::Contract,
disallow_functions: false,
defer_monomorphization: false,
storage_declaration: false,
experimental,
}
Expand Down Expand Up @@ -199,7 +191,6 @@ impl<'a> TypeCheckContext<'a> {
kind: self.kind,
engines: self.engines,
disallow_functions: self.disallow_functions,
defer_monomorphization: self.defer_monomorphization,
storage_declaration: self.storage_declaration,
experimental: self.experimental,
}
Expand All @@ -226,7 +217,6 @@ impl<'a> TypeCheckContext<'a> {
kind: self.kind,
engines: self.engines,
disallow_functions: self.disallow_functions,
defer_monomorphization: self.defer_monomorphization,
storage_declaration: self.storage_declaration,
experimental: self.experimental,
};
Expand Down Expand Up @@ -254,7 +244,6 @@ impl<'a> TypeCheckContext<'a> {
kind: self.kind,
engines: self.engines,
disallow_functions: self.disallow_functions,
defer_monomorphization: self.defer_monomorphization,
storage_declaration: self.storage_declaration,
experimental: self.experimental,
};
Expand Down Expand Up @@ -391,15 +380,6 @@ impl<'a> TypeCheckContext<'a> {
}
}

/// Map this `TypeCheckContext` instance to a new one with
/// `defer_method_application` set to `true`.
pub(crate) fn with_defer_monomorphization(self) -> Self {
Self {
defer_monomorphization: true,
..self
}
}

/// Map this `TypeCheckContext` instance to a new one with
/// `storage_declaration` set to `true`.
pub(crate) fn with_storage_declaration(self) -> Self {
Expand Down Expand Up @@ -453,10 +433,6 @@ impl<'a> TypeCheckContext<'a> {
self.disallow_functions
}

pub(crate) fn defer_monomorphization(&self) -> bool {
self.defer_monomorphization
}

pub(crate) fn storage_declaration(&self) -> bool {
self.storage_declaration
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
category = "disabled" # TODO: Enable once https://github.com/FuelLabs/sway/issues/6174 is fixed.
category = "run"
expected_result = { action = "revert", value = 42 }
expected_result_new_encoding = { action = "revert", value = 42 }
validate_abi = true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
category = "disabled" # TODO: Enable once https://github.com/FuelLabs/sway/issues/6174 is fixed.
category = "compile"

# not: $()This returns a value of type unknown, which is not assigned to anything and is ignored.

0 comments on commit fcb18c9

Please sign in to comment.