-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[compiler-v2] Variable window peephole optimization
- Loading branch information
Showing
35 changed files
with
980 additions
and
236 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 0 additions & 51 deletions
51
.../move/move-compiler-v2/src/file_format_generator/peephole_optimizer/inefficient_binops.rs
This file was deleted.
Oops, something went wrong.
77 changes: 77 additions & 0 deletions
77
...y/move/move-compiler-v2/src/file_format_generator/peephole_optimizer/inefficient_loads.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright (c) Aptos Foundation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
//! This module contains a window peephole optimizer for the Move bytecode. | ||
//! As with all peephole optimizers here, it assumes that the bytecode is valid. | ||
//! | ||
//! This optimizer addresses a commonly appearing pattern when involving loads. | ||
//! | ||
//! The pattern is: | ||
//! 1. Load a constant into the stack. | ||
//! 2. Store the constant into a local `u`. | ||
//! 3. A (possibly empty) sequence of instructions that do not involve `u`, | ||
//! which we name `sequence`. Currently, the only instructions that can | ||
//! involve `u` are: `CopyLoc`, `MoveLoc`, `StLoc`, `ImmBorrowLoc`, | ||
//! and `MutBorrowLoc`. | ||
//! 4. A `MoveLoc` of `u`. | ||
//! | ||
//! This pattern can be replaced with: | ||
//! 1. `sequence`. | ||
//! 2. Load the constant into the stack. | ||
//! | ||
//! This transformation leaves the stack in the same state. | ||
//! The local `u` in the original code has been moved from, so later code | ||
//! cannot use it without a subsequent store. | ||
//! So, skipping the store to `u` is safe. | ||
use crate::file_format_generator::peephole_optimizer::optimizers::WindowOptimizer; | ||
use move_binary_format::file_format::Bytecode; | ||
|
||
/// An optimizer for inefficient loads. | ||
pub struct InefficientLoads; | ||
|
||
impl InefficientLoads { | ||
// We need at least 3 instructions, corresponding to points 1, 2, and 4 in the pattern | ||
// described in the module documentation (at the top of the file). | ||
const MIN_WINDOW_SIZE: usize = 3; | ||
} | ||
|
||
impl WindowOptimizer for InefficientLoads { | ||
fn optimize_window(&self, window: &[Bytecode]) -> Option<(Vec<Bytecode>, usize)> { | ||
use Bytecode::*; | ||
if window.len() < Self::MIN_WINDOW_SIZE { | ||
return None; | ||
} | ||
// Load and Store a constant into `u`. | ||
let u = match (&window[0], &window[1]) { | ||
( | ||
LdU8(_) | LdU16(_) | LdU32(_) | LdU64(_) | LdU128(_) | LdU256(_) | LdConst(_) | ||
| LdTrue | LdFalse, | ||
StLoc(u), | ||
) => *u, | ||
_ => return None, | ||
}; | ||
for (index, instr) in window[2..].iter().enumerate() { | ||
match instr { | ||
CopyLoc(v) | StLoc(v) | ImmBorrowLoc(v) | MutBorrowLoc(v) if u == *v => { | ||
// We have encountered an instruction that involves `u`. | ||
return None; | ||
}, | ||
MoveLoc(v) if u == *v => { | ||
// We have reached the end of the pattern (point 4 in the module documentation). | ||
let sequence = &window[2..index + 2]; | ||
let load_constant = &window[0..1]; | ||
return Some(( | ||
[sequence, load_constant].concat(), | ||
index + Self::MIN_WINDOW_SIZE, | ||
)); | ||
}, | ||
_ => { | ||
// Instruction that does not involve `u`, including `MoveLoc` of a different local. | ||
}, | ||
} | ||
} | ||
// The full pattern was not found. | ||
None | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.