11use crate :: datastructures:: id:: Id ;
22use 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} ;
66use crate :: sea_of_nodes:: nodes:: node:: { IfOp , Region } ;
77use 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
1010impl 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
618634impl 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+
640741impl Node {
641742 fn find_dead_input ( self , sea : & Nodes ) -> Option < usize > {
642743 ( 1 ..self . inputs ( sea) . len ( ) )
0 commit comments