Skip to content

Commit 797e722

Browse files
chapter17: idealize MinusF, RoundF32, Shl, Shr, Sar, ToFloat
1 parent 5ae17e4 commit 797e722

1 file changed

Lines changed: 104 additions & 3 deletions

File tree

src/sea_of_nodes/nodes/idealize.rs

Lines changed: 104 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use crate::datastructures::id::Id;
22
use crate::sea_of_nodes::nodes::node::{
3-
Add, Bool, CProj, Cast, Constant, Div, If, Load, Minus, Mul, Not, Phi, ReadOnly, Return, Stop,
4-
Store, Sub, TypedNode,
3+
Add, Bool, CProj, Cast, Constant, Div, If, Load, Minus, MinusF, Mul, Not, Phi, ReadOnly,
4+
Return, RoundF32, Sar, Shl, Shr, Stop, Store, Sub, TypedNode,
55
};
66
use crate::sea_of_nodes::nodes::node::{IfOp, Region};
77
use crate::sea_of_nodes::nodes::{BoolOp, Node, Nodes};
8-
use crate::sea_of_nodes::types::Ty;
8+
use crate::sea_of_nodes::types::{Ty, TyInt};
99

1010
impl Node {
1111
/// do not peephole directly returned values!
@@ -27,16 +27,23 @@ impl Node {
2727
TypedNode::Load(n) => n.idealize_load(sea),
2828
TypedNode::Store(n) => n.idealize_store(sea),
2929
TypedNode::Minus(n) => n.idealize_minus(sea),
30+
TypedNode::MinusF(n) => n.idealize_minusf(sea),
3031
TypedNode::Div(n) => n.idealize_div(sea),
3132
TypedNode::ReadOnly(n) => n.idealize_read_only(sea),
33+
TypedNode::RoundF32(n) => n.idealize_round_f32(sea),
34+
TypedNode::Shl(n) => n.idealize_shl(sea),
35+
TypedNode::Shr(n) => n.idealize_shr(sea),
36+
TypedNode::Sar(n) => n.idealize_sar(sea),
3237
TypedNode::Constant(_)
3338
| TypedNode::XCtrl(_)
3439
| TypedNode::Start(_)
3540
| TypedNode::Scope(_)
3641
| TypedNode::ScopeMin(_)
3742
| TypedNode::Struct(_)
3843
| TypedNode::New(_)
44+
| TypedNode::ToFloat(_)
3945
| TypedNode::Not(_) => None,
46+
TypedNode::Cfg(_) => unreachable!(),
4047
n => todo!("{n:?}"),
4148
}
4249
}
@@ -614,6 +621,15 @@ impl Minus {
614621
None
615622
}
616623
}
624+
impl MinusF {
625+
fn idealize_minusf(self, sea: &mut Nodes) -> Option<Node> {
626+
// -(-x) is x
627+
if let Some(m) = self.inputs(sea)[1]?.to_minus(sea) {
628+
return m.inputs(sea)[1];
629+
}
630+
None
631+
}
632+
}
617633

618634
impl Div {
619635
fn idealize_div(self, sea: &mut Nodes) -> Option<Node> {
@@ -637,6 +653,91 @@ impl ReadOnly {
637653
}
638654
}
639655

656+
impl RoundF32 {
657+
fn idealize_round_f32(self, sea: &mut Nodes) -> Option<Node> {
658+
let lhs = self.inputs(sea)[1].unwrap();
659+
660+
// RoundF32 of float
661+
if let Some(t) = lhs.ty(sea).and_then(Ty::to_float) {
662+
if t.sz() == 32 {
663+
return Some(lhs);
664+
}
665+
}
666+
None
667+
}
668+
}
669+
670+
impl Shl {
671+
fn idealize_shl(self, sea: &mut Nodes) -> Option<Node> {
672+
let lhs = self.inputs(sea)[1].unwrap();
673+
let rhs = self.inputs(sea)[1].unwrap();
674+
675+
if let Some(shl) = rhs.ty(sea).and_then(Ty::to_int) {
676+
if let Some(i) = shl.value() {
677+
// Shl of 0.
678+
if i & 63 == 0 {
679+
return Some(lhs);
680+
}
681+
// (x + c) << i => (x << i) + (c << i)
682+
if let Some(add) = lhs.to_add(sea) {
683+
if let Some(c) = add.add_dep(self, sea).inputs(sea)[2]
684+
.unwrap()
685+
.ty(sea)
686+
.and_then(Ty::to_int)
687+
{
688+
if let Some(c) = c.value() {
689+
if c != 0 {
690+
let sum = c << i;
691+
if i32::try_from(sum).is_ok() {
692+
return Some(*Add::new(
693+
Shl::new(add.inputs(sea)[1].unwrap(), Some(rhs), sea)
694+
.peephole(sea),
695+
Constant::new(*sea.types.get_int(sum), sea).peephole(sea),
696+
sea,
697+
));
698+
}
699+
}
700+
}
701+
}
702+
}
703+
}
704+
}
705+
// TODO: x << 3 << (y ? 1 : 2) ==> x << (y ? 4 : 5)
706+
None
707+
}
708+
}
709+
710+
impl Shr {
711+
fn idealize_shr(self, sea: &mut Nodes) -> Option<Node> {
712+
let lhs = self.inputs(sea)[1].unwrap();
713+
let rhs = self.inputs(sea)[1].unwrap();
714+
715+
// Shr of 0.
716+
if let Some(shr) = rhs.ty(sea).and_then(Ty::to_int).and_then(TyInt::value) {
717+
if shr & 63 == 0 {
718+
return Some(lhs);
719+
}
720+
}
721+
// TODO: x >>> 3 >>> (y ? 1 : 2) ==> x >>> (y ? 4 : 5)
722+
None
723+
}
724+
}
725+
impl Sar {
726+
fn idealize_sar(self, sea: &mut Nodes) -> Option<Node> {
727+
let lhs = self.inputs(sea)[1].unwrap();
728+
let rhs = self.inputs(sea)[1].unwrap();
729+
730+
// Sar of 0.
731+
if let Some(shr) = rhs.ty(sea).and_then(Ty::to_int).and_then(TyInt::value) {
732+
if shr & 63 == 0 {
733+
return Some(lhs);
734+
}
735+
}
736+
// TODO: x >> 3 >> (y ? 1 : 2) ==> x >> (y ? 4 : 5)
737+
None
738+
}
739+
}
740+
640741
impl Node {
641742
fn find_dead_input(self, sea: &Nodes) -> Option<usize> {
642743
(1..self.inputs(sea).len())

0 commit comments

Comments
 (0)