55
66//! Fast postorder computation.
77
8- use crate :: { Block , VecExt } ;
8+ use crate :: { Block , RegAllocError , VecExt } ;
99use alloc:: vec:: Vec ;
1010use smallvec:: { smallvec, SmallVec } ;
1111
@@ -15,7 +15,7 @@ pub fn calculate<'a, SuccFn: Fn(Block) -> &'a [Block]>(
1515 visited_scratch : & mut Vec < bool > ,
1616 out : & mut Vec < Block > ,
1717 succ_blocks : SuccFn ,
18- ) {
18+ ) -> Result < ( ) , RegAllocError > {
1919 // State: visited-block map, and explicit DFS stack.
2020 struct State < ' a > {
2121 block : Block ,
@@ -26,7 +26,10 @@ pub fn calculate<'a, SuccFn: Fn(Block) -> &'a [Block]>(
2626 let mut stack: SmallVec < [ State ; 64 ] > = smallvec ! [ ] ;
2727 out. clear ( ) ;
2828
29- visited[ entry. index ( ) ] = true ;
29+ let entry_visit = visited
30+ . get_mut ( entry. index ( ) )
31+ . ok_or ( RegAllocError :: BB ( entry) ) ?;
32+ * entry_visit = true ;
3033 stack. push ( State {
3134 block : entry,
3235 succs : succ_blocks ( entry) . iter ( ) ,
@@ -35,8 +38,11 @@ pub fn calculate<'a, SuccFn: Fn(Block) -> &'a [Block]>(
3538 while let Some ( ref mut state) = stack. last_mut ( ) {
3639 // Perform one action: push to new succ, skip an already-visited succ, or pop.
3740 if let Some ( & succ) = state. succs . next ( ) {
38- if !visited[ succ. index ( ) ] {
39- visited[ succ. index ( ) ] = true ;
41+ let succ_visit = visited
42+ . get_mut ( succ. index ( ) )
43+ . ok_or ( RegAllocError :: BB ( succ) ) ?;
44+ if !* succ_visit {
45+ * succ_visit = true ;
4046 stack. push ( State {
4147 block : succ,
4248 succs : succ_blocks ( succ) . iter ( ) ,
@@ -47,4 +53,5 @@ pub fn calculate<'a, SuccFn: Fn(Block) -> &'a [Block]>(
4753 stack. pop ( ) ;
4854 }
4955 }
56+ Ok ( ( ) )
5057}
0 commit comments