Rework x64 addressing-mode lowering to be slightly more flexible. (#4080)
This PR refactors the x64 backend address-mode lowering to use an incremental-build approach, where it considers each node in a tree of `iadd`s that feed into a load/store address and, at each step, builds the best possible `Amode`. It will combine an arbitrary number of constant offsets (an extension beyond the current rules), and can capture a left-shifted (scaled) index in any position of the tree (another extension). This doesn't have any measurable performance improvement on our Wasm benchmarks in Sightglass, unfortunately, because the IR lowered from wasm32 will do address computation in 32 bits and then `uextend` it to add to the 64-bit heap base. We can't quite lift the 32-bit adds to 64 bits because this loses the wraparound semantics. (We could label adds as "expected not to overflow", and allow *those* to be lifted to 64 bit operations; wasm32 heap address computation should fit this. This is `add nuw` (no unsigned wrap) in LLVM IR terms. That's likely my next step.) Nevertheless, (i) this generalizes the cases we can handle, which should be a good thing, all other things being equal (and in this case, no compile time impact was measured); and (ii) might benefit non-Wasm frontends.
This commit is contained in:
@@ -249,30 +249,11 @@ newtype_of_reg!(
|
||||
|reg| reg.class() == RegClass::Float
|
||||
);
|
||||
|
||||
/// A possible addressing mode (amode) that can be used in instructions.
|
||||
/// These denote a 64-bit value only.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Amode {
|
||||
/// Immediate sign-extended and a Register.
|
||||
ImmReg {
|
||||
simm32: u32,
|
||||
base: Reg,
|
||||
flags: MemFlags,
|
||||
},
|
||||
// N.B.: `Amode` is defined in `inst.isle`. We add some convenience
|
||||
// constructors here.
|
||||
|
||||
/// sign-extend-32-to-64(Immediate) + Register1 + (Register2 << Shift)
|
||||
ImmRegRegShift {
|
||||
simm32: u32,
|
||||
base: Gpr,
|
||||
index: Gpr,
|
||||
shift: u8, /* 0 .. 3 only */
|
||||
flags: MemFlags,
|
||||
},
|
||||
|
||||
/// sign-extend-32-to-64(Immediate) + RIP (instruction pointer).
|
||||
/// To wit: not supported in 32-bits mode.
|
||||
RipRelative { target: MachLabel },
|
||||
}
|
||||
// Re-export the type from the ISLE generated code.
|
||||
pub use crate::isa::x64::lower::isle::generated_code::Amode;
|
||||
|
||||
impl Amode {
|
||||
pub(crate) fn imm_reg(simm32: u32, base: Reg) -> Self {
|
||||
|
||||
Reference in New Issue
Block a user