Optimize IL when stride is `1`

da5a5cd539a19ba6862d26c3e4b2ce8e65799677506e378d5af1b5bed73092aa
Alexis Sellier committed ago 1 parent b9832e26
lib/std/lang/lower.rad +15 -1
4114 4114
}
4115 4115
4116 4116
/// Emit an element address computation for array/slice indexing.
4117 4117
/// Computes: `base + idx * stride`.
4118 4118
fn emitElem(self: *mut FnLowerer, stride: u32, base: il::Reg, idx: il::Val) -> il::Reg {
4119 -
    // Optimize: if index is zero.
4119 +
    // If index is zero, return base directly.
4120 4120
    if idx == il::Val::Imm(0) {
4121 4121
        return base;
4122 4122
    }
4123 +
    // If stride is `1`, skip the multiply.
4124 +
    if stride == 1 {
4125 +
        let dst = nextReg(self);
4126 +
4127 +
        emit(self, il::Instr::BinOp {
4128 +
            op: il::BinOp::Add,
4129 +
            typ: il::Type::W64,
4130 +
            dst,
4131 +
            a: il::Val::Reg(base),
4132 +
            b: idx
4133 +
        });
4134 +
        return dst;
4135 +
    }
4123 4136
    // Compute `offset = idx * stride`.
4124 4137
    let offset = nextReg(self);
4138 +
4125 4139
    emit(self, il::Instr::BinOp {
4126 4140
        op: il::BinOp::Mul,
4127 4141
        typ: il::Type::W64,
4128 4142
        dst: offset,
4129 4143
        a: idx,
lib/std/lang/lower/tests/array.repeat.ril +12 -16
20 20
  @entry0
21 21
    reserve %0 3 1;
22 22
    store w8 1 %0 0;
23 23
    store w8 1 %0 1;
24 24
    store w8 1 %0 2;
25 -
    mul w64 %1 1 1;
26 -
    add w64 %2 %0 %1;
27 -
    load w8 %3 %2 0;
28 -
    ret %3;
25 +
    add w64 %1 %0 1;
26 +
    load w8 %2 %1 0;
27 +
    ret %2;
29 28
}
30 29
31 30
fn w8 $arrayRepeatChar() {
32 31
  @entry0
33 32
    reserve %0 3 1;
34 33
    store w8 120 %0 0;
35 34
    store w8 120 %0 1;
36 35
    store w8 120 %0 2;
37 -
    mul w64 %1 2 1;
38 -
    add w64 %2 %0 %1;
39 -
    load w8 %3 %2 0;
40 -
    ret %3;
36 +
    add w64 %1 %0 2;
37 +
    load w8 %2 %1 0;
38 +
    ret %2;
41 39
}
42 40
43 41
fn w8 $constRepeatBool() {
44 42
  @entry0
45 43
    copy %0 $BOOLS;
46 -
    mul w64 %1 1 1;
47 -
    add w64 %2 %0 %1;
48 -
    load w8 %3 %2 0;
49 -
    ret %3;
44 +
    add w64 %1 %0 1;
45 +
    load w8 %2 %1 0;
46 +
    ret %2;
50 47
}
51 48
52 49
fn w8 $constRepeatChar() {
53 50
  @entry0
54 51
    copy %0 $CHARS;
55 -
    mul w64 %1 2 1;
56 -
    add w64 %2 %0 %1;
57 -
    load w8 %3 %2 0;
58 -
    ret %3;
52 +
    add w64 %1 %0 2;
53 +
    load w8 %2 %1 0;
54 +
    ret %2;
59 55
}
lib/std/lang/lower/tests/byte.load.store.ril +6 -8
19 19
20 20
fn w8 $byteArrayAccess(w64 %0, w32 %1) {
21 21
  @entry0
22 22
    br.ult w32 %1 4 @guard#pass1 @guard#trap2;
23 23
  @guard#pass1
24 -
    mul w64 %2 %1 1;
25 -
    add w64 %3 %0 %2;
26 -
    load w8 %4 %3 0;
27 -
    ret %4;
24 +
    add w64 %2 %0 %1;
25 +
    load w8 %3 %2 0;
26 +
    ret %3;
28 27
  @guard#trap2
29 28
    ebreak;
30 29
    unreachable;
31 30
}
32 31
34 33
  @entry0
35 34
    load w32 %2 %0 8;
36 35
    br.ult w32 %1 %2 @guard#pass1 @guard#trap2;
37 36
  @guard#pass1
38 37
    load w64 %3 %0 0;
39 -
    mul w64 %4 %1 1;
40 -
    add w64 %5 %3 %4;
41 -
    load w8 %6 %5 0;
42 -
    ret %6;
38 +
    add w64 %4 %3 %1;
39 +
    load w8 %5 %4 0;
40 +
    ret %5;
43 41
  @guard#trap2
44 42
    ebreak;
45 43
    unreachable;
46 44
}
lib/std/lang/lower/tests/slice.append.ril +12 -14
2 2
  @entry0
3 3
    load w32 %3 %0 8;
4 4
    load w32 %4 %0 12;
5 5
    br.ult w32 %3 %4 @append.store1 @append.grow2;
6 6
  @append.store1
7 -
    load w64 %20 %0 0;
8 -
    mul w64 %21 %3 4;
9 -
    add w64 %22 %20 %21;
10 -
    store w32 %1 %22 0;
11 -
    add w32 %23 %3 1;
12 -
    store w32 %23 %0 8;
7 +
    load w64 %18 %0 0;
8 +
    mul w64 %19 %3 4;
9 +
    add w64 %20 %18 %19;
10 +
    store w32 %1 %20 0;
11 +
    add w32 %21 %3 1;
12 +
    store w32 %21 %0 8;
13 13
    ret;
14 14
  @append.grow2
15 15
    shl w32 %5 %4 1;
16 16
    or w32 %6 %5 1;
17 17
    load w64 %7 %2 0;
22 22
    mul w32 %12 %3 4;
23 23
    jmp @append3(0);
24 24
  @append3(w32 %13)
25 25
    br.ult w32 %13 %12 @append4 @append5;
26 26
  @append4
27 -
    mul w64 %14 %13 1;
28 -
    add w64 %15 %11 %14;
29 -
    load w8 %16 %15 0;
30 -
    mul w64 %17 %13 1;
31 -
    add w64 %18 %10 %17;
32 -
    store w8 %16 %18 0;
33 -
    add w32 %19 %13 1;
34 -
    jmp @append3(%19);
27 +
    add w64 %14 %11 %13;
28 +
    load w8 %15 %14 0;
29 +
    add w64 %16 %10 %13;
30 +
    store w8 %15 %16 0;
31 +
    add w32 %17 %13 1;
32 +
    jmp @append3(%17);
35 33
  @append5
36 34
    store w64 %10 %0 0;
37 35
    store w32 %6 %0 12;
38 36
    jmp @append.store1;
39 37
}
lib/std/lang/lower/tests/slice.delete.ril +8 -10
15 15
    ebreak;
16 16
    unreachable;
17 17
  @delete3(w32 %10)
18 18
    br.ult w32 %10 %9 @delete4 @delete5;
19 19
  @delete4
20 -
    mul w64 %11 %10 1;
21 -
    add w64 %12 %6 %11;
22 -
    load w8 %13 %12 0;
23 -
    mul w64 %14 %10 1;
24 -
    add w64 %15 %5 %14;
25 -
    store w8 %13 %15 0;
26 -
    add w32 %16 %10 1;
27 -
    jmp @delete3(%16);
20 +
    add w64 %11 %6 %10;
21 +
    load w8 %12 %11 0;
22 +
    add w64 %13 %5 %10;
23 +
    store w8 %12 %13 0;
24 +
    add w32 %14 %10 1;
25 +
    jmp @delete3(%14);
28 26
  @delete5
29 -
    sub w32 %17 %2 1;
30 -
    store w32 %17 %0 8;
27 +
    sub w32 %15 %2 1;
28 +
    store w32 %15 %0 8;
31 29
    ret;
32 30
}