Skip to content
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
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