1
1
mod builder;
2
2
mod dot;
3
3
4
- use itertools:: Itertools ;
5
4
use oxc_span:: CompactStr ;
6
5
use oxc_syntax:: operator:: {
7
6
AssignmentOperator , BinaryOperator , LogicalOperator , UnaryOperator , UpdateOperator ,
8
7
} ;
9
8
use petgraph:: {
10
9
stable_graph:: NodeIndex ,
11
- visit:: { depth_first_search, Dfs , DfsEvent , Walker } ,
10
+ visit:: { depth_first_search, Control , DfsEvent } ,
12
11
Graph ,
13
12
} ;
14
13
@@ -192,19 +191,28 @@ impl ControlFlowGraph {
192
191
}
193
192
194
193
pub fn is_reachabale ( & self , from : BasicBlockId , to : BasicBlockId ) -> bool {
194
+ if from == to {
195
+ return true ;
196
+ }
195
197
let graph = & self . graph ;
196
- let mut dfs = Dfs :: empty ( graph) ;
197
- dfs. reset ( graph) ;
198
- dfs. move_to ( from) ;
199
- dfs. iter ( graph)
200
- . take_while_inclusive ( |it| {
201
- !self
202
- . basic_block ( * it)
203
- . instructions ( )
204
- . iter ( )
205
- . any ( |it| matches ! ( it, Instruction { kind: InstructionKind :: Unreachable , .. } ) )
206
- } )
207
- . any ( |x| x == to)
198
+ depth_first_search ( & self . graph , Some ( from) , |event| match event {
199
+ DfsEvent :: TreeEdge ( a, b) => {
200
+ let unreachable = graph. edges_connecting ( a, b) . all ( |edge| {
201
+ matches ! ( edge. weight( ) , EdgeType :: NewFunction | EdgeType :: Unreachable )
202
+ } ) ;
203
+
204
+ if unreachable {
205
+ Control :: Prune
206
+ } else if b == to {
207
+ return Control :: Break ( true ) ;
208
+ } else {
209
+ Control :: Continue
210
+ }
211
+ }
212
+ _ => Control :: Continue ,
213
+ } )
214
+ . break_value ( )
215
+ . unwrap_or ( false )
208
216
}
209
217
210
218
pub fn is_cyclic ( & self , node : BasicBlockId ) -> bool {
@@ -214,6 +222,18 @@ impl ControlFlowGraph {
214
222
} )
215
223
. is_err ( )
216
224
}
225
+
226
+ pub fn has_conditional_path ( & self , from : BasicBlockId , to : BasicBlockId ) -> bool {
227
+ let graph = & self . graph ;
228
+ // All nodes should be able to reach the `to` node, Otherwise we have a conditional/branching flow.
229
+ petgraph:: algo:: dijkstra ( graph, from, Some ( to) , |e| match e. weight ( ) {
230
+ EdgeType :: NewFunction => 1 ,
231
+ EdgeType :: Jump | EdgeType :: Unreachable | EdgeType :: Backedge | EdgeType :: Normal => 0 ,
232
+ } )
233
+ . into_iter ( )
234
+ . filter ( |( _, val) | * val == 0 )
235
+ . any ( |( f, _) | !self . is_reachabale ( f, to) )
236
+ }
217
237
}
218
238
219
239
pub struct PreservedExpressionState {
0 commit comments