1717use crate :: expr:: TypeCheck ;
1818use crate :: expr:: nodes:: * ;
1919use baa:: {
20- ArrayOps , BitVecValue , BitVecValueIndex , BitVecValueRef , IndexToRef , SparseArrayValue , Value ,
20+ ArrayOps , BitVecOps , BitVecValue , BitVecValueIndex , BitVecValueRef , IndexToRef ,
21+ SparseArrayValue , Value ,
2122} ;
2223use rustc_hash:: FxBuildHasher ;
2324use std:: borrow:: Borrow ;
@@ -53,18 +54,20 @@ pub struct ExprRef(NonZeroU32);
5354impl Debug for ExprRef {
5455 fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
5556 // we need a custom implementation in order to show the zero based index
56- write ! ( f, "ExprRef({})" , self . index( ) )
57+ let index: usize = ( * self ) . into ( ) ;
58+ write ! ( f, "ExprRef({})" , index)
5759 }
5860}
5961
60- impl ExprRef {
61- // TODO: reduce visibility to pub(crate)
62- pub fn from_index ( index : usize ) -> Self {
63- ExprRef ( NonZeroU32 :: new ( ( index + 1 ) as u32 ) . unwrap ( ) )
62+ impl From < ExprRef > for usize {
63+ fn from ( value : ExprRef ) -> Self {
64+ ( value. 0 . get ( ) - 1 ) as usize
6465 }
66+ }
6567
66- pub ( crate ) fn index ( & self ) -> usize {
67- ( self . 0 . get ( ) - 1 ) as usize
68+ impl From < usize > for ExprRef {
69+ fn from ( index : usize ) -> Self {
70+ ExprRef ( NonZeroU32 :: new ( ( index + 1 ) as u32 ) . unwrap ( ) )
6871 }
6972}
7073
@@ -87,8 +90,8 @@ impl Default for Context {
8790 strings : Default :: default ( ) ,
8891 exprs : Default :: default ( ) ,
8992 values : Default :: default ( ) ,
90- true_expr_ref : ExprRef :: from_index ( 0 ) ,
91- false_expr_ref : ExprRef :: from_index ( 0 ) ,
93+ true_expr_ref : 0 . into ( ) , // only a placeholder!
94+ false_expr_ref : 0 . into ( ) , // only a placeholder!
9295 } ;
9396 // create valid cached expressions
9497 out. false_expr_ref = out. zero ( 1 ) ;
@@ -105,7 +108,7 @@ impl Context {
105108
106109 pub ( crate ) fn add_expr ( & mut self , value : Expr ) -> ExprRef {
107110 let ( index, _) = self . exprs . insert_full ( value) ;
108- ExprRef :: from_index ( index)
111+ index. into ( )
109112 }
110113
111114 pub fn string ( & mut self , value : std:: borrow:: Cow < str > ) -> StringRef {
@@ -127,7 +130,7 @@ impl Index<ExprRef> for Context {
127130
128131 fn index ( & self , index : ExprRef ) -> & Self :: Output {
129132 self . exprs
130- . get_index ( index. index ( ) )
133+ . get_index ( index. into ( ) )
131134 . expect ( "Invalid ExprRef!" )
132135 }
133136}
@@ -142,21 +145,15 @@ impl Index<StringRef> for Context {
142145 }
143146}
144147
148+ /// Convenience methods to inspect IR nodes.
145149impl Context {
146- /// Returns the number of interned expressions in this context.
147- pub fn num_exprs ( & self ) -> usize {
148- self . exprs . len ( )
149- }
150-
151- /// Returns a reference to the expression for the given reference.
152- /// Panics if the reference is invalid (use indices in range 0..num_exprs()).
153- pub fn get_expr ( & self , r : ExprRef ) -> & Expr {
154- & self [ r]
155- }
156-
157- /// Returns the zero-based intern index of the given expression reference.
158- pub fn expr_index ( & self , r : ExprRef ) -> usize {
159- r. index ( )
150+ /// Returns whether `e` represents a bit vector literal `0` of any width.
151+ pub fn is_zero ( & self , e : ExprRef ) -> bool {
152+ if let Expr :: BVLiteral ( value) = self [ e] {
153+ value. get ( self ) . is_zero ( )
154+ } else {
155+ false
156+ }
160157 }
161158}
162159
@@ -247,6 +244,11 @@ impl Context {
247244 pub fn ones ( & mut self , width : WidthInt ) -> ExprRef {
248245 self . bv_lit ( & BitVecValue :: ones ( width) )
249246 }
247+
248+ pub fn distinct ( & mut self , a : ExprRef , b : ExprRef ) -> ExprRef {
249+ let is_eq = self . equal ( a, b) ;
250+ self . not ( is_eq)
251+ }
250252 pub fn equal ( & mut self , a : ExprRef , b : ExprRef ) -> ExprRef {
251253 debug_assert_eq ! ( a. get_type( self ) , b. get_type( self ) ) ;
252254 if a. get_type ( self ) . is_bit_vector ( ) {
@@ -311,6 +313,20 @@ impl Context {
311313 debug_assert_eq ! ( a. get_bv_type( self ) . unwrap( ) , b. get_bv_type( self ) . unwrap( ) ) ;
312314 self . add_expr ( Expr :: BVXor ( a, b, b. get_bv_type ( self ) . unwrap ( ) ) )
313315 }
316+
317+ pub fn xor3 ( & mut self , a : ExprRef , b : ExprRef , c : ExprRef ) -> ExprRef {
318+ let x = self . xor ( a, b) ;
319+ self . xor ( x, c)
320+ }
321+
322+ pub fn majority ( & mut self , a : ExprRef , b : ExprRef , c : ExprRef ) -> ExprRef {
323+ let a_and_b = self . and ( a, b) ;
324+ let a_and_c = self . and ( a, c) ;
325+ let b_and_c = self . and ( b, c) ;
326+ let x = self . or ( a_and_b, a_and_c) ;
327+ self . or ( x, b_and_c)
328+ }
329+
314330 pub fn shift_left ( & mut self , a : ExprRef , b : ExprRef ) -> ExprRef {
315331 debug_assert_eq ! ( a. get_bv_type( self ) . unwrap( ) , b. get_bv_type( self ) . unwrap( ) ) ;
316332 self . add_expr ( Expr :: BVShiftLeft ( a, b, b. get_bv_type ( self ) . unwrap ( ) ) )
@@ -515,6 +531,12 @@ impl<'a> Builder<'a> {
515531 pub fn xor ( & self , a : ExprRef , b : ExprRef ) -> ExprRef {
516532 self . ctx . borrow_mut ( ) . xor ( a, b)
517533 }
534+ pub fn xor3 ( & mut self , a : ExprRef , b : ExprRef , c : ExprRef ) -> ExprRef {
535+ self . ctx . borrow_mut ( ) . xor3 ( a, b, c)
536+ }
537+ pub fn majority ( & mut self , a : ExprRef , b : ExprRef , c : ExprRef ) -> ExprRef {
538+ self . ctx . borrow_mut ( ) . majority ( a, b, c)
539+ }
518540 pub fn shift_left ( & self , a : ExprRef , b : ExprRef ) -> ExprRef {
519541 self . ctx . borrow_mut ( ) . shift_left ( a, b)
520542 }
0 commit comments