Skip to content

Commit bcfa756

Browse files
vaivaswathaElaela22soL
authored andcommitted
When demoting aggregate returns, no need to return back the new argument pointer (FuelLabs#7381)
This aids optimizations to perform better. For example https://github.com/IGI-111/blackjack comes down from `22.288 KB` to `21.312 KB`.
1 parent 0ede5bd commit bcfa756

File tree

28 files changed

+1116
-1098
lines changed

28 files changed

+1116
-1098
lines changed

forc-plugins/forc-client/tests/deploy.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ async fn test_simple_deploy() {
377377
node.kill().unwrap();
378378
let expected = vec![DeployedPackage::Contract(DeployedContract {
379379
id: ContractId::from_str(
380-
"b3186dd386c846c80366df07130a4c6d6b9aae183298bf18166897a65007b3ac",
380+
"2fa29eaad02a2b3e090307cede8dd70f73d81315e05b10ba2ded19c8fcdad0f6",
381381
)
382382
.unwrap(),
383383
proxy: None,
@@ -421,7 +421,7 @@ async fn test_deploy_submit_only() {
421421
node.kill().unwrap();
422422
let expected = vec![DeployedPackage::Contract(DeployedContract {
423423
id: ContractId::from_str(
424-
"b3186dd386c846c80366df07130a4c6d6b9aae183298bf18166897a65007b3ac",
424+
"2fa29eaad02a2b3e090307cede8dd70f73d81315e05b10ba2ded19c8fcdad0f6",
425425
)
426426
.unwrap(),
427427
proxy: None,
@@ -468,12 +468,12 @@ async fn test_deploy_fresh_proxy() {
468468
node.kill().unwrap();
469469
let impl_contract = DeployedPackage::Contract(DeployedContract {
470470
id: ContractId::from_str(
471-
"b3186dd386c846c80366df07130a4c6d6b9aae183298bf18166897a65007b3ac",
471+
"2fa29eaad02a2b3e090307cede8dd70f73d81315e05b10ba2ded19c8fcdad0f6",
472472
)
473473
.unwrap(),
474474
proxy: Some(
475475
ContractId::from_str(
476-
"344f0e98c784ca03463f992c65cd3f321855c9ad22aa1309ec0d4f6d56dbb004",
476+
"9aaebaece00250296a1459e6ab1413083b69061d7942360880457c5002d9040d",
477477
)
478478
.unwrap(),
479479
),

forc/tests/cli_integration.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ fn test_forc_test_raw_logs() -> Result<(), rexpect::error::Error> {
5151
// Assert that the output is correct
5252
process.exp_string(" test test_log_4")?;
5353
process.exp_string("raw logs:")?;
54-
process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12448,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
54+
process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12416,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
5555
process.exp_string(" test test_log_2")?;
5656
process.exp_string("raw logs:")?;
57-
process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12448,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
57+
process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12416,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
5858

5959
process.process.exit()?;
6060
Ok(())
@@ -77,12 +77,12 @@ fn test_forc_test_both_logs() -> Result<(), rexpect::error::Error> {
7777
process.exp_string("decoded log values:")?;
7878
process.exp_string("4, log rb: 1515152261580153489")?;
7979
process.exp_string("raw logs:")?;
80-
process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12448,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
80+
process.exp_string(r#"[{"LogData":{"data":"0000000000000004","digest":"8005f02d43fa06e7d0585fb64c961d57e318b27a145c857bcd3a6bdb413ff7fc","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12416,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
8181
process.exp_string(" test test_log_2")?;
8282
process.exp_string("decoded log values:")?;
8383
process.exp_string("2, log rb: 1515152261580153489")?;
8484
process.exp_string("raw logs:")?;
85-
process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12448,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
85+
process.exp_string(r#"[{"LogData":{"data":"0000000000000002","digest":"cd04a4754498e06db5a13c5f371f1f04ff6d2470f24aa9bd886540e5dce77f70","id":"0000000000000000000000000000000000000000000000000000000000000000","is":10368,"len":8,"pc":12416,"ptr":67107840,"ra":0,"rb":1515152261580153489}}]"#)?;
8686
process.process.exit()?;
8787
Ok(())
8888
}

sway-ir/src/optimize/ret_demotion.rs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
/// This pass demotes 'by-value' function return types to 'by-reference` pointer types, based on
44
/// target specific parameters.
55
///
6-
/// An extra argument pointer is added to the function and this pointer is also returned. The
7-
/// return value is mem_copied to the new argument instead of being returned by value.
6+
/// An extra argument pointer is added to the function.
7+
/// The return value is mem_copied to the new argument instead of being returned by value.
88
use crate::{
9-
AnalysisResults, BlockArgument, Context, Function, InstOp, Instruction, InstructionInserter,
10-
IrError, Module, Pass, PassMutability, ScopedPass, Type, Value,
9+
AnalysisResults, BlockArgument, ConstantContent, Context, Function, InstOp, Instruction,
10+
InstructionInserter, IrError, Module, Pass, PassMutability, ScopedPass, Type, Value,
1111
};
1212

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

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

4040
changed = true;
4141

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

4646
// The storage for the return value must be determined. For entry-point functions it's a new
4747
// local and otherwise it's an extra argument.
4848
let entry_block = function.get_entry_block(context);
4949
let ptr_arg_val = if function.is_entry(context) {
50+
// Entry functions return a pointer to the original return type.
51+
function.set_return_type(context, ptr_ret_type);
52+
53+
// Create a local variable to hold the return value.
5054
let ret_var = function.new_unique_local_var(
5155
context,
5256
"__ret_value".to_owned(),
@@ -61,6 +65,9 @@ pub fn ret_val_demotion(
6165
entry_block.prepend_instructions(context, vec![get_ret_var]);
6266
get_ret_var
6367
} else {
68+
// non-entry functions now return unit.
69+
function.set_return_type(context, unit_ty);
70+
6471
let ptr_arg_val = Value::new_argument(
6572
context,
6673
BlockArgument {
@@ -102,10 +109,20 @@ pub fn ret_val_demotion(
102109
.append(context)
103110
.store(ptr_arg_val, ret_val)
104111
.add_metadatum(context, md_idx);
105-
ret_block
106-
.append(context)
107-
.ret(ptr_arg_val, ptr_ret_type)
108-
.add_metadatum(context, md_idx);
112+
113+
if !function.is_entry(context) {
114+
let unit_ret = ConstantContent::get_unit(context);
115+
ret_block
116+
.append(context)
117+
.ret(unit_ret, unit_ty)
118+
.add_metadatum(context, md_idx);
119+
} else {
120+
// Entry functions still return the pointer to the return value.
121+
ret_block
122+
.append(context)
123+
.ret(ptr_arg_val, ptr_ret_type)
124+
.add_metadatum(context, md_idx);
125+
}
109126
}
110127

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

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

185202
calling_block
186203
.replace_instruction(context, call_val, get_loc_val, false)

sway-ir/tests/demote_ret/demote_ret00.ir

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ script {
88
v0 = call a()
99

1010
// check: $(local_val=$ID) = get_local __ptr b256, $ret_var
11-
// check: $(returned_ptr=$ID) = call a($local_val)
12-
// check: $ID = load $returned_ptr
11+
// check: $ID = call a($local_val)
12+
// check: $ID = load $local_val
1313

1414
v1 = const unit ()
1515
ret () v1
1616
}
1717

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

2222
entry():
@@ -27,6 +27,6 @@ script {
2727
// check: $(twobee=$ID) = get_local __ptr b256, __const
2828
// check: $(load_val=$ID) = load $twobee
2929
// check: store $load_val to $ret_arg_val
30-
// check: ret __ptr b256 $ret_arg_val
30+
// check: ret ()
3131
}
3232
}

sway-ir/tests/demote_ret/demote_ret01.ir

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ script {
99
v1 = const bool true
1010
v2 = call c(v0, v1)
1111
v3 = get_local __ptr b256, tmp
12+
// check: $(ptr_arg_val=$ID) = get_local __ptr b256, $ID
1213
store v2 to v3
1314

14-
// check: $(call_val=$ID) = call c($ID, $ID, $ID)
15-
// check: $(load_val=$ID) = load $call_val
15+
// check: $ID = call c($ID, $ID, $ptr_arg_val)
16+
// check: $(load_val=$ID) = load $ptr_arg_val
1617
// check: $(tmp_val=$ID) = get_local __ptr b256, tmp
1718
// check: store $load_val to $tmp_val
1819

@@ -21,9 +22,9 @@ script {
2122
}
2223

2324
fn c(p: bool, q: bool) -> b256 {
25+
// check: local b256 $(ret_val=$ID)
2426
// check: local b256 $(ret_val0=$ID)
2527
// check: local b256 $(ret_val1=$ID)
26-
// check: local b256 $(ret_val2=$ID)
2728

2829
entry(p: bool, q: bool):
2930
cbr p, block0(), block1()
@@ -32,9 +33,9 @@ script {
3233
v0 = call a()
3334
br block5(v0)
3435

35-
// check: $(ptr_arg_val=$ID) = get_local __ptr b256, $ret_val0
36+
// check: $(ptr_arg_val=$ID) = get_local __ptr b256, $ret_val
3637
// check: $(ret_val=$ID) = call a($ptr_arg_val)
37-
// check: $(load_val=$ID) = load $ret_val
38+
// check: $(load_val=$ID) = load $ptr_arg_val
3839
// check: br block5($load_val)
3940

4041
block1():
@@ -43,17 +44,17 @@ script {
4344
block2():
4445
v1 = call a()
4546
br block5(v1)
46-
// check: $(ptr_arg_val=$ID) = get_local __ptr b256, $ret_val1
47-
// check: $(ret_val=$ID) = call a($ptr_arg_val)
48-
// check: $(load_val=$ID) = load $ret_val
47+
// check: $(ptr_arg_val=$ID) = get_local __ptr b256, $ret_val0
48+
// check: $ID = call a($ptr_arg_val)
49+
// check: $(load_val=$ID) = load $ptr_arg_val
4950
// check: br block5($load_val)
5051

5152
block3():
5253
v2 = call b()
5354
br block5(v2)
54-
// check: $(ptr_arg_val=$ID) = get_local __ptr b256, $ret_val2
55-
// check: $(ret_val=$ID) = call b($ptr_arg_val)
56-
// check: $(load_val=$ID) = load $ret_val
55+
// check: $(ptr_arg_val=$ID) = get_local __ptr b256, $ret_val1
56+
// check: $ID = call b($ptr_arg_val)
57+
// check: $(load_val=$ID) = load $ptr_arg_val
5758
// check: br block5($load_val)
5859

5960
block5(v3: b256):

0 commit comments

Comments
 (0)