@ -107,7 +107,6 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
IncludeNestedContainers ( loop ) ;
IncludeNestedContainers ( loop ) ;
// Try to extend the loop to reduce the number of exit points:
// Try to extend the loop to reduce the number of exit points:
ExtendLoop ( h , loop , out var exitPoint ) ;
ExtendLoop ( h , loop , out var exitPoint ) ;
IncludeUnreachablePredecessors ( loop ) ;
// Sort blocks in the loop in reverse post-order to make the output look a bit nicer.
// Sort blocks in the loop in reverse post-order to make the output look a bit nicer.
// (if the loop doesn't contain nested loops, this is a topological sort)
// (if the loop doesn't contain nested loops, this is a topological sort)
@ -115,7 +114,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
Debug . Assert ( loop [ 0 ] = = h ) ;
Debug . Assert ( loop [ 0 ] = = h ) ;
foreach ( var node in loop ) {
foreach ( var node in loop ) {
node . Visited = false ; // reset visited flag so that we can find outer loops
node . Visited = false ; // reset visited flag so that we can find outer loops
Debug . Assert ( h . Dominates ( node ) | | ! node . IsReachable , "The loop body must be dominated by the loop head" ) ;
Debug . Assert ( h . Dominates ( node ) , "The loop body must be dominated by the loop head" ) ;
}
}
ConstructLoop ( loop , exitPoint ) ;
ConstructLoop ( loop , exitPoint ) ;
}
}
@ -150,7 +149,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
// (the entry-point itself doesn't have a CFG node, because it's newly created by this transform)
// (the entry-point itself doesn't have a CFG node, because it's newly created by this transform)
for ( int i = 1 ; i < nestedContainer . Blocks . Count ; i + + ) {
for ( int i = 1 ; i < nestedContainer . Blocks . Count ; i + + ) {
var node = context . ControlFlowGraph . GetNode ( nestedContainer . Blocks [ i ] ) ;
var node = context . ControlFlowGraph . GetNode ( nestedContainer . Blocks [ i ] ) ;
Debug . Assert ( loop [ 0 ] . Dominates ( node ) | | ! node . IsReachable ) ;
Debug . Assert ( loop [ 0 ] . Dominates ( node ) ) ;
if ( ! node . Visited ) {
if ( ! node . Visited ) {
node . Visited = true ;
node . Visited = true ;
loop . Add ( node ) ;
loop . Add ( node ) ;
@ -602,30 +601,6 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
}
#endregion
#endregion
/// <summary>
/// While our normal dominance logic ensures the loop has just a single reachable entry point,
/// it's possible that there are unreachable code blocks that have jumps into the loop.
/// We'll also include those into the loop.
///
/// Requires and maintains the invariant that a node is marked as visited iff it is contained in the loop.
/// </summary>
private void IncludeUnreachablePredecessors ( List < ControlFlowNode > loop )
{
for ( int i = 1 ; i < loop . Count ; i + + ) {
Debug . Assert ( loop [ i ] . Visited ) ;
foreach ( var pred in loop [ i ] . Predecessors ) {
if ( ! pred . Visited ) {
if ( pred . IsReachable ) {
Debug . Fail ( "All jumps into the loop body should go through the entry point" ) ;
} else {
pred . Visited = true ;
loop . Add ( pred ) ;
}
}
}
}
}
/// <summary>
/// <summary>
/// Move the blocks associated with the loop into a new block container.
/// Move the blocks associated with the loop into a new block container.
/// </summary>
/// </summary>
@ -708,7 +683,6 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
}
exitPoint = null ;
exitPoint = null ;
}
}
IncludeUnreachablePredecessors ( nodesInSwitch ) ;
context . Step ( "Create BlockContainer for switch" , switchInst ) ;
context . Step ( "Create BlockContainer for switch" , switchInst ) ;
// Sort blocks in the loop in reverse post-order to make the output look a bit nicer.
// Sort blocks in the loop in reverse post-order to make the output look a bit nicer.
@ -717,7 +691,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
Debug . Assert ( nodesInSwitch [ 0 ] = = h ) ;
Debug . Assert ( nodesInSwitch [ 0 ] = = h ) ;
foreach ( var node in nodesInSwitch ) {
foreach ( var node in nodesInSwitch ) {
node . Visited = false ; // reset visited flag so that we can find outer loops
node . Visited = false ; // reset visited flag so that we can find outer loops
Debug . Assert ( h . Dominates ( node ) | | ! node . IsReachable , "The switch body must be dominated by the switch head" ) ;
Debug . Assert ( h . Dominates ( node ) , "The switch body must be dominated by the switch head" ) ;
}
}
BlockContainer switchContainer = new BlockContainer ( ContainerKind . Switch ) ;
BlockContainer switchContainer = new BlockContainer ( ContainerKind . Switch ) ;