Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
8 changes: 4 additions & 4 deletions forc-plugins/forc-client/tests/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ async fn test_simple_deploy() {
node.kill().unwrap();
let expected = vec![DeployedPackage::Contract(DeployedContract {
id: ContractId::from_str(
"b3186dd386c846c80366df07130a4c6d6b9aae183298bf18166897a65007b3ac",
"2fa29eaad02a2b3e090307cede8dd70f73d81315e05b10ba2ded19c8fcdad0f6",
)
.unwrap(),
proxy: None,
Expand Down Expand Up @@ -421,7 +421,7 @@ async fn test_deploy_submit_only() {
node.kill().unwrap();
let expected = vec![DeployedPackage::Contract(DeployedContract {
id: ContractId::from_str(
"b3186dd386c846c80366df07130a4c6d6b9aae183298bf18166897a65007b3ac",
"2fa29eaad02a2b3e090307cede8dd70f73d81315e05b10ba2ded19c8fcdad0f6",
)
.unwrap(),
proxy: None,
Expand Down Expand Up @@ -468,12 +468,12 @@ async fn test_deploy_fresh_proxy() {
node.kill().unwrap();
let impl_contract = DeployedPackage::Contract(DeployedContract {
id: ContractId::from_str(
"b3186dd386c846c80366df07130a4c6d6b9aae183298bf18166897a65007b3ac",
"2fa29eaad02a2b3e090307cede8dd70f73d81315e05b10ba2ded19c8fcdad0f6",
)
.unwrap(),
proxy: Some(
ContractId::from_str(
"344f0e98c784ca03463f992c65cd3f321855c9ad22aa1309ec0d4f6d56dbb004",
"9aaebaece00250296a1459e6ab1413083b69061d7942360880457c5002d9040d",
)
.unwrap(),
),
Expand Down
8 changes: 4 additions & 4 deletions forc/tests/cli_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ fn test_forc_test_raw_logs() -> Result<(), rexpect::error::Error> {
// Assert that the output is correct
process.exp_string(" test test_log_4")?;
process.exp_string("raw logs:")?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12448,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12416,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
process.exp_string(" test test_log_2")?;
process.exp_string("raw logs:")?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12448,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12416,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;

process.process.exit()?;
Ok(())
Expand All @@ -77,12 +77,12 @@ fn test_forc_test_both_logs() -> Result<(), rexpect::error::Error> {
process.exp_string("decoded log values:")?;
process.exp_string("4, log rb: 1515152261580153489")?;
process.exp_string("raw logs:")?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12448,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12416,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
process.exp_string(" test test_log_2")?;
process.exp_string("decoded log values:")?;
process.exp_string("2, log rb: 1515152261580153489")?;
process.exp_string("raw logs:")?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12448,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12416,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
process.process.exit()?;
Ok(())
}
41 changes: 29 additions & 12 deletions sway-ir/src/optimize/ret_demotion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
/// This pass demotes 'by-value' function return types to 'by-reference` pointer types, based on
/// target specific parameters.
///
/// An extra argument pointer is added to the function and this pointer is also returned. The
/// return value is mem_copied to the new argument instead of being returned by value.
/// An extra argument pointer is added to the function.
/// The return value is mem_copied to the new argument instead of being returned by value.
use crate::{
AnalysisResults, BlockArgument, Context, Function, InstOp, Instruction, InstructionInserter,
IrError, Module, Pass, PassMutability, ScopedPass, Type, Value,
AnalysisResults, BlockArgument, ConstantContent, Context, Function, InstOp, Instruction,
InstructionInserter, IrError, Module, Pass, PassMutability, ScopedPass, Type, Value,
};

pub const RET_DEMOTION_NAME: &str = "ret-demotion";
Expand All @@ -23,7 +23,7 @@ pub fn create_ret_demotion_pass() -> Pass {

pub fn ret_val_demotion(
context: &mut Context,
_: &AnalysisResults,
_analyses: &AnalysisResults,
module: Module,
) -> Result<bool, IrError> {
// This is a module pass because we need to update all the callers of a function if we change
Expand All @@ -39,14 +39,18 @@ pub fn ret_val_demotion(

changed = true;

// Change the function signature. It now returns a pointer.
// Change the function signature.
let ptr_ret_type = Type::new_typed_pointer(context, ret_type);
function.set_return_type(context, ptr_ret_type);
let unit_ty = Type::get_unit(context);

// The storage for the return value must be determined. For entry-point functions it's a new
// local and otherwise it's an extra argument.
let entry_block = function.get_entry_block(context);
let ptr_arg_val = if function.is_entry(context) {
// Entry functions return a pointer to the original return type.
function.set_return_type(context, ptr_ret_type);

// Create a local variable to hold the return value.
let ret_var = function.new_unique_local_var(
context,
"__ret_value".to_owned(),
Expand All @@ -61,6 +65,9 @@ pub fn ret_val_demotion(
entry_block.prepend_instructions(context, vec![get_ret_var]);
get_ret_var
} else {
// non-entry functions now return unit.
function.set_return_type(context, unit_ty);

let ptr_arg_val = Value::new_argument(
context,
BlockArgument {
Expand Down Expand Up @@ -102,10 +109,20 @@ pub fn ret_val_demotion(
.append(context)
.store(ptr_arg_val, ret_val)
.add_metadatum(context, md_idx);
ret_block
.append(context)
.ret(ptr_arg_val, ptr_ret_type)
.add_metadatum(context, md_idx);

if !function.is_entry(context) {
let unit_ret = ConstantContent::get_unit(context);
ret_block
.append(context)
.ret(unit_ret, unit_ty)
.add_metadatum(context, md_idx);
} else {
// Entry functions still return the pointer to the return value.
ret_block
.append(context)
.ret(ptr_arg_val, ptr_ret_type)
.add_metadatum(context, md_idx);
}
}

// If the function isn't an entry point we need to update all the callers to pass the extra
Expand Down Expand Up @@ -180,7 +197,7 @@ fn update_callers(context: &mut Context, function: Function, ret_type: Type) {
Value::new_instruction(context, calling_block, InstOp::Call(function, new_args));

// And finally load the value from the new local var.
let load_val = Value::new_instruction(context, calling_block, InstOp::Load(new_call_val));
let load_val = Value::new_instruction(context, calling_block, InstOp::Load(get_loc_val));

calling_block
.replace_instruction(context, call_val, get_loc_val, false)
Expand Down
8 changes: 4 additions & 4 deletions sway-ir/tests/demote_ret/demote_ret00.ir
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ script {
v0 = call a()

// check: $(local_val=$ID) = get_local __ptr b256, $ret_var
// check: $(returned_ptr=$ID) = call a($local_val)
// check: $ID = load $returned_ptr
// check: $ID = call a($local_val)
// check: $ID = load $local_val

v1 = const unit ()
ret () v1
}

fn a() -> b256 {
// check: fn a($(ret_arg_val=$ID): __ptr b256) -> __ptr b256 {
// check: fn a($(ret_arg_val=$ID): __ptr b256) -> () {
local b256 __const = const b256 0x2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b

entry():
Expand All @@ -27,6 +27,6 @@ script {
// check: $(twobee=$ID) = get_local __ptr b256, __const
// check: $(load_val=$ID) = load $twobee
// check: store $load_val to $ret_arg_val
// check: ret __ptr b256 $ret_arg_val
// check: ret ()
}
}
23 changes: 12 additions & 11 deletions sway-ir/tests/demote_ret/demote_ret01.ir
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ script {
v1 = const bool true
v2 = call c(v0, v1)
v3 = get_local __ptr b256, tmp
// check: $(ptr_arg_val=$ID) = get_local __ptr b256, $ID
store v2 to v3

// check: $(call_val=$ID) = call c($ID, $ID, $ID)
// check: $(load_val=$ID) = load $call_val
// check: $ID = call c($ID, $ID, $ptr_arg_val)
// check: $(load_val=$ID) = load $ptr_arg_val
// check: $(tmp_val=$ID) = get_local __ptr b256, tmp
// check: store $load_val to $tmp_val

Expand All @@ -21,9 +22,9 @@ script {
}

fn c(p: bool, q: bool) -> b256 {
// check: local b256 $(ret_val=$ID)
// check: local b256 $(ret_val0=$ID)
// check: local b256 $(ret_val1=$ID)
// check: local b256 $(ret_val2=$ID)

entry(p: bool, q: bool):
cbr p, block0(), block1()
Expand All @@ -32,9 +33,9 @@ script {
v0 = call a()
br block5(v0)

// check: $(ptr_arg_val=$ID) = get_local __ptr b256, $ret_val0
// check: $(ptr_arg_val=$ID) = get_local __ptr b256, $ret_val
// check: $(ret_val=$ID) = call a($ptr_arg_val)
// check: $(load_val=$ID) = load $ret_val
// check: $(load_val=$ID) = load $ptr_arg_val
// check: br block5($load_val)

block1():
Expand All @@ -43,17 +44,17 @@ script {
block2():
v1 = call a()
br block5(v1)
// check: $(ptr_arg_val=$ID) = get_local __ptr b256, $ret_val1
// check: $(ret_val=$ID) = call a($ptr_arg_val)
// check: $(load_val=$ID) = load $ret_val
// check: $(ptr_arg_val=$ID) = get_local __ptr b256, $ret_val0
// check: $ID = call a($ptr_arg_val)
// check: $(load_val=$ID) = load $ptr_arg_val
// check: br block5($load_val)

block3():
v2 = call b()
br block5(v2)
// check: $(ptr_arg_val=$ID) = get_local __ptr b256, $ret_val2
// check: $(ret_val=$ID) = call b($ptr_arg_val)
// check: $(load_val=$ID) = load $ret_val
// check: $(ptr_arg_val=$ID) = get_local __ptr b256, $ret_val1
// check: $ID = call b($ptr_arg_val)
// check: $(load_val=$ID) = load $ptr_arg_val
// check: br block5($load_val)

block5(v3: b256):
Expand Down
Loading
Loading