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

Introduce GlobalVar akin to LocalVar and introduce get_global instruction similar to get_local. #6928

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c318607
unique constants in the IR
vaivaswatha Feb 6, 2025
63fc159
Merge branch 'master' into vaivaswatha/ir_consts_1
vaivaswatha Feb 6, 2025
3e840cd
clippy fixes
vaivaswatha Feb 7, 2025
681f8b9
Merge branch 'master' into vaivaswatha/ir_consts_1
vaivaswatha Feb 7, 2025
0176256
Merge branch 'master' into vaivaswatha/ir_consts_1
vaivaswatha Feb 8, 2025
5056ff4
Merge branch 'master' into vaivaswatha/ir_consts_1
IGI-111 Feb 10, 2025
9ed1a99
Introduce global variables and a get_global IR instruction
vaivaswatha Feb 13, 2025
a58e55a
Merge branch 'master' into vaivaswatha/ir_consts_1
vaivaswatha Feb 13, 2025
7679f39
Merge branch 'vaivaswatha/ir_consts_1' of github.com:FuelLabs/sway in…
vaivaswatha Feb 13, 2025
269c3cc
Merge branch 'vaivaswatha/ir_consts_1' into vaivaswatha/ir_consts_2
vaivaswatha Feb 13, 2025
4129d3d
fix bugs
vaivaswatha Feb 14, 2025
503cecf
IR printer and parser for the new IR insruction
vaivaswatha Feb 18, 2025
167bb5e
Merge branch 'master' into vaivaswatha/ir_consts_1
vaivaswatha Feb 18, 2025
625149d
Merge branch 'vaivaswatha/ir_consts_1' into vaivaswatha/ir_consts_2
vaivaswatha Feb 18, 2025
8227ff6
use BTreeMap since we iterate over the entries
vaivaswatha Feb 19, 2025
a15fa81
test updates
vaivaswatha Feb 19, 2025
0e359eb
remove unused globals
vaivaswatha Feb 19, 2025
15b342c
fix a test
vaivaswatha Feb 19, 2025
5c7f1e4
add a unit test that checks addresses of global consts
vaivaswatha Feb 19, 2025
39e3019
pass to promote global consts to immediate constants when possible
vaivaswatha Feb 20, 2025
c1d0136
Merge branch 'master' into vaivaswatha/ir_consts_2
vaivaswatha Feb 20, 2025
3ec3f90
update tests
vaivaswatha Feb 20, 2025
6f142fa
Merge branch 'master' into vaivaswatha/ir_consts_2
vaivaswatha Feb 22, 2025
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
5 changes: 5 additions & 0 deletions sway-core/src/asm_generation/evm/evm_asm_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ impl<'ir, 'eng> EvmAsmBuilder<'ir, 'eng> {
indices,
} => self.compile_get_elem_ptr(instr_val, base, elem_ptr_ty, indices),
InstOp::GetLocal(local_var) => self.compile_get_local(instr_val, local_var),
InstOp::GetGlobal(global_var) => self.compile_get_global(instr_val, global_var),
InstOp::GetConfig(_, name) => self.compile_get_config(instr_val, name),
InstOp::IntToPtr(val, _) => self.compile_int_to_ptr(instr_val, val),
InstOp::Load(src_val) => self.compile_load(handler, instr_val, src_val)?,
Expand Down Expand Up @@ -471,6 +472,10 @@ impl<'ir, 'eng> EvmAsmBuilder<'ir, 'eng> {
todo!();
}

fn compile_get_global(&mut self, instr_val: &Value, global_var: &GlobalVar) {
todo!();
}

fn compile_get_local(&mut self, instr_val: &Value, local_var: &LocalVar) {
todo!();
}
Expand Down
35 changes: 35 additions & 0 deletions sway-core/src/asm_generation/fuel/fuel_asm_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
indices,
} => self.compile_get_elem_ptr(instr_val, base, elem_ptr_ty, indices),
InstOp::GetLocal(local_var) => self.compile_get_local(instr_val, local_var),
InstOp::GetGlobal(global_var) => self.compile_get_global(instr_val, global_var),
InstOp::GetConfig(_, name) => self.compile_get_config(instr_val, name),
InstOp::IntToPtr(val, _) => self.compile_no_op_move(instr_val, val),
InstOp::Load(src_val) => self.compile_load(instr_val, src_val),
Expand Down Expand Up @@ -1249,6 +1250,40 @@ impl<'ir, 'eng> FuelAsmBuilder<'ir, 'eng> {
Ok(())
}

fn compile_get_global(
&mut self,
instr_val: &Value,
local_var: &GlobalVar,
) -> Result<(), CompileError> {
let span = self
.md_mgr
.val_to_span(self.context, *instr_val)
.unwrap_or_else(Span::dummy);
let Some(constant) = local_var.get_initializer(self.context) else {
return Err(CompileError::Internal(
"Global variable must have an initializer.",
span,
));
};
let entry = Entry::from_constant(
self.context,
constant.get_content(self.context),
EntryName::NonConfigurable,
None,
);
let data_id = self.data_section.insert_data_value(entry);

// Allocate a register for it, and an address_of instruction.
let reg = self.reg_seqr.next();
self.cur_bytecode.push(Op {
opcode: either::Either::Left(VirtualOp::AddrDataId(reg.clone(), data_id.clone())),
comment: "constant address in data section".into(),
owning_span: Some(span),
});
self.reg_map.insert(*instr_val, reg);
Ok(())
}

fn compile_get_local(
&mut self,
instr_val: &Value,
Expand Down
22 changes: 17 additions & 5 deletions sway-core/src/ir_generation/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use sway_ir::{
context::Context,
module::Module,
value::Value,
Constant, InstOp, Instruction, Type, TypeContent,
Constant, GlobalVar, InstOp, Instruction, Type, TypeContent,
};
use sway_types::{ident::Ident, integer_bits::IntegerBits, span::Spanned, Named, Span};
use sway_utils::mapped_stack::MappedStack;
Expand Down Expand Up @@ -118,10 +118,15 @@ pub(crate) fn compile_const_decl(
// Check if it's a processed global constant.
match (
env.module
.get_global_constant(env.context, &call_path.as_vec_string()),
.get_global_variable(env.context, &call_path.as_vec_string()),
env.module_ns,
) {
(Some(const_val), _) => Ok(Some(const_val)),
(Some(global_var), _) => {
if let Some(constant) = global_var.get_initializer(env.context) {
return Ok(Some(Value::new_constant(env.context, *constant)));
}
Ok(None)
}
(None, Some(module_ns)) => {
// See if we it's a global const and whether we can compile it *now*.
let decl = module_ns.root_items().check_symbol(&call_path.suffix);
Expand Down Expand Up @@ -161,10 +166,17 @@ pub(crate) fn compile_const_decl(
&value,
)?;

env.module.add_global_constant(
let const_val_c = *const_val
.get_constant(env.context)
.expect("Must have been compiled to a constant");

let c_ty = const_val_c.get_content(env.context).ty;
let const_global = GlobalVar::new(env.context, c_ty, Some(const_val_c), false);

env.module.add_global_variable(
env.context,
call_path.as_vec_string().to_vec(),
const_val,
const_global,
);

Ok(Some(const_val))
Expand Down
11 changes: 8 additions & 3 deletions sway-core/src/ir_generation/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3322,11 +3322,16 @@ impl<'eng> FnCompiler<'eng> {
Ok(TerminatorValue::new(val, context))
} else if let Some(val) = self.function.get_arg(context, name.as_str()) {
Ok(TerminatorValue::new(val, context))
} else if let Some(const_val) = self
} else if let Some(global_val) = self
.module
.get_global_constant(context, &call_path.as_vec_string())
.get_global_variable(context, &call_path.as_vec_string())
{
Ok(TerminatorValue::new(const_val, context))
let val = self
.current_block
.append(context)
.get_global(global_val)
.add_metadatum(context, span_md_idx);
Ok(TerminatorValue::new(val, context))
} else if self
.module
.get_config(context, &call_path.suffix.to_string())
Expand Down
3 changes: 3 additions & 0 deletions sway-ir/src/analysis/memory_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ pub fn compute_escaped_symbols(context: &Context, function: &Function) -> Escape
}
InstOp::FuelVm(_) => (),
InstOp::GetLocal(_) => (),
InstOp::GetGlobal(_) => (),
InstOp::GetConfig(_, _) => (),
InstOp::GetElemPtr { .. } => (),
InstOp::IntToPtr(_, _) => (),
Expand Down Expand Up @@ -453,6 +454,7 @@ pub fn get_loaded_ptr_values(context: &Context, inst: Value) -> Vec<Value> {
| InstOp::Nop
| InstOp::CastPtr(_, _)
| InstOp::GetLocal(_)
| InstOp::GetGlobal(_)
| InstOp::GetConfig(_, _)
| InstOp::GetElemPtr { .. }
| InstOp::IntToPtr(_, _) => vec![],
Expand Down Expand Up @@ -540,6 +542,7 @@ pub fn get_stored_ptr_values(context: &Context, inst: Value) -> Vec<Value> {
| InstOp::Ret(_, _)
| InstOp::CastPtr(_, _)
| InstOp::GetLocal(_)
| InstOp::GetGlobal(_)
| InstOp::GetConfig(_, _)
| InstOp::GetElemPtr { .. }
| InstOp::IntToPtr(_, _) => vec![],
Expand Down
6 changes: 4 additions & 2 deletions sway-ir/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ use sway_types::SourceEngine;
use crate::{
block::BlockContent,
function::FunctionContent,
local_var::LocalVarContent,
metadata::Metadatum,
module::{Kind, ModuleContent, ModuleIterator},
value::ValueContent,
Constant, ConstantContent, Type, TypeContent,
variable::LocalVarContent,
Constant, ConstantContent, GlobalVarContent, Type, TypeContent,
};

/// The main IR context handle.
Expand All @@ -33,6 +33,7 @@ pub struct Context<'eng> {
pub(crate) blocks: SlotMap<DefaultKey, BlockContent>,
pub(crate) values: SlotMap<DefaultKey, ValueContent>,
pub(crate) local_vars: SlotMap<DefaultKey, LocalVarContent>,
pub(crate) global_vars: SlotMap<DefaultKey, GlobalVarContent>,
pub(crate) types: SlotMap<DefaultKey, TypeContent>,
pub(crate) type_map: FxHashMap<TypeContent, Type>,
pub(crate) constants: SlotMap<DefaultKey, ConstantContent>,
Expand All @@ -57,6 +58,7 @@ impl<'eng> Context<'eng> {
blocks: Default::default(),
values: Default::default(),
local_vars: Default::default(),
global_vars: Default::default(),
types: Default::default(),
type_map: Default::default(),
constants: Default::default(),
Expand Down
2 changes: 1 addition & 1 deletion sway-ir/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ use crate::{
context::Context,
error::IrError,
irtype::Type,
local_var::{LocalVar, LocalVarContent},
metadata::MetadataIndex,
module::Module,
value::{Value, ValueDatum},
variable::{LocalVar, LocalVarContent},
BlockArgument, BranchToWithArgs,
};
use crate::{Constant, InstOp};
Expand Down
17 changes: 15 additions & 2 deletions sway-ir/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ use crate::{
context::Context,
function::Function,
irtype::Type,
local_var::LocalVar,
pretty::DebugWithContext,
value::{Value, ValueDatum},
AsmInstruction, ConstantContent, Module,
variable::LocalVar,
AsmInstruction, ConstantContent, GlobalVar, Module,
};

#[derive(Debug, Clone, DebugWithContext)]
Expand Down Expand Up @@ -85,6 +85,8 @@ pub enum InstOp {
FuelVm(FuelVmInstruction),
/// Return a local variable.
GetLocal(LocalVar),
/// Return a global variable.
GetGlobal(GlobalVar),
/// Return a ptr to a config
GetConfig(Module, String),
/// Translate a pointer from a base to a nested element in an aggregate type.
Expand Down Expand Up @@ -299,6 +301,7 @@ impl InstOp {
// These return pointer types.
InstOp::GetElemPtr { elem_ptr_ty, .. } => Some(*elem_ptr_ty),
InstOp::GetLocal(local_var) => Some(local_var.get_type(context)),
InstOp::GetGlobal(global_var) => Some(global_var.get_type(context)),
InstOp::GetConfig(module, name) => Some(match module.get_config(context, name)? {
crate::ConfigContent::V0 { ptr_ty, .. } => *ptr_ty,
crate::ConfigContent::V1 { ptr_ty, .. } => *ptr_ty,
Expand Down Expand Up @@ -390,6 +393,10 @@ impl InstOp {
// `GetLocal` returns an SSA `Value` but does not take any as an operand.
vec![]
}
InstOp::GetGlobal(_global_var) => {
// `GetGlobal` returns an SSA `Value` but does not take any as an operand.
vec![]
}
InstOp::GetConfig(_, _) => {
// `GetConfig` returns an SSA `Value` but does not take any as an operand.
vec![]
Expand Down Expand Up @@ -523,6 +530,7 @@ impl InstOp {
replace(gas);
}
InstOp::GetLocal(_) => (),
InstOp::GetGlobal(_) => (),
InstOp::GetConfig(_, _) => (),
InstOp::GetElemPtr {
base,
Expand Down Expand Up @@ -684,6 +692,7 @@ impl InstOp {
| InstOp::FuelVm(FuelVmInstruction::StateLoadWord(_))
| InstOp::GetElemPtr { .. }
| InstOp::GetLocal(_)
| InstOp::GetGlobal(_)
| InstOp::GetConfig(_, _)
| InstOp::IntToPtr(..)
| InstOp::Load(_)
Expand Down Expand Up @@ -1042,6 +1051,10 @@ impl<'a, 'eng> InstructionInserter<'a, 'eng> {
insert_instruction!(self, InstOp::GetLocal(local_var))
}

pub fn get_global(self, global_var: GlobalVar) -> Value {
insert_instruction!(self, InstOp::GetGlobal(global_var))
}

pub fn get_config(self, module: Module, name: String) -> Value {
insert_instruction!(self, InstOp::GetConfig(module, name))
}
Expand Down
4 changes: 2 additions & 2 deletions sway-ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ pub mod optimize;
pub use optimize::*;
pub mod parser;
pub use parser::*;
pub mod local_var;
pub use local_var::*;
pub mod variable;
pub use variable::*;
pub mod pass_manager;
pub use pass_manager::*;
pub mod pretty;
Expand Down
43 changes: 28 additions & 15 deletions sway-ir/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@
//!
//! A module also has a 'kind' corresponding to the different Sway module types.

use std::{
cell::Cell,
collections::{BTreeMap, HashMap},
};
use std::{cell::Cell, collections::BTreeMap};

use crate::{
context::Context,
function::{Function, FunctionIterator},
value::Value,
Constant, MetadataIndex, Type,
Constant, GlobalVar, MetadataIndex, Type,
};

/// A wrapper around an [ECS](https://github.com/orlp/slotmap) handle into the
Expand All @@ -23,7 +19,7 @@ pub struct Module(pub slotmap::DefaultKey);
pub struct ModuleContent {
pub kind: Kind,
pub functions: Vec<Function>,
pub global_constants: HashMap<Vec<String>, Value>,
pub global_variables: BTreeMap<Vec<String>, GlobalVar>,
pub configs: BTreeMap<String, ConfigContent>,
}

Expand Down Expand Up @@ -61,7 +57,7 @@ impl Module {
let content = ModuleContent {
kind,
functions: Vec::new(),
global_constants: HashMap::new(),
global_variables: BTreeMap::new(),
configs: BTreeMap::new(),
};
Module(context.modules.insert(content))
Expand All @@ -77,26 +73,43 @@ impl Module {
FunctionIterator::new(context, self)
}

/// Add a global constant value to this module.
pub fn add_global_constant(
/// Add a global variable value to this module.
pub fn add_global_variable(
&self,
context: &mut Context,
call_path: Vec<String>,
const_val: Value,
const_val: GlobalVar,
) {
context.modules[self.0]
.global_constants
.global_variables
.insert(call_path, const_val);
}

/// Get a named global constant value from this module, if found.
pub fn get_global_constant(&self, context: &Context, call_path: &Vec<String>) -> Option<Value> {
/// Get a named global variable from this module, if found.
pub fn get_global_variable(
&self,
context: &Context,
call_path: &Vec<String>,
) -> Option<GlobalVar> {
context.modules[self.0]
.global_constants
.global_variables
.get(call_path)
.copied()
}

/// Lookup global variable name
pub fn lookup_global_variable_name(
&self,
context: &Context,
global: &GlobalVar,
) -> Option<String> {
context.modules[self.0]
.global_variables
.iter()
.find(|(_key, val)| *val == global)
.map(|(key, _)| key.join("::"))
}

/// Add a config value to this module.
pub fn add_config(&self, context: &mut Context, name: String, content: ConfigContent) {
context.modules[self.0].configs.insert(name, content);
Expand Down
1 change: 1 addition & 0 deletions sway-ir/src/optimize/cse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ fn instr_to_expr(context: &Context, vntable: &VNTable, instr: Value) -> Option<E
InstOp::ContractCall { .. } => None,
InstOp::FuelVm(_) => None,
InstOp::GetLocal(_) => None,
InstOp::GetGlobal(_) => None,
InstOp::GetConfig(_, _) => None,
InstOp::GetElemPtr {
base,
Expand Down
Loading
Loading