Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function deduplication #5167

Merged
merged 8 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions sway-core/src/asm_generation/fuel/fuel_asm_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {

// For each opcode in the asm expression, attempt to parse it into an opcode and
// replace references to the above registers with the newly allocated ones.
let asm_block = asm.get_content(self.context);
let asm_block = asm;
for op in &asm_block.body {
let replaced_registers = op
.args
Expand Down Expand Up @@ -432,7 +432,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
.unwrap_or_else(Span::dummy);
let opcode = Op::parse_opcode(
handler,
&op.name,
&op.op_name,
&replaced_registers,
&op.immediate,
op_span.clone(),
Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/ir_generation/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2621,7 +2621,7 @@ impl<'eng> FnCompiler<'eng> {
immediate,
span,
}| AsmInstruction {
name: op_name.clone(),
op_name: op_name.clone(),
args: op_args.clone(),
immediate: immediate.clone(),
metadata: md_mgr.span_to_md(context, span),
Expand Down
18 changes: 8 additions & 10 deletions sway-core/src/ir_generation/purity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,14 @@ pub(crate) fn check_function_purity(
}

// Iterate for and check each instruction in the ASM block.
Instruction::AsmBlock(asm_block, _args) => {
asm_block.get_content(context).body.iter().fold(
(reads, writes),
|(reads, writes), asm_op| match asm_op.name.as_str() {
"scwq" | "srw" | "srwq" => (true, writes),
"sww" | "swwq" => (reads, true),
_ => (reads, writes),
},
)
}
Instruction::AsmBlock(asm_block, _args) => asm_block.body.iter().fold(
(reads, writes),
|(reads, writes), asm_op| match asm_op.op_name.as_str() {
"scwq" | "srw" | "srwq" => (true, writes),
"sww" | "swwq" => (reads, true),
_ => (reads, writes),
},
),

// Recurse to find the called function purity. Use memoisation to
// avoid redoing work.
Expand Down
31 changes: 4 additions & 27 deletions sway-ir/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,9 @@ use crate::{
context::Context, irtype::Type, metadata::MetadataIndex, pretty::DebugWithContext, value::Value,
};

/// A wrapper around an [ECS](https://github.com/fitzgen/generational-arena) handle into the
/// [`Context`].
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, DebugWithContext)]
pub struct AsmBlock(#[in_context(asm_blocks)] pub generational_arena::Index);

#[doc(hidden)]
#[derive(Clone, Debug, DebugWithContext)]
pub struct AsmBlockContent {
pub struct AsmBlock {
pub args_names: Vec<Ident>,
pub body: Vec<AsmInstruction>,
pub return_type: Type,
Expand All @@ -42,7 +37,7 @@ pub struct AsmArg {

#[derive(Clone, Debug)]
pub struct AsmInstruction {
pub name: Ident,
pub op_name: Ident,
pub args: Vec<Ident>,
pub immediate: Option<Ident>,
pub metadata: Option<MetadataIndex>,
Expand All @@ -51,34 +46,16 @@ pub struct AsmInstruction {
impl AsmBlock {
/// Create a new [`AsmBlock`] in the passed context and return its handle.
pub fn new(
context: &mut Context,
args_names: Vec<Ident>,
body: Vec<AsmInstruction>,
return_type: Type,
return_name: Option<Ident>,
) -> Self {
let content = AsmBlockContent {
AsmBlock {
args_names,
body,
return_type,
return_name,
};
AsmBlock(context.asm_blocks.insert(content))
}

/// Return the [`AsmBlock`] return type.
pub fn get_type(&self, context: &Context) -> Type {
// The type is a named register, which will be a u64.
context.asm_blocks[self.0].return_type
}

/// Change the [`AsmBlock`] return type.
pub fn set_type(&self, context: &mut Context, new_ret_type: Type) {
context.asm_blocks[self.0].return_type = new_ret_type
}

/// Get a reference to the [`AsmBlockContent`] for this ASM block.
pub fn get_content<'a>(&self, context: &'a Context) -> &'a AsmBlockContent {
&context.asm_blocks[self.0]
}
}
}
4 changes: 2 additions & 2 deletions sway-ir/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{context::Context, irtype::Type, pretty::DebugWithContext, value::Val
use sway_types::u256::U256;

/// A [`Type`] and constant value, including [`ConstantValue::Undef`] for uninitialized constants.
#[derive(Debug, Clone, DebugWithContext)]
#[derive(Debug, Clone, DebugWithContext, Hash)]
pub struct Constant {
pub ty: Type,
pub value: ConstantValue,
Expand All @@ -13,7 +13,7 @@ pub struct Constant {
pub type B256 = U256;

/// A constant representation of each of the supported [`Type`]s.
#[derive(Debug, Clone, DebugWithContext)]
#[derive(Debug, Clone, DebugWithContext, Hash)]
pub enum ConstantValue {
Undef,
Unit,
Expand Down
8 changes: 3 additions & 5 deletions sway-ir/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ use rustc_hash::FxHashMap;
use sway_types::SourceEngine;

use crate::{
asm::AsmBlockContent, block::BlockContent, function::FunctionContent,
local_var::LocalVarContent, metadata::Metadatum, module::Kind, module::ModuleContent,
module::ModuleIterator, value::ValueContent, Type, TypeContent,
block::BlockContent, function::FunctionContent, local_var::LocalVarContent,
metadata::Metadatum, module::Kind, module::ModuleContent, module::ModuleIterator,
value::ValueContent, Type, TypeContent,
};

/// The main IR context handle.
Expand All @@ -30,7 +30,6 @@ pub struct Context<'eng> {
pub(crate) local_vars: Arena<LocalVarContent>,
pub(crate) types: Arena<TypeContent>,
pub(crate) type_map: FxHashMap<TypeContent, Type>,
pub(crate) asm_blocks: Arena<AsmBlockContent>,
pub(crate) metadata: Arena<Metadatum>,

pub program_kind: Kind,
Expand All @@ -49,7 +48,6 @@ impl<'eng> Context<'eng> {
local_vars: Default::default(),
types: Default::default(),
type_map: Default::default(),
asm_blocks: Default::default(),
metadata: Default::default(),
next_unique_sym_tag: Default::default(),
program_kind: Kind::Contract,
Expand Down
11 changes: 5 additions & 6 deletions sway-ir/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,19 +181,19 @@ pub enum FuelVmInstruction {
}

/// Comparison operations.
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, Hash)]
pub enum Predicate {
Equal,
LessThan,
GreaterThan,
}

#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, Hash)]
pub enum UnaryOpKind {
Not,
}

#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, Hash)]
pub enum BinaryOpKind {
Add,
Sub,
Expand All @@ -208,7 +208,7 @@ pub enum BinaryOpKind {
}

/// Special registers in the Fuel Virtual Machine.
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, Hash)]
pub enum Register {
/// Contains overflow/underflow of addition, subtraction, and multiplication.
Of,
Expand Down Expand Up @@ -248,7 +248,7 @@ impl Instruction {
pub fn get_type(&self, context: &Context) -> Option<Type> {
match self {
// These all return something in particular.
Instruction::AsmBlock(asm_block, _) => Some(asm_block.get_type(context)),
Instruction::AsmBlock(asm_block, _) => Some(asm_block.return_type),
Instruction::UnaryOp { arg, .. } => arg.get_type(context),
Instruction::BinaryOp { arg1, .. } => arg1.get_type(context),
Instruction::BitCast(_, ty) => Some(*ty),
Expand Down Expand Up @@ -746,7 +746,6 @@ impl<'a, 'eng> InstructionInserter<'a, 'eng> {
return_name: Option<Ident>,
) -> Value {
let asm = AsmBlock::new(
self.context,
args.iter().map(|arg| arg.name.clone()).collect(),
body,
return_type,
Expand Down
2 changes: 2 additions & 0 deletions sway-ir/src/optimize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ pub mod simplify_cfg;
pub use simplify_cfg::*;
pub mod sroa;
pub use sroa::*;
pub mod fn_dedup;
pub use fn_dedup::*;

mod target_fuel;

Expand Down
Loading