orginizing null checks better to get more peephole hits
This commit is contained in:
parent
83146cfd61
commit
afc1c5aac5
|
@ -957,10 +957,10 @@ main := fn(): int {
|
||||||
```hb
|
```hb
|
||||||
main := fn(): uint {
|
main := fn(): uint {
|
||||||
always_nn := @as(?^uint, &0)
|
always_nn := @as(?^uint, &0)
|
||||||
ptr := @unwrap(always_nn)
|
ptr1 := @unwrap(always_nn)
|
||||||
always_n := @as(?^uint, null)
|
always_n := @as(?^uint, null)
|
||||||
ptr = @unwrap(always_n)
|
ptr2 := @unwrap(always_n)
|
||||||
return *ptr
|
return *ptr1 + *ptr2
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -1362,8 +1362,36 @@ impl Nodes {
|
||||||
return Some(self[target].inputs[0]);
|
return Some(self[target].inputs[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
K::Die => {
|
||||||
|
if self[target].inputs[0] == NEVER {
|
||||||
|
return Some(NEVER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
K::Assert { kind, .. } => 'b: {
|
||||||
|
let pin = match (kind, self.try_match_cond(target)) {
|
||||||
|
(AssertKind::NullCheck, CondOptRes::Known { value: false, pin }) => pin,
|
||||||
|
(AssertKind::UnwrapCheck, CondOptRes::Unknown) => None,
|
||||||
|
_ => break 'b,
|
||||||
|
}
|
||||||
|
.unwrap_or(self[target].inputs[0]);
|
||||||
|
|
||||||
|
for out in self[target].outputs.clone() {
|
||||||
|
if !self[out].kind.is_pinned() && self[out].inputs[0] != pin {
|
||||||
|
self.modify_input(out, 0, pin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Some(self[target].inputs[2]);
|
||||||
|
}
|
||||||
_ if self.is_cfg(target) && self.idom(target) == NEVER => panic!(),
|
_ if self.is_cfg(target) && self.idom(target) == NEVER => panic!(),
|
||||||
_ => {}
|
K::Start
|
||||||
|
| K::Entry
|
||||||
|
| K::Mem
|
||||||
|
| K::Loops
|
||||||
|
| K::End
|
||||||
|
| K::CInt { .. }
|
||||||
|
| K::Arg
|
||||||
|
| K::Global { .. }
|
||||||
|
| K::Join => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
|
@ -1923,7 +1951,8 @@ impl Kind {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_pinned(&self) -> bool {
|
fn is_pinned(&self) -> bool {
|
||||||
self.is_cfg() || matches!(self, Self::Phi | Self::Arg | Self::Mem | Self::Loops)
|
self.is_cfg()
|
||||||
|
|| matches!(self, Self::Phi | Self::Arg | Self::Mem | Self::Loops | Kind::Assert { .. })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_cfg(&self) -> bool {
|
fn is_cfg(&self) -> bool {
|
||||||
|
@ -1937,7 +1966,6 @@ impl Kind {
|
||||||
| Self::Then
|
| Self::Then
|
||||||
| Self::Else
|
| Self::Else
|
||||||
| Self::Call { .. }
|
| Self::Call { .. }
|
||||||
| Self::Assert { .. }
|
|
||||||
| Self::If
|
| Self::If
|
||||||
| Self::Region
|
| Self::Region
|
||||||
| Self::Loop
|
| Self::Loop
|
||||||
|
@ -2257,9 +2285,7 @@ impl ItemCtx {
|
||||||
mem::take(&mut self.ctrl).soft_remove(&mut self.nodes);
|
mem::take(&mut self.ctrl).soft_remove(&mut self.nodes);
|
||||||
|
|
||||||
self.nodes.iter_peeps(1000, stack, tys);
|
self.nodes.iter_peeps(1000, stack, tys);
|
||||||
}
|
|
||||||
|
|
||||||
fn unlock(&mut self) {
|
|
||||||
self.nodes.unlock(MEM);
|
self.nodes.unlock(MEM);
|
||||||
self.nodes.unlock(NEVER);
|
self.nodes.unlock(NEVER);
|
||||||
self.nodes.unlock(LOOPS);
|
self.nodes.unlock(LOOPS);
|
||||||
|
@ -4383,7 +4409,7 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
self.ci.finalize(&mut self.pool.nid_stack, self.tys, self.files);
|
self.ci.finalize(&mut self.pool.nid_stack, self.tys, self.files);
|
||||||
|
|
||||||
let mut to_remove = vec![];
|
//let mut to_remove = vec![];
|
||||||
for (id, node) in self.ci.nodes.iter() {
|
for (id, node) in self.ci.nodes.iter() {
|
||||||
let Kind::Assert { kind, pos } = node.kind else { continue };
|
let Kind::Assert { kind, pos } = node.kind else { continue };
|
||||||
|
|
||||||
|
@ -4408,49 +4434,10 @@ impl<'a> Codegen<'a> {
|
||||||
or explicitly check for null and handle it \
|
or explicitly check for null and handle it \
|
||||||
('if <opt> == null { /* handle */ } else { /* use opt */ }')"
|
('if <opt> == null { /* handle */ } else { /* use opt */ }')"
|
||||||
}
|
}
|
||||||
(AK::NullCheck, CR::Known { value: false, pin }) => {
|
_ => unreachable!(),
|
||||||
to_remove.push((id, pin));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
(AK::UnwrapCheck, CR::Unknown) => {
|
|
||||||
to_remove.push((id, None));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
self.report(pos, msg);
|
self.report(pos, msg);
|
||||||
}
|
}
|
||||||
to_remove.into_iter().for_each(|(n, pin)| {
|
|
||||||
let pin = pin.unwrap_or_else(|| {
|
|
||||||
let mut pin = self.ci.nodes[n].inputs[0];
|
|
||||||
while matches!(self.ci.nodes[pin].kind, Kind::Assert { .. }) {
|
|
||||||
pin = self.ci.nodes[n].inputs[0];
|
|
||||||
}
|
|
||||||
pin
|
|
||||||
});
|
|
||||||
for mut out in self.ci.nodes[n].outputs.clone() {
|
|
||||||
if self.ci.nodes.is_cfg(out) {
|
|
||||||
let index = self.ci.nodes[out].inputs.iter().position(|&p| p == n).unwrap();
|
|
||||||
self.ci.nodes.modify_input(out, index, self.ci.nodes[n].inputs[0]);
|
|
||||||
} else {
|
|
||||||
if !self.ci.nodes[out].kind.is_pinned() && self.ci.nodes[out].inputs[0] != pin {
|
|
||||||
out = self.ci.nodes.modify_input(out, 0, pin);
|
|
||||||
}
|
|
||||||
let index =
|
|
||||||
self.ci.nodes[out].inputs[1..].iter().position(|&p| p == n).unwrap() + 1;
|
|
||||||
self.ci.nodes.modify_input(out, index, self.ci.nodes[n].inputs[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug_assert!(
|
|
||||||
self.ci.nodes.values[n as usize]
|
|
||||||
.as_ref()
|
|
||||||
.map_or(true, |n| !matches!(n.kind, Kind::Assert { .. })),
|
|
||||||
"{:?} {:?}",
|
|
||||||
self.ci.nodes[n],
|
|
||||||
self.ci.nodes[n].outputs.iter().map(|&o| &self.ci.nodes[o]).collect::<Vec<_>>(),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
self.ci.unlock();
|
|
||||||
|
|
||||||
for &node in self.ci.nodes[NEVER].inputs.iter() {
|
for &node in self.ci.nodes[NEVER].inputs.iter() {
|
||||||
if self.ci.nodes[node].kind == Kind::Return
|
if self.ci.nodes[node].kind == Kind::Return
|
||||||
|
@ -4607,16 +4594,13 @@ impl<'a> Codegen<'a> {
|
||||||
self.unwrap_opt_unchecked(ty, oty, opt);
|
self.unwrap_opt_unchecked(ty, oty, opt);
|
||||||
|
|
||||||
// TODO: extract the if check int a fucntion
|
// TODO: extract the if check int a fucntion
|
||||||
self.ci.ctrl.set(
|
let ass = self.ci.nodes.new_node_nop(oty, Kind::Assert { kind, pos }, [
|
||||||
self.ci.nodes.new_node_nop(oty, Kind::Assert { kind, pos }, [
|
self.ci.ctrl.get(),
|
||||||
self.ci.ctrl.get(),
|
null_check,
|
||||||
null_check,
|
opt.id,
|
||||||
opt.id,
|
]);
|
||||||
]),
|
self.ci.nodes.pass_aclass(self.ci.nodes.aclass_index(opt.id).1, ass);
|
||||||
&mut self.ci.nodes,
|
opt.id = ass;
|
||||||
);
|
|
||||||
self.ci.nodes.pass_aclass(self.ci.nodes.aclass_index(opt.id).1, self.ci.ctrl.get());
|
|
||||||
opt.id = self.ci.ctrl.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unwrap_opt_unchecked(&mut self, ty: ty::Id, oty: ty::Id, opt: &mut Value) {
|
fn unwrap_opt_unchecked(&mut self, ty: ty::Id, oty: ty::Id, opt: &mut Value) {
|
||||||
|
|
|
@ -27,8 +27,8 @@ main:
|
||||||
ADDI64 r254, r254, 90d
|
ADDI64 r254, r254, 90d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
put_filled_rect:
|
put_filled_rect:
|
||||||
ADDI64 r254, r254, -212d
|
ADDI64 r254, r254, -220d
|
||||||
ST r32, r254, 108a, 104h
|
ST r32, r254, 108a, 112h
|
||||||
ST r3, r254, 92a, 16h
|
ST r3, r254, 92a, 16h
|
||||||
ADDI64 r3, r254, 92d
|
ADDI64 r3, r254, 92d
|
||||||
ST r5, r254, 76a, 16h
|
ST r5, r254, 76a, 16h
|
||||||
|
@ -36,74 +36,73 @@ put_filled_rect:
|
||||||
ST r7, r254, 75a, 1h
|
ST r7, r254, 75a, 1h
|
||||||
ADDI64 r7, r254, 75d
|
ADDI64 r7, r254, 75d
|
||||||
LI64 r8, 25d
|
LI64 r8, 25d
|
||||||
LI64 r6, 2d
|
LI64 r32, 2d
|
||||||
LI64 r9, 8d
|
LI64 r6, 8d
|
||||||
ADDI64 r32, r254, 25d
|
ADDI64 r33, r254, 25d
|
||||||
ADDI64 r33, r254, 50d
|
ADDI64 r34, r254, 50d
|
||||||
LI8 r34, 5b
|
LI8 r35, 5b
|
||||||
ST r34, r254, 25a, 1h
|
ST r35, r254, 25a, 1h
|
||||||
LD r35, r5, 0a, 8h
|
LD r36, r5, 0a, 8h
|
||||||
ST r35, r254, 26a, 4h
|
ST r36, r254, 26a, 4h
|
||||||
LI64 r36, 1d
|
LI64 r37, 1d
|
||||||
ST r36, r254, 30a, 4h
|
ST r37, r254, 30a, 4h
|
||||||
ST r7, r254, 34a, 8h
|
ST r7, r254, 34a, 8h
|
||||||
ST r34, r254, 50a, 1h
|
ST r35, r254, 50a, 1h
|
||||||
ST r35, r254, 51a, 4h
|
ST r36, r254, 51a, 4h
|
||||||
ST r36, r254, 55a, 4h
|
ST r37, r254, 55a, 4h
|
||||||
ST r7, r254, 59a, 8h
|
ST r7, r254, 59a, 8h
|
||||||
CP r37, r7
|
CP r38, r7
|
||||||
LD r4, r3, 8a, 8h
|
LD r7, r3, 8a, 8h
|
||||||
LD r38, r5, 8a, 8h
|
LD r39, r5, 8a, 8h
|
||||||
ADD64 r1, r38, r4
|
ADD64 r11, r39, r7
|
||||||
SUB64 r5, r1, r36
|
SUB64 r4, r11, r37
|
||||||
LD r39, r2, 8a, 8h
|
LD r40, r2, 8a, 8h
|
||||||
MUL64 r7, r39, r5
|
MUL64 r5, r40, r4
|
||||||
LD r10, r2, 0a, 8h
|
LD r10, r2, 0a, 8h
|
||||||
ADD64 r11, r10, r7
|
ADD64 r9, r10, r5
|
||||||
LD r5, r3, 0a, 8h
|
LD r41, r3, 0a, 8h
|
||||||
ADD64 r40, r5, r11
|
ADD64 r42, r41, r9
|
||||||
MUL64 r4, r39, r4
|
MUL64 r43, r40, r7
|
||||||
ADD64 r7, r10, r4
|
3: ADD64 r43, r43, r10
|
||||||
ADD64 r41, r5, r7
|
ADD64 r9, r43, r41
|
||||||
3: JGTU r38, r36, :0
|
JGTU r39, r37, :0
|
||||||
JNE r38, r36, :1
|
JNE r39, r37, :1
|
||||||
ADDI64 r4, r254, 0d
|
ADDI64 r4, r254, 0d
|
||||||
ST r34, r254, 0a, 1h
|
ST r35, r254, 0a, 1h
|
||||||
ST r35, r254, 1a, 4h
|
ST r36, r254, 1a, 4h
|
||||||
ST r36, r254, 5a, 4h
|
ST r37, r254, 5a, 4h
|
||||||
ST r37, r254, 9a, 8h
|
ST r38, r254, 9a, 8h
|
||||||
ST r41, r254, 17a, 8h
|
ST r9, r254, 17a, 8h
|
||||||
CP r2, r9
|
CP r2, r6
|
||||||
CP r3, r6
|
CP r3, r32
|
||||||
CP r5, r8
|
CP r5, r8
|
||||||
ECA
|
ECA
|
||||||
JMP :1
|
JMP :1
|
||||||
1: JMP :2
|
1: JMP :2
|
||||||
0: CP r3, r6
|
0: CP r3, r32
|
||||||
CP r42, r9
|
CP r44, r6
|
||||||
CP r43, r8
|
CP r45, r8
|
||||||
ST r41, r254, 67a, 8h
|
ST r9, r254, 67a, 8h
|
||||||
CP r44, r3
|
CP r2, r44
|
||||||
CP r2, r42
|
CP r4, r34
|
||||||
|
CP r5, r45
|
||||||
|
ECA
|
||||||
|
ST r42, r254, 42a, 8h
|
||||||
|
CP r2, r44
|
||||||
|
CP r3, r32
|
||||||
CP r4, r33
|
CP r4, r33
|
||||||
CP r5, r43
|
CP r5, r45
|
||||||
ECA
|
ECA
|
||||||
ST r40, r254, 42a, 8h
|
SUB64 r42, r42, r40
|
||||||
CP r2, r42
|
SUB64 r39, r39, r32
|
||||||
CP r3, r44
|
CP r10, r41
|
||||||
CP r4, r32
|
CP r41, r40
|
||||||
CP r5, r43
|
CP r8, r45
|
||||||
ECA
|
|
||||||
SUB64 r40, r40, r39
|
|
||||||
ADD64 r41, r39, r41
|
|
||||||
SUB64 r38, r38, r44
|
|
||||||
CP r6, r44
|
CP r6, r44
|
||||||
CP r8, r43
|
|
||||||
CP r9, r42
|
|
||||||
JMP :3
|
JMP :3
|
||||||
2: LD r32, r254, 108a, 104h
|
2: LD r32, r254, 108a, 112h
|
||||||
ADDI64 r254, r254, 212d
|
ADDI64 r254, r254, 220d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 910
|
code size: 906
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
test.hb:4:17: unwrap is not needed since the value is (provably) never null, remove it, or replace with '@as(<expr_ty>, <opt_expr>)'
|
test.hb:4:18: unwrap is not needed since the value is (provably) never null, remove it, or replace with '@as(<expr_ty>, <opt_expr>)'
|
||||||
ptr := @unwrap(always_nn)
|
ptr1 := @unwrap(always_nn)
|
||||||
^
|
^
|
||||||
test.hb:6:16: unwrap is incorrect since the value is (provably) always null, make sure your logic is correct
|
test.hb:6:18: unwrap is incorrect since the value is (provably) always null, make sure your logic is correct
|
||||||
ptr = @unwrap(always_n)
|
ptr2 := @unwrap(always_n)
|
||||||
^
|
^
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
foo:
|
foo:
|
||||||
ADDI64 r254, r254, -184d
|
ADDI64 r254, r254, -176d
|
||||||
ST r31, r254, 80a, 104h
|
ST r31, r254, 80a, 96h
|
||||||
ADDI64 r32, r254, 64d
|
ADDI64 r32, r254, 64d
|
||||||
LRA r3, r0, :some_file
|
LRA r3, r0, :some_file
|
||||||
JAL r31, r0, :get
|
JAL r31, r0, :get
|
||||||
|
@ -17,25 +17,25 @@ foo:
|
||||||
LI64 r36, 4d
|
LI64 r36, 4d
|
||||||
LD r37, r254, 72a, 8h
|
LD r37, r254, 72a, 8h
|
||||||
JNE r37, r36, :2
|
JNE r37, r36, :2
|
||||||
ADDI64 r38, r254, 32d
|
ADDI64 r37, r254, 32d
|
||||||
ST r35, r254, 32a, 1h
|
ST r35, r254, 32a, 1h
|
||||||
LI64 r39, 2d
|
LI64 r38, 2d
|
||||||
ST r39, r254, 40a, 8h
|
ST r38, r254, 40a, 8h
|
||||||
LD r1, r38, 0a, 16h
|
LD r1, r37, 0a, 16h
|
||||||
JMP :1
|
JMP :1
|
||||||
2: LRA r40, r0, :MAGIC
|
2: LRA r39, r0, :MAGIC
|
||||||
LD r41, r40, 0a, 8h
|
LD r40, r39, 0a, 8h
|
||||||
JNE r41, r37, :3
|
JNE r40, r37, :3
|
||||||
ADDI64 r42, r254, 16d
|
ADDI64 r41, r254, 16d
|
||||||
ST r35, r254, 16a, 1h
|
ST r35, r254, 16a, 1h
|
||||||
ST r0, r254, 24a, 8h
|
ST r0, r254, 24a, 8h
|
||||||
LD r1, r42, 0a, 16h
|
LD r1, r41, 0a, 16h
|
||||||
JMP :1
|
JMP :1
|
||||||
3: ADDI64 r43, r254, 0d
|
3: ADDI64 r42, r254, 0d
|
||||||
ST r0, r254, 0a, 1h
|
ST r0, r254, 0a, 1h
|
||||||
LD r1, r43, 0a, 16h
|
LD r1, r42, 0a, 16h
|
||||||
1: LD r31, r254, 80a, 104h
|
1: LD r31, r254, 80a, 96h
|
||||||
ADDI64 r254, r254, 184d
|
ADDI64 r254, r254, 176d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
get:
|
get:
|
||||||
ADDI64 r254, r254, -32d
|
ADDI64 r254, r254, -32d
|
||||||
|
|
|
@ -9,9 +9,9 @@ create_back_buffer:
|
||||||
LI8 r34, 255b
|
LI8 r34, 255b
|
||||||
CP r2, r34
|
CP r2, r34
|
||||||
JAL r31, r0, :request_page
|
JAL r31, r0, :request_page
|
||||||
CP r2, r33
|
CP r35, r33
|
||||||
SUB64 r35, r2, r32
|
5: SUB64 r35, r35, r32
|
||||||
5: JGTS r35, r0, :2
|
JGTS r35, r0, :2
|
||||||
JMP :1
|
JMP :1
|
||||||
2: CP r36, r1
|
2: CP r36, r1
|
||||||
JLTS r35, r32, :3
|
JLTS r35, r32, :3
|
||||||
|
@ -20,8 +20,7 @@ create_back_buffer:
|
||||||
JMP :4
|
JMP :4
|
||||||
3: CP r2, r35
|
3: CP r2, r35
|
||||||
JAL r31, r0, :request_page
|
JAL r31, r0, :request_page
|
||||||
4: SUB64 r35, r35, r32
|
4: CP r1, r36
|
||||||
CP r1, r36
|
|
||||||
JMP :5
|
JMP :5
|
||||||
1: LD r31, r254, 0a, 48h
|
1: LD r31, r254, 0a, 48h
|
||||||
ADDI64 r254, r254, 48d
|
ADDI64 r254, r254, 48d
|
||||||
|
@ -42,6 +41,6 @@ request_page:
|
||||||
LI64 r2, 3d
|
LI64 r2, 3d
|
||||||
ECA
|
ECA
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 321
|
code size: 317
|
||||||
ret: 42
|
ret: 42
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -4,8 +4,8 @@ do_stuff:
|
||||||
just_read:
|
just_read:
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -104d
|
ADDI64 r254, r254, -96d
|
||||||
ST r31, r254, 48a, 56h
|
ST r31, r254, 48a, 48h
|
||||||
ADDI64 r32, r254, 16d
|
ADDI64 r32, r254, 16d
|
||||||
CP r1, r32
|
CP r1, r32
|
||||||
JAL r31, r0, :optionala
|
JAL r31, r0, :optionala
|
||||||
|
@ -28,13 +28,11 @@ main:
|
||||||
JNE r36, r0, :2
|
JNE r36, r0, :2
|
||||||
LI64 r1, 20d
|
LI64 r1, 20d
|
||||||
JMP :1
|
JMP :1
|
||||||
2: LI64 r37, 100d
|
2: LI64 r2, 100d
|
||||||
ST r37, r254, 8a, 8h
|
|
||||||
LD r2, r254, 8a, 8h
|
|
||||||
JAL r31, r0, :do_stuff
|
JAL r31, r0, :do_stuff
|
||||||
ADD64 r1, r1, r34
|
ADD64 r1, r1, r34
|
||||||
1: LD r31, r254, 48a, 56h
|
1: LD r31, r254, 48a, 48h
|
||||||
ADDI64 r254, r254, 104d
|
ADDI64 r254, r254, 96d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
optional:
|
optional:
|
||||||
ADDI64 r254, r254, -16d
|
ADDI64 r254, r254, -16d
|
||||||
|
@ -61,6 +59,6 @@ optionala:
|
||||||
BMC r6, r1, 32h
|
BMC r6, r1, 32h
|
||||||
ADDI64 r254, r254, 48d
|
ADDI64 r254, r254, 48d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 580
|
code size: 554
|
||||||
ret: 100
|
ret: 100
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
Loading…
Reference in a new issue