11//! High-level intermediate representation effects.
22
33// TODO(Jacob): Replace Effect with EffectSet and EffectPair with Effect
4- //
54
65#![ allow( non_upper_case_globals) ]
76use crate :: hir:: { PtrPrintMap } ;
@@ -58,25 +57,22 @@ pub struct EffectPrinter<'a> {
5857impl < ' a > std:: fmt:: Display for EffectPrinter < ' a > {
5958 fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
6059 let effect = self . inner ;
61- // If there's an exact match, write and return
62- for ( name, pattern) in bits:: AllBitPatterns {
63- if effect. bits == pattern {
64- write ! ( f, "{name}" ) ?;
65- return Ok ( ( ) ) ;
66- }
67- }
68- // Otherwise, find the most descriptive sub-effect write it, and mask out the handled bits.
69- // Most descriptive means "highest number of bits set while remaining fully contained within `effect`"
70- debug_assert ! ( bits:: AllBitPatterns . is_sorted_by( |( _, left) , ( _, right) | left > right) ) ;
7160 let mut bits = effect. bits ;
7261 let mut sep = "" ;
62+ // First, make sure patterns are sorted from higher order bits to lower order.
63+ // For each match where `bits` contains the pattern, we mask off the matched bits
64+ // and continue searching for matches until bits == 0.
65+ // Our first match could be exact and may not require a separator, but all subsequent
66+ // matches do.
67+ debug_assert ! ( bits:: AllBitPatterns . is_sorted_by( |( _, left) , ( _, right) | left > right) ) ;
7368 for ( name, pattern) in bits:: AllBitPatterns {
74- if bits == 0 { break ; }
7569 if ( bits & pattern) == pattern {
7670 write ! ( f, "{sep}{name}" ) ?;
7771 sep = "|" ;
7872 bits &= !pattern;
7973 }
74+ // The `sep != ""` check allows us to handle the effects::None case gracefully.
75+ if ( bits == 0 ) & ( sep != "" ) { break ; }
8076 }
8177 debug_assert_eq ! ( bits, 0 , "Should have eliminated all bits by iterating over all patterns" ) ;
8278 Ok ( ( ) )
@@ -89,6 +85,7 @@ impl std::fmt::Display for Effect {
8985 }
9086}
9187
88+ // TODO(Jacob): Modify union and effect to work on an arbitrary number of args
9289impl Effect {
9390 const fn from_bits ( bits : EffectBits ) -> Effect {
9491 Effect { bits }
@@ -116,7 +113,7 @@ impl Effect {
116113 }
117114
118115 pub fn overlaps ( & self , other : Effect ) -> bool {
119- !self . intersect ( other) . bit_equal ( effects:: None )
116+ !self . intersect ( other) . bit_equal ( effects:: Empty )
120117 }
121118
122119 pub fn print ( self , ptr_map : & PtrPrintMap ) -> EffectPrinter < ' _ > {
@@ -145,24 +142,22 @@ mod tests {
145142
146143 #[ test]
147144 fn none_is_subeffect_of_everything ( ) {
148- assert_subeffect ( effects:: None , effects:: None ) ;
149- assert_subeffect ( effects:: None , effects:: Any ) ;
150- assert_subeffect ( effects:: None , effects:: World ) ;
151- assert_subeffect ( effects:: None , effects:: Frame ) ;
152- assert_subeffect ( effects:: None , effects:: Other ) ;
153- assert_subeffect ( effects:: None , effects:: Stack ) ;
154- assert_subeffect ( effects:: None , effects:: Locals ) ;
155- assert_subeffect ( effects:: None , effects:: PC ) ;
145+ assert_subeffect ( effects:: Empty , effects:: Empty ) ;
146+ assert_subeffect ( effects:: Empty , effects:: Any ) ;
147+ assert_subeffect ( effects:: Empty , effects:: Control ) ;
148+ assert_subeffect ( effects:: Empty , effects:: Frame ) ;
149+ assert_subeffect ( effects:: Empty , effects:: Stack ) ;
150+ assert_subeffect ( effects:: Empty , effects:: Locals ) ;
151+ assert_subeffect ( effects:: Empty , effects:: Allocator ) ;
156152 }
157153
158154 #[ test]
159155 fn everything_is_subeffect_of_any ( ) {
160- assert_subeffect ( effects:: None , effects:: Any ) ;
156+ assert_subeffect ( effects:: Empty , effects:: Any ) ;
161157 assert_subeffect ( effects:: Any , effects:: Any ) ;
162- assert_subeffect ( effects:: World , effects:: Any ) ;
158+ assert_subeffect ( effects:: Control , effects:: Any ) ;
163159 assert_subeffect ( effects:: Frame , effects:: Any ) ;
164- assert_subeffect ( effects:: Other , effects:: Any ) ;
165- assert_subeffect ( effects:: Stack , effects:: Any ) ;
160+ assert_subeffect ( effects:: Memory , effects:: Any ) ;
166161 assert_subeffect ( effects:: Locals , effects:: Any ) ;
167162 assert_subeffect ( effects:: PC , effects:: Any ) ;
168163 }
@@ -173,7 +168,7 @@ mod tests {
173168 for i in [ 0 , 1 , 4 , 6 , 10 , 15 ] {
174169 let e = Effect :: from_bits ( i) ;
175170 // Testing on bottom, top, and some arbitrary element in the middle
176- assert_subeffect ( effects:: None , effects:: None . union ( e) ) ;
171+ assert_subeffect ( effects:: Empty , effects:: Empty . union ( e) ) ;
177172 assert_subeffect ( effects:: Any , effects:: Any . union ( e) ) ;
178173 assert_subeffect ( effects:: Frame , effects:: Frame . union ( e) ) ;
179174 }
@@ -185,7 +180,7 @@ mod tests {
185180 for i in [ 0 , 3 , 6 , 8 , 15 ] {
186181 let e = Effect :: from_bits ( i) ;
187182 // Testing on bottom, top, and some arbitrary element in the middle
188- assert_subeffect ( effects:: None . intersect ( e) , effects:: None ) ;
183+ assert_subeffect ( effects:: Empty . intersect ( e) , effects:: Empty ) ;
189184 assert_subeffect ( effects:: Any . intersect ( e) , effects:: Any ) ;
190185 assert_subeffect ( effects:: Frame . intersect ( e) , effects:: Frame ) ;
191186 }
@@ -194,8 +189,8 @@ mod tests {
194189 #[ test]
195190 fn self_is_included ( ) {
196191 assert ! ( effects:: Stack . includes( effects:: Stack ) ) ;
197- assert ! ( effects:: Other . includes( effects:: Other ) ) ;
198- assert ! ( effects:: Stack . includes( effects:: Stack ) ) ;
192+ assert ! ( effects:: Any . includes( effects:: Any ) ) ;
193+ assert ! ( effects:: Empty . includes( effects:: Empty ) ) ;
199194 }
200195
201196 #[ test]
@@ -212,29 +207,28 @@ mod tests {
212207 }
213208
214209 #[ test]
215- fn world_includes_other ( ) {
216- assert_subeffect ( effects:: Other , effects:: World ) ;
217- }
218-
219- #[ test]
220- fn any_includes_world_and_frame ( ) {
221- assert_subeffect ( effects:: World , effects:: Any ) ;
210+ fn any_includes_some_subeffects ( ) {
211+ assert_subeffect ( effects:: Allocator , effects:: Any ) ;
222212 assert_subeffect ( effects:: Frame , effects:: Any ) ;
213+ assert_subeffect ( effects:: Memory , effects:: Any ) ;
223214 }
224215
225216 #[ test]
226217 fn display_exact_bits_match ( ) {
227- assert_eq ! ( format!( "{}" , effects:: None ) , "None " ) ;
218+ assert_eq ! ( format!( "{}" , effects:: Empty ) , "Empty " ) ;
228219 assert_eq ! ( format!( "{}" , effects:: PC ) , "PC" ) ;
229- assert_eq ! ( format!( "{}" , effects:: Other ) , "Other" ) ;
220+ assert_eq ! ( format!( "{}" , effects:: Any ) , "Any" ) ;
221+ assert_eq ! ( format!( "{}" , effects:: Frame ) , "Frame" ) ;
222+ assert_eq ! ( format!( "{}" , effects:: Stack . union ( effects:: Locals . union ( effects:: PC ) ) ) , "Frame" ) ;
230223 }
231224
232- // TODO(Jacob): Figure out why these last two comments cause test failures
233225 #[ test]
234226 fn display_multiple_bits ( ) {
235- assert_eq ! ( format! ( "{}" , effects:: Frame ) , "Frame" ) ;
227+ let union = effects:: Stack . union ( effects :: Locals ) ;
236228 assert_eq ! ( format!( "{}" , effects:: Stack . union ( effects:: Locals . union ( effects:: PC ) ) ) , "Frame" ) ;
237- // assert_eq!(format!("{}", effects::Stack.union(effects::Locals)), "Locals|Stack");
238- // assert_eq!(format!("{}", effects::Any), "Any");
229+ println ! ( "{}" , union ) ;
230+ println ! ( "{}" , effects:: Stack . union ( effects:: Locals . union ( effects:: PC ) ) ) ;
231+ assert_eq ! ( format!( "{}" , effects:: Stack . union ( effects:: Locals ) ) , "Stack|Locals" ) ;
232+ assert_eq ! ( format!( "{}" , effects:: PC . union ( effects:: Allocator ) ) , "PC|Allocator" ) ;
239233 }
240234}
0 commit comments