Skip to content

Commit 746b7f0

Browse files
authored
[move-compiler] remove the ExpList form from the lower parts of the compiler (#13916)
## Description This changes some of how the HLIR and below represent things, eliminating the ExpList form. ## Test Plan All tests still work --- If your changes are not user-facing and not a breaking change, you can skip the following section. Otherwise, please indicate what changed, and then add to the Release Notes section as highlighted during the release process. ### Type of Change (Check all that apply) - [ ] protocol change - [ ] user-visible impact - [ ] breaking change for a client SDKs - [ ] breaking change for FNs (FN binary must upgrade) - [ ] breaking change for validators or node operators (must upgrade binaries) - [ ] breaking change for on-chain data layout - [ ] necessitate either a data wipe or data migration ### Release notes
1 parent befeab2 commit 746b7f0

File tree

10 files changed

+263
-313
lines changed

10 files changed

+263
-313
lines changed

move-compiler/src/cfgir/borrows/mod.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,8 @@ fn exp(context: &mut Context, parent_e: &Exp) -> Values {
209209
vec![value]
210210
}
211211

212-
E::Builtin(b, e) => {
213-
let evalues = exp(context, e);
212+
E::Builtin(b, args) => {
213+
let evalues: Values = args.iter().flat_map(|arg| exp(context, arg)).collect();
214214
let b: &BuiltinFunction = b;
215215
match b {
216216
sp!(_, BuiltinFunction_::BorrowGlobal(mut_, t)) => {
@@ -238,15 +238,19 @@ fn exp(context: &mut Context, parent_e: &Exp) -> Values {
238238
}
239239
}
240240

241-
E::Vector(_, n, _, e) => {
242-
let evalues = exp(context, e);
241+
E::Vector(_, n, _, args) => {
242+
let evalues: Values = args.iter().flat_map(|arg| exp(context, arg)).collect();
243243
debug_assert_eq!(*n, evalues.len());
244244
evalues.into_iter().for_each(|v| assert!(!v.is_ref()));
245245
svalue()
246246
}
247247

248248
E::ModuleCall(mcall) => {
249-
let evalues = exp(context, &mcall.arguments);
249+
let evalues: Values = mcall
250+
.arguments
251+
.iter()
252+
.flat_map(|arg| exp(context, arg))
253+
.collect();
250254
let ret_ty = &parent_e.ty;
251255
let (diags, values) =
252256
context
@@ -293,17 +297,8 @@ fn exp(context: &mut Context, parent_e: &Exp) -> Values {
293297
svalue()
294298
}
295299

296-
E::ExpList(es) => es
297-
.iter()
298-
.flat_map(|item| exp_list_item(context, item))
299-
.collect(),
300+
E::Multiple(es) => es.iter().flat_map(|e| exp(context, e)).collect(),
300301

301302
E::Unreachable => panic!("ICE should not analyze dead code"),
302303
}
303304
}
304-
305-
fn exp_list_item(context: &mut Context, item: &ExpListItem) -> Values {
306-
match item {
307-
ExpListItem::Single(e, _) | ExpListItem::Splat(_, e, _) => exp(context, e),
308-
}
309-
}

move-compiler/src/cfgir/cfg.rs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::{
99
},
1010
diag,
1111
diagnostics::Diagnostics,
12-
hlir::ast::{Command, Command_, Exp, ExpListItem, Label, UnannotatedExp_, UnitCase},
12+
hlir::ast::{Command, Command_, Exp, Label, UnannotatedExp_, UnitCase},
1313
shared::ast_debug::*,
1414
};
1515
use move_ir_types::location::*;
@@ -320,10 +320,9 @@ fn unreachable_loc_exp(parent_e: &Exp) -> Option<Loc> {
320320
| E::BorrowLocal(_, _)
321321
| E::Copy { .. }
322322
| E::Move { .. } => None,
323-
E::ModuleCall(mcall) => unreachable_loc_exp(&mcall.arguments),
324-
E::Builtin(_, e)
325-
| E::Vector(_, _, _, e)
326-
| E::Freeze(e)
323+
E::ModuleCall(mcall) => mcall.arguments.iter().find_map(unreachable_loc_exp),
324+
E::Builtin(_, args) | E::Vector(_, _, _, args) => args.iter().find_map(unreachable_loc_exp),
325+
E::Freeze(e)
327326
| E::Dereference(e)
328327
| E::UnaryExp(_, e)
329328
| E::Borrow(_, e, _)
@@ -333,13 +332,7 @@ fn unreachable_loc_exp(parent_e: &Exp) -> Option<Loc> {
333332

334333
E::Pack(_, _, fields) => fields.iter().find_map(|(_, _, e)| unreachable_loc_exp(e)),
335334

336-
E::ExpList(es) => es.iter().find_map(unreachable_loc_item),
337-
}
338-
}
339-
340-
fn unreachable_loc_item(item: &ExpListItem) -> Option<Loc> {
341-
match item {
342-
ExpListItem::Single(e, _) | ExpListItem::Splat(_, e, _) => unreachable_loc_exp(e),
335+
E::Multiple(es) => es.iter().find_map(unreachable_loc_exp),
343336
}
344337
}
345338

move-compiler/src/cfgir/liveness/mod.rs

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,9 @@ fn exp(state: &mut LivenessState, parent_e: &Exp) {
128128
state.0.insert(*v);
129129
}),
130130

131-
E::ModuleCall(mcall) => exp(state, &mcall.arguments),
132-
E::Builtin(_, e)
133-
| E::Vector(_, _, _, e)
134-
| E::Freeze(e)
131+
E::ModuleCall(mcall) => mcall.arguments.iter().for_each(|e| exp(state, e)),
132+
E::Builtin(_, args) | E::Vector(_, _, _, args) => args.iter().for_each(|e| exp(state, e)),
133+
E::Freeze(e)
135134
| E::Dereference(e)
136135
| E::UnaryExp(_, e)
137136
| E::Borrow(_, e, _)
@@ -144,18 +143,12 @@ fn exp(state: &mut LivenessState, parent_e: &Exp) {
144143

145144
E::Pack(_, _, fields) => fields.iter().for_each(|(_, _, e)| exp(state, e)),
146145

147-
E::ExpList(es) => es.iter().for_each(|item| exp_list_item(state, item)),
146+
E::Multiple(es) => es.iter().for_each(|e| exp(state, e)),
148147

149148
E::Unreachable => panic!("ICE should not analyze dead code"),
150149
}
151150
}
152151

153-
fn exp_list_item(state: &mut LivenessState, item: &ExpListItem) {
154-
match item {
155-
ExpListItem::Single(e, _) | ExpListItem::Splat(_, e, _) => exp(state, e),
156-
}
157-
}
158-
159152
//**************************************************************************************************
160153
// Copy Refinement
161154
//**************************************************************************************************
@@ -353,10 +346,15 @@ mod last_usage {
353346
}
354347
}
355348

356-
E::ModuleCall(mcall) => exp(context, &mut mcall.arguments),
357-
E::Builtin(_, e)
358-
| E::Vector(_, _, _, e)
359-
| E::Freeze(e)
349+
E::ModuleCall(mcall) => mcall
350+
.arguments
351+
.iter_mut()
352+
.rev()
353+
.for_each(|arg| exp(context, arg)),
354+
E::Builtin(_, args) | E::Vector(_, _, _, args) => {
355+
args.iter_mut().rev().for_each(|arg| exp(context, arg))
356+
}
357+
E::Freeze(e)
360358
| E::Dereference(e)
361359
| E::UnaryExp(_, e)
362360
| E::Borrow(_, e, _)
@@ -372,20 +370,11 @@ mod last_usage {
372370
.rev()
373371
.for_each(|(_, _, e)| exp(context, e)),
374372

375-
E::ExpList(es) => es
376-
.iter_mut()
377-
.rev()
378-
.for_each(|item| exp_list_item(context, item)),
373+
E::Multiple(es) => es.iter_mut().rev().for_each(|e| exp(context, e)),
379374

380375
E::Unreachable => panic!("ICE should not analyze dead code"),
381376
}
382377
}
383-
384-
fn exp_list_item(context: &mut Context, item: &mut ExpListItem) {
385-
match item {
386-
ExpListItem::Single(e, _) | ExpListItem::Splat(_, e, _) => exp(context, e),
387-
}
388-
}
389378
}
390379

391380
//**************************************************************************************************

move-compiler/src/cfgir/locals/mod.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,11 @@ fn exp(context: &mut Context, parent_e: &Exp) {
262262
)
263263
}
264264

265-
E::ModuleCall(mcall) => exp(context, &mcall.arguments),
266-
E::Builtin(_, e)
267-
| E::Vector(_, _, _, e)
268-
| E::Freeze(e)
265+
E::ModuleCall(mcall) => mcall.arguments.iter().map(|e| exp(context, e)).collect(),
266+
E::Builtin(_, args) | E::Vector(_, _, _, args) => {
267+
args.iter().map(|e| exp(context, e)).collect()
268+
}
269+
E::Freeze(e)
269270
| E::Dereference(e)
270271
| E::UnaryExp(_, e)
271272
| E::Borrow(_, e, _)
@@ -278,18 +279,12 @@ fn exp(context: &mut Context, parent_e: &Exp) {
278279

279280
E::Pack(_, _, fields) => fields.iter().for_each(|(_, _, e)| exp(context, e)),
280281

281-
E::ExpList(es) => es.iter().for_each(|item| exp_list_item(context, item)),
282+
E::Multiple(es) => es.iter().for_each(|e| exp(context, e)),
282283

283284
E::Unreachable => panic!("ICE should not analyze dead code"),
284285
}
285286
}
286287

287-
fn exp_list_item(context: &mut Context, item: &ExpListItem) {
288-
match item {
289-
ExpListItem::Single(e, _) | ExpListItem::Splat(_, e, _) => exp(context, e),
290-
}
291-
}
292-
293288
fn use_local(context: &mut Context, loc: &Loc, local: &Var) {
294289
use LocalState as L;
295290
let state = context.get_state(local);

move-compiler/src/cfgir/optimize/constant_fold.rs

Lines changed: 33 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
use crate::{
66
cfgir::cfg::MutForwardCFG,
77
hlir::ast::{
8-
BaseType, BaseType_, Command, Command_, Exp, ExpListItem, FunctionSignature, SingleType,
9-
TypeName, TypeName_, UnannotatedExp_, Value, Value_, Var,
8+
BaseType, BaseType_, Command, Command_, Exp, FunctionSignature, SingleType, TypeName,
9+
TypeName_, UnannotatedExp_, Value_, Var,
1010
},
1111
naming::ast::{BuiltinTypeName, BuiltinTypeName_},
1212
parser::ast::{BinOp, BinOp_, UnaryOp, UnaryOp_},
@@ -59,10 +59,11 @@ fn optimize_cmd(sp!(_, cmd_): &mut Command) -> Option<bool> {
5959
C::Return { exp: e, .. } | C::Abort(e) | C::JumpIf { cond: e, .. } => optimize_exp(e),
6060
C::IgnoreAndPop { exp: e, .. } => {
6161
let c = optimize_exp(e);
62-
match foldable_exps(e) {
63-
// All values, so the command can be removed
64-
Some(_) => return None,
65-
None => c,
62+
if ignorable_exp(e) {
63+
// value(s), so the command can be removed
64+
return None;
65+
} else {
66+
c
6667
}
6768
}
6869

@@ -87,15 +88,17 @@ fn optimize_exp(e: &mut Exp) -> bool {
8788
| E::Copy { .. }
8889
| E::Unreachable => false,
8990

90-
E::ModuleCall(mcall) => optimize_exp(&mut mcall.arguments),
91-
E::Builtin(_, e) | E::Freeze(e) | E::Dereference(e) | E::Borrow(_, e, _) => optimize_exp(e),
91+
E::ModuleCall(mcall) => mcall.arguments.iter_mut().map(optimize_exp).any(|x| x),
92+
E::Builtin(_, args) => args.iter_mut().map(optimize_exp).any(|x| x),
93+
94+
E::Freeze(e) | E::Dereference(e) | E::Borrow(_, e, _) => optimize_exp(e),
9295

9396
E::Pack(_, _, fields) => fields
9497
.iter_mut()
9598
.map(|(_, _, e)| optimize_exp(e))
9699
.any(|changed| changed),
97100

98-
E::ExpList(es) => es.iter_mut().map(optimize_exp_item).any(|changed| changed),
101+
E::Multiple(es) => es.iter_mut().map(optimize_exp).any(|changed| changed),
99102

100103
//************************************
101104
// Foldable cases
@@ -122,16 +125,15 @@ fn optimize_exp(e: &mut Exp) -> bool {
122125
let changed1 = optimize_exp(e1);
123126
let changed2 = optimize_exp(e2);
124127
let changed = changed1 || changed2;
125-
let (v1, v2) = match (foldable_exp(e1), foldable_exp(e2)) {
126-
(Some(v1), Some(v2)) => (v1, v2),
127-
_ => return changed,
128-
};
129-
match fold_binary_op(e.exp.loc, op, v1, v2) {
130-
Some(folded) => {
128+
if let (Some(v1), Some(v2)) = (foldable_exp(e1), foldable_exp(e2)) {
129+
if let Some(folded) = fold_binary_op(e.exp.loc, op, v1, v2) {
131130
*e_ = folded;
132131
true
132+
} else {
133+
changed
133134
}
134-
None => changed,
135+
} else {
136+
changed
135137
}
136138
}
137139

@@ -159,27 +161,26 @@ fn optimize_exp(e: &mut Exp) -> bool {
159161
E::Vector(_, n, ty, eargs) => (*n, ty, eargs),
160162
_ => unreachable!(),
161163
};
162-
let changed = optimize_exp(eargs);
164+
let changed = eargs.iter_mut().map(optimize_exp).any(|changed| changed);
163165
if !is_valid_const_type(ty) {
164166
return changed;
165167
}
166-
let vs = match foldable_exps(eargs) {
167-
Some(vs) => vs,
168-
None => return changed,
169-
};
168+
let mut vs = vec![];
169+
for earg in eargs {
170+
let eloc = earg.exp.loc;
171+
if let Some(v) = foldable_exp(earg) {
172+
vs.push(sp(eloc, v));
173+
} else {
174+
return changed;
175+
}
176+
}
170177
debug_assert!(n == vs.len());
171178
*e_ = evalue_(e.exp.loc, Value_::Vector(ty.clone(), vs));
172179
true
173180
}
174181
}
175182
}
176183

177-
fn optimize_exp_item(item: &mut ExpListItem) -> bool {
178-
match item {
179-
ExpListItem::Single(e, _) | ExpListItem::Splat(_, e, _) => optimize_exp(e),
180-
}
181-
}
182-
183184
fn is_valid_const_type(sp!(_, ty_): &BaseType) -> bool {
184185
use BaseType_ as T;
185186
match ty_ {
@@ -422,20 +423,12 @@ fn foldable_exp(e: &Exp) -> Option<Value_> {
422423
}
423424
}
424425

425-
fn foldable_exps(e: &Exp) -> Option<Vec<Value>> {
426+
fn ignorable_exp(e: &Exp) -> bool {
426427
use UnannotatedExp_ as E;
427428
match &e.exp.value {
428-
E::Unit { .. } => Some(vec![]),
429-
E::ExpList(items) => {
430-
let mut values = vec![];
431-
for item in items {
432-
match item {
433-
ExpListItem::Single(e, _) => values.push(sp(e.exp.loc, foldable_exp(e)?)),
434-
ExpListItem::Splat(_, es, _) => values.extend(foldable_exps(es)?),
435-
}
436-
}
437-
Some(values)
438-
}
439-
_ => Some(vec![sp(e.exp.loc, foldable_exp(e)?)]),
429+
E::Unit { .. } => true,
430+
E::Value(_) => true,
431+
E::Multiple(es) => es.iter().all(ignorable_exp),
432+
_ => false,
440433
}
441434
}

0 commit comments

Comments
 (0)