Skip to content

Commit d8ce3a7

Browse files
committed
memcpy optimization allowing pointers of different types
1 parent 09ab3f7 commit d8ce3a7

File tree

2 files changed

+57
-14
lines changed
  • sway-ir/src/optimize
  • test/src/e2e_vm_tests/test_programs/should_pass/language/main_args/main_args_empty/src

2 files changed

+57
-14
lines changed

sway-ir/src/optimize/memcpyopt.rs

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
77
use sway_types::{FxIndexMap, FxIndexSet};
88

99
use crate::{
10-
get_gep_symbol, get_loaded_symbols, get_referred_symbol, get_referred_symbols,
11-
get_stored_symbols, memory_utils, AnalysisResults, Block, Context, EscapedSymbols,
12-
FuelVmInstruction, Function, InstOp, Instruction, InstructionInserter, IrError, LocalVar, Pass,
13-
PassMutability, ReferredSymbols, ScopedPass, Symbol, Type, Value, ValueDatum,
14-
ESCAPED_SYMBOLS_NAME,
10+
AnalysisResults, Block, Context, DebugWithContext, ESCAPED_SYMBOLS_NAME, EscapedSymbols, FuelVmInstruction, Function, InstOp, Instruction, InstructionInserter, IrError, LocalVar, Pass, PassMutability, ReferredSymbols, ScopedPass, Symbol, Type, Value, ValueContent, ValueDatum, get_gep_symbol, get_loaded_symbols, get_referred_symbol, get_referred_symbols, get_stored_symbols, memory_utils
1511
};
1612

1713
pub const MEMCPYOPT_NAME: &str = "memcpyopt";
@@ -1121,9 +1117,11 @@ fn copy_prop_reverse(
11211117
_ => continue,
11221118
};
11231119

1124-
if dst_sym.get_type(context) != src_sym.get_type(context) {
1125-
continue;
1126-
}
1120+
// if types are different, insert a cast_ptr
1121+
// if dst_sym.get_type(context) != src_sym.get_type(context) {
1122+
// eprintln!("MEMCPY: {:?} <- {:?}", dst_sym.get_type(context).with_context(context), src_sym.get_type(context).with_context(context));
1123+
// continue;
1124+
// }
11271125

11281126
// We don't deal with partial memcpys
11291127
if dst_sym
@@ -1230,16 +1228,36 @@ fn copy_prop_reverse(
12301228
}
12311229
}
12321230

1233-
// Gather the get_local instructions that need to be replaced.
12341231
let mut repl_locals = vec![];
1232+
let mut value_replacements = FxHashMap::default();
1233+
1234+
// Gather the get_local instructions that need to be replaced.
12351235
for (_block, inst) in function.instruction_iter(context) {
1236-
match inst.get_instruction(context).unwrap() {
1236+
match inst.get_instruction(context).cloned().unwrap() {
12371237
Instruction {
12381238
op: InstOp::GetLocal(sym),
1239+
parent,
12391240
..
12401241
} => {
1241-
if let Some(dst) = src_to_dst.get(&Symbol::Local(*sym)) {
1242-
repl_locals.push((inst, *dst));
1242+
if let Some(dst) = src_to_dst.get(&Symbol::Local(sym)) {
1243+
let sym_type = sym.get_type(context);
1244+
let dst_type = dst.get_type(context);
1245+
1246+
if sym_type.eq(context, &dst_type) {
1247+
repl_locals.push((inst, *dst));
1248+
} else {
1249+
eprintln!("MEMCPY: {:?} <- {:?}", dst_type.with_context(context), sym_type.with_context(context));
1250+
1251+
let original_ptr = match dst {
1252+
Symbol::Local(..) => todo!(),
1253+
Symbol::Arg(block_argument) => {
1254+
block_argument.as_value(context)
1255+
},
1256+
};
1257+
1258+
let cast_ptr = InstOp::CastPtr(original_ptr, sym_type);
1259+
value_replacements.insert(inst, (parent, cast_ptr));
1260+
}
12431261
}
12441262
}
12451263
_ => {
@@ -1249,12 +1267,27 @@ fn copy_prop_reverse(
12491267
}
12501268
}
12511269

1252-
if repl_locals.is_empty() {
1270+
if repl_locals.is_empty() && value_replacements.is_empty() {
12531271
return Ok(modified);
12541272
}
1273+
12551274
modified = true;
12561275

1257-
let mut value_replacements = FxHashMap::default();
1276+
let mut value_replacements = value_replacements.into_iter()
1277+
.map(|(old, (block, instruction))| {
1278+
let v = Value::new_instruction(context, block, instruction);
1279+
1280+
let mut inserter = InstructionInserter::new(
1281+
context,
1282+
block,
1283+
crate::InsertionPosition::Before(old),
1284+
);
1285+
inserter.insert(v);
1286+
1287+
(old, v)
1288+
})
1289+
.collect::<FxHashMap<Value, Value>>();
1290+
12581291
for (to_repl, repl_with) in repl_locals {
12591292
let Instruction {
12601293
op: InstOp::GetLocal(sym),
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
script;
22

3+
#[inline(never)]
4+
fn f3() -> raw_slice {
5+
let ptr = asm(size: 0) {
6+
aloc size;
7+
hp: raw_ptr
8+
};
9+
__transmute::<(raw_ptr, u64), raw_slice>((ptr, 0))
10+
}
11+
312
fn main() {
13+
f3();
414
}

0 commit comments

Comments
 (0)