1- // Copyright (c) 2014 Daniel Grunwald
1+ // Copyright (c) 2014 Daniel Grunwald
22//
33// Permission is hereby granted, free of charge, to any person obtaining a copy of this
44// software and associated documentation files (the "Software"), to deal in the Software
@@ -137,7 +137,7 @@ void InlineVariableInReturnBlock(Block block, ILTransformContext context)
137137
138138 void SimplifyBranchChains ( ILFunction function , ILTransformContext context )
139139 {
140- List < ( BlockContainer , Block ) > blocksToAdd = new List < ( BlockContainer , Block ) > ( ) ;
140+ List < ( Block Block , BlockContainer TargetContainer ) > blocksToMove = new List < ( Block , BlockContainer ) > ( ) ;
141141 HashSet < Block > visitedBlocks = new HashSet < Block > ( ) ;
142142 foreach ( var branch in function . Descendants . OfType < Branch > ( ) )
143143 {
@@ -167,19 +167,17 @@ void SimplifyBranchChains(ILFunction function, ILTransformContext context)
167167 context . Step ( "Replace branch to return with return" , branch ) ;
168168 branch . ReplaceWith ( targetBlock . Instructions [ 0 ] . Clone ( ) ) ;
169169 }
170- else if ( branch . TargetContainer != branch . Ancestors . OfType < BlockContainer > ( ) . First ( ) )
170+ else if ( branch . TargetContainer != branch . Ancestors . OfType < BlockContainer > ( ) . First ( ) && targetBlock . IncomingEdgeCount == 1 )
171171 {
172172 // We don't want to always inline the return directly, because this
173173 // might force us to place the return within a loop, when it's better
174174 // placed outside.
175175 // But we do want to move the return block into the correct try-finally scope,
176176 // so that loop detection at least has the option to put it inside
177177 // the loop body.
178- context . Step ( "Copy return block into try block" , branch ) ;
179- Block blockCopy = ( Block ) branch . TargetBlock . Clone ( ) ;
178+ context . Step ( "Move return block into try block" , branch ) ;
180179 BlockContainer localContainer = branch . Ancestors . OfType < BlockContainer > ( ) . First ( ) ;
181- blocksToAdd . Add ( ( localContainer , blockCopy ) ) ;
182- branch . TargetBlock = blockCopy ;
180+ blocksToMove . Add ( ( targetBlock , localContainer ) ) ;
183181 }
184182 }
185183 else if ( targetBlock . Instructions . Count == 1 && targetBlock . Instructions [ 0 ] is Leave leave && leave . Value . MatchNop ( ) )
@@ -194,9 +192,10 @@ void SimplifyBranchChains(ILFunction function, ILTransformContext context)
194192 if ( targetBlock . IncomingEdgeCount == 0 )
195193 targetBlock . Instructions . Clear ( ) ; // mark the block for deletion
196194 }
197- foreach ( var ( container , block ) in blocksToAdd )
195+ foreach ( ( Block block , BlockContainer targetContainer ) in blocksToMove )
198196 {
199- container . Blocks . Add ( block ) ;
197+ block . Remove ( ) ;
198+ targetContainer . Blocks . Add ( block ) ;
200199 }
201200 }
202201
0 commit comments