Skip to content

Commit

Permalink
Remove unused locals (FuelLabs#4458)
Browse files Browse the repository at this point in the history
vaivaswatha authored Apr 18, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 7011edd commit 2e494f3
Showing 12 changed files with 57 additions and 12 deletions.
9 changes: 9 additions & 0 deletions sway-ir/src/function.rs
Original file line number Diff line number Diff line change
@@ -398,6 +398,15 @@ impl Function {
context.functions[self.0].local_storage.iter()
}

/// Remove given list of locals
pub fn remove_locals(&self, context: &mut Context, removals: &Vec<String>) {
for remove in removals {
if let Some(local) = context.functions[self.0].local_storage.remove(remove) {
context.local_vars.remove(local.0);
}
}
}

/// Merge values from another [`Function`] into this one.
///
/// The names of the merged values are guaranteed to be unique via the use of
31 changes: 28 additions & 3 deletions sway-ir/src/optimize/dce.rs
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@
//! This pass does not do CFG transformations. That is handled by simplify_cfg.
use crate::{
AnalysisResults, Block, Context, Function, Instruction, IrError, Module, Pass, PassMutability,
ScopedPass, Value, ValueDatum,
AnalysisResults, Block, Context, Function, Instruction, IrError, LocalVar, Module, Pass,
PassMutability, ScopedPass, Value, ValueDatum,
};

use std::collections::{HashMap, HashSet};
@@ -47,10 +47,18 @@ pub fn dce(
) -> Result<bool, IrError> {
// Number of uses that an instruction has.
let mut num_uses: HashMap<Value, (Block, u32)> = HashMap::new();
let mut num_local_uses: HashMap<LocalVar, u32> = HashMap::new();

// Go through each instruction and update use_count.
for (block, inst) in function.instruction_iter(context) {
let opds = inst.get_instruction(context).unwrap().get_operands();
let inst = inst.get_instruction(context).unwrap();
if let Instruction::GetLocal(local) = inst {
num_local_uses
.entry(*local)
.and_modify(|count| *count += 1)
.or_insert(1);
}
let opds = inst.get_operands();
for v in opds {
match context.values[v.0].value {
ValueDatum::Instruction(_) => {
@@ -94,7 +102,24 @@ pub fn dce(
}

in_block.remove_instruction(context, dead);

if let ValueDatum::Instruction(Instruction::GetLocal(local)) = context.values[dead.0].value
{
let count = num_local_uses.get_mut(&local).unwrap();
*count -= 1;
}
modified = true;
}

let local_removals: Vec<_> = function
.locals_iter(context)
.filter_map(|(name, local)| {
(num_local_uses.get(local).cloned().unwrap_or(0) == 0).then_some(name.clone())
})
.collect();
if !local_removals.is_empty() {
modified = true;
function.remove_locals(context, &local_removals);
}

Ok(modified)
12 changes: 12 additions & 0 deletions sway-ir/tests/dce/dce2.ir
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// regex: ID=[[:alpha:]0-9]+

script {
fn main() -> bool {
// not: local u64 i
local u64 i

entry():
v9 = const bool false
ret bool v9
}
}
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ use array_of_structs_abi::{Id, TestContract, Wrapper};
use std::hash::sha256;

fn main() -> u64 {
let addr = abi(TestContract, 0xa5d354e58efd316c2eb3f4b273a2143e7d534952fae5e191e057b27403ae829e);
let addr = abi(TestContract, 0xfd87acbc9cfdbae40894dc1be15c8f5f07a5775ca110df2584f053ac6ad10672);

let input = [Wrapper {
id: Id {
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ script;
use basic_storage_abi::{BasicStorage, Quad};

fn main() -> u64 {
let addr = abi(BasicStorage, 0xc98246b75472af9196be66b65a979ebbe5cd5975d1331f18ce2cda66a9819379);
let addr = abi(BasicStorage, 0x6906bdbccb7ca8e66c11ce16518c2f946da094d3e2c8561ca38d5a6d9a13e996);
let key = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
let value = 4242;

Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ script;
use contract_with_type_aliases_abi::*;

fn main() {
let caller = abi(MyContract, 0xaa380eacd28dbfba42ee88a1df59544f5cbc3e862a5b12bc2af894923ec4f5e8);
let caller = abi(MyContract, 0xf5030df8b9336a88f24afa90afe33aea6affd5295821aeb4eade84cd1fee4345);

let x = AssetId::from(0x0101010101010101010101010101010101010101010101010101010101010101);

Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ script;
use increment_abi::Incrementor;

fn main() -> bool {
let the_abi = abi(Incrementor, 0xc9baa3acb84a53e91b31b2ecc514d5ad8a715083282dc16d520b5d40a9fc94a7);
let the_abi = abi(Incrementor, 0x6b259c454583b3995b9e35effa476f8cb2155ff44d1d8d567a83108b4fe65444);
the_abi.increment(5);
the_abi.increment(5);
let result = the_abi.get();
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ fn main() -> bool {
let zero = b256::min();
let gas: u64 = u64::max();
let amount: u64 = 11;
let other_contract_id = ContractId::from(0xc29171776f4d174a9e338d12c3b84e1de1694ba8bd64fb725d9eaf2842c7c6f1);
let other_contract_id = ContractId::from(0x338000acdb5764cdaaf90a70b2fa73c68fed43ce2b7bdb329d361cb6b5393a43);
let base_asset_id = BASE_ASSET_ID;

let test_contract = abi(ContextTesting, other_contract_id.into());
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ script;
use get_storage_key_abi::TestContract;

fn main() -> u64 {
let caller = abi(TestContract, 0x79fd3f7662e227f8ff7bef65b683fa4417b7e9f6d6bdbc0eb4d899ea2d73cad3);
let caller = abi(TestContract, 0xfd77b8770d4b9ad2402e8d6c838c8a837d2a56dd02ec4445c4c212bfce66b143);

// Get the storage keys directly by calling the contract methods from_f1,
// from_f2, from_f3, from_f4. The keys correspond to different entries in
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ script;
use nested_struct_args_abi::*;

fn main() -> bool {
let contract_id = 0xc07c133be5867020f483c34e045c9162867d6b40accc022525e50c048d17d679;
let contract_id = 0x1ce4c30fc1fe5d4639683ad1330de7739efd297671a540ffe9012e9cf3953fe7;
let caller = abi(NestedStructArgs, contract_id);

let param_one = StructOne {
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ use storage_access_abi::*;
use std::hash::sha256;

fn main() -> bool {
let contract_id = 0x9ec7ac3cce15b1b75adabd598a374e96b606471a56229486a2d0ca26c08ed994;
let contract_id = 0x8982d742b1f313818d24516f7410519ca4fd4bbab470012809ffde710c45c0a4;
let caller = abi(StorageAccess, contract_id);

// Test initializers
1 change: 0 additions & 1 deletion test/src/ir_generation/tests/simple_contract_call.sw
Original file line number Diff line number Diff line change
@@ -48,7 +48,6 @@ fn main() -> u64 {
// check: local b256 $(asset_id_2_const=$ID) = const b256 0x0000000000000000000000000000000000000000000000000000000000000000

// check: local u64 a
// check: local b256 arg_for_get_b256
// check: local { u64, b256 } args_struct_for_get_s
// check: local b256 b
// check: local { u64, b256 } s

0 comments on commit 2e494f3

Please sign in to comment.