Skip to content

Commit b93ba2e

Browse files
authored
fix acquire list (#17817)
1 parent d6e70fb commit b93ba2e

File tree

6 files changed

+234
-12
lines changed

6 files changed

+234
-12
lines changed

third_party/move/move-compiler-v2/src/file_format_generator/module_generator.rs

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,6 +1074,33 @@ impl ModuleContext<'_> {
10741074
}
10751075

10761076
impl ModuleContext<'_> {
1077+
/// Get the called functions from the same module by traversing the stackless bytecode.
1078+
fn get_same_module_called_functions(
1079+
&self,
1080+
module: &ModuleEnv,
1081+
) -> BTreeMap<FunId, BTreeSet<FunId>> {
1082+
let mut called_functions_map = BTreeMap::new();
1083+
for fun in module.get_functions() {
1084+
if fun.is_inline() {
1085+
continue;
1086+
}
1087+
let mut called_functions = BTreeSet::new();
1088+
let target = self.targets.get_target(&fun, &FunctionVariant::Baseline);
1089+
for bc in target.get_bytecode() {
1090+
use Bytecode::*;
1091+
use Operation::*;
1092+
if let Call(_, _, Function(mid, fid, _), ..) = bc {
1093+
// only add functions from the same module and not the function itself
1094+
if *mid == module.get_id() && *fid != fun.get_id() {
1095+
called_functions.insert(*fid);
1096+
}
1097+
}
1098+
}
1099+
called_functions_map.insert(fun.get_id(), called_functions);
1100+
}
1101+
called_functions_map
1102+
}
1103+
10771104
/// Acquires analysis. This is temporary until we have the full reference analysis.
10781105
fn generate_acquires_map(&self, module: &ModuleEnv) -> BTreeMap<FunId, BTreeSet<StructId>> {
10791106
// Compute map with direct usage of resources
@@ -1082,6 +1109,7 @@ impl ModuleContext<'_> {
10821109
.filter(|f| !f.is_inline())
10831110
.map(|f| (f.get_id(), self.get_direct_function_acquires(&f)))
10841111
.collect::<BTreeMap<_, _>>();
1112+
let called_functions_map = self.get_same_module_called_functions(module);
10851113
// Now run a fixed-point loop: add resources used by called functions until there are no
10861114
// changes.
10871115
loop {
@@ -1090,20 +1118,16 @@ impl ModuleContext<'_> {
10901118
if fun.is_inline() {
10911119
continue;
10921120
}
1093-
if let Some(callees) = fun.get_called_functions() {
1094-
let mut usage = usage_map[&fun.get_id()].clone();
1095-
let count = usage.len();
1121+
let mut usage = usage_map[&fun.get_id()].clone();
1122+
let count = usage.len();
1123+
for called_fun in called_functions_map[&fun.get_id()].iter() {
10961124
// Extend usage by that of callees from the same module. Acquires is only
10971125
// local to a module.
1098-
for callee in callees {
1099-
if callee.module_id == module.get_id() {
1100-
usage.extend(usage_map[&callee.id].iter().cloned());
1101-
}
1102-
}
1103-
if usage.len() > count {
1104-
*usage_map.get_mut(&fun.get_id()).unwrap() = usage;
1105-
changes = true;
1106-
}
1126+
usage.extend(usage_map[called_fun].iter().cloned());
1127+
}
1128+
if usage.len() > count {
1129+
*usage_map.get_mut(&fun.get_id()).unwrap() = usage;
1130+
changes = true;
11071131
}
11081132
}
11091133
if !changes {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
============ disassembled file-format ==================
3+
// Move bytecode v8
4+
module cafe.Module0 {
5+
struct S has copy, drop, store, key {
6+
dummy_field: bool
7+
}
8+
9+
public function1() /* def_idx: 0 */ {
10+
B0:
11+
0: Ret
12+
B1:
13+
1: Call function2()
14+
2: Ret
15+
}
16+
public function2() /* def_idx: 1 */ {
17+
L0: $t0: &S
18+
B0:
19+
0: LdConst[0](Address: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, 239])
20+
1: ImmBorrowGlobal[0](S)
21+
2: StLoc[0]($t0: &S)
22+
3: MoveLoc[0]($t0: &S)
23+
4: Pop
24+
5: Ret
25+
}
26+
}
27+
============ bytecode verification succeeded ========
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module 0xCAFE::Module0 {
2+
const ADDR: address = @0xBEEF;
3+
struct S has copy, drop, store, key { }
4+
5+
public fun function1() acquires S {
6+
return;
7+
function2();
8+
}
9+
public fun function2() acquires S {
10+
borrow_global<S>(ADDR);
11+
}
12+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
============ disassembled file-format ==================
3+
// Move bytecode v8
4+
module cafe.Module0 {
5+
struct S has copy, drop, store, key {
6+
dummy_field: bool
7+
}
8+
9+
public function1() /* def_idx: 0 */ {
10+
B0:
11+
0: Ret
12+
}
13+
public function2() /* def_idx: 1 */ {
14+
L0: $t0: &S
15+
B0:
16+
0: LdConst[0](Address: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, 239])
17+
1: ImmBorrowGlobal[0](S)
18+
2: Pop
19+
3: Ret
20+
}
21+
}
22+
============ bytecode verification succeeded ========
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// -- Model dump before first bytecode pipeline
2+
module 0x8675309::M1 {
3+
struct R<T> {
4+
x: u64,
5+
}
6+
public fun extract<T>(r: &mut R<T>,y: u64): R<T> {
7+
{
8+
let x: u64 = Sub<u64>(select M1::R.x<&mut R<T>>(r), y);
9+
pack M1::R<T>(x)
10+
}
11+
}
12+
} // end 0x8675309::M1
13+
module 0x8675309::M {
14+
use 0x8675309::M1::{R}; // resolved as: 0x8675309::M1
15+
use 0x8675309::M1::{extract}; // resolved as: 0x8675309::M1
16+
struct R1<T> {
17+
x: M1::R<T>,
18+
}
19+
private fun f<T>(a: address): M1::R<T> {
20+
{
21+
let r: &mut R1<T> = BorrowGlobal(Mutable)<R1<T>>(a);
22+
M1::extract<T>(Borrow(Mutable)(select M::R1.x<&mut R1<T>>(r)), 3)
23+
}
24+
}
25+
public fun t0<T>(a: address): M1::R<T> {
26+
if false {
27+
Tuple()
28+
} else {
29+
Abort(0)
30+
};
31+
M::f<T>(a)
32+
}
33+
} // end 0x8675309::M
34+
35+
// -- Sourcified model before first bytecode pipeline
36+
module 0x8675309::M1 {
37+
struct R<phantom T> has copy, drop, store, key {
38+
x: u64,
39+
}
40+
public fun extract<T>(r: &mut R<T>, y: u64): R<T> {
41+
let x = r.x - y;
42+
R<T>{x: x}
43+
}
44+
}
45+
module 0x8675309::M {
46+
use 0x8675309::M1;
47+
use 0x8675309::M1;
48+
struct R1<phantom T> has key {
49+
x: M1::R<T>,
50+
}
51+
fun f<T>(a: address): M1::R<T> {
52+
let r = borrow_global_mut<R1<T>>(a);
53+
M1::extract<T>(&mut r.x, 3)
54+
}
55+
public fun t0<T>(a: address): M1::R<T> {
56+
if (false) () else abort 0;
57+
f<T>(a)
58+
}
59+
}
60+
61+
62+
Diagnostics:
63+
warning: If condition is always false, so then branch code eliminated as dead code
64+
┌─ tests/simplifier-elimination/assert_false_with_resource.move:30:17
65+
66+
30 │ assert!(false, 0);
67+
│ ------ ^^^^^
68+
│ │ │
69+
│ │ condition is always false
70+
│ then branch eliminated
71+
72+
// -- Model dump before second bytecode pipeline
73+
module 0x8675309::M1 {
74+
struct R<T> {
75+
x: u64,
76+
}
77+
public fun extract<T>(r: &mut R<T>,y: u64): R<T> {
78+
{
79+
let x: u64 = Sub<u64>(select M1::R.x<&mut R<T>>(r), y);
80+
pack M1::R<T>(x)
81+
}
82+
}
83+
} // end 0x8675309::M1
84+
module 0x8675309::M {
85+
use 0x8675309::M1::{R}; // resolved as: 0x8675309::M1
86+
use 0x8675309::M1::{extract}; // resolved as: 0x8675309::M1
87+
struct R1<T> {
88+
x: M1::R<T>,
89+
}
90+
private fun f<T>(a: address): M1::R<T> {
91+
{
92+
let r: &mut R1<T> = BorrowGlobal(Mutable)<R1<T>>(a);
93+
M1::extract<T>(Borrow(Mutable)(select M::R1.x<&mut R1<T>>(r)), 3)
94+
}
95+
}
96+
public fun t0<T>(a: address): M1::R<T> {
97+
Abort(0);
98+
M::f<T>(a)
99+
}
100+
} // end 0x8675309::M
101+
102+
103+
============ bytecode verification succeeded ========
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module 0x8675309::M1 {
2+
3+
4+
struct R<phantom T> has key, store, copy, drop {
5+
x: u64
6+
}
7+
8+
public fun extract<T>(r: &mut R<T>, y: u64): R<T> {
9+
let x = r.x - y;
10+
R {x}
11+
}
12+
13+
}
14+
15+
module 0x8675309::M {
16+
use 0x8675309::M1::R;
17+
use 0x8675309::M1::extract;
18+
19+
struct R1<phantom T> has key {
20+
x: R<T>
21+
}
22+
23+
24+
fun f<T>(a: address): R<T> {
25+
let r = borrow_global_mut<R1<T>>(a);
26+
extract<T>(&mut r.x, 3)
27+
}
28+
29+
public fun t0<T>(a: address): R<T> {
30+
assert!(false, 0);
31+
f(a)
32+
}
33+
34+
}

0 commit comments

Comments
 (0)