@@ -7472,7 +7472,6 @@ void Compiler::fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCa
7472
7472
//------------------------------------------------------------------------------
7473
7473
// fgAssignRecursiveCallArgToCallerParam : Assign argument to a recursive call to the corresponding caller parameter.
7474
7474
//
7475
- //
7476
7475
// Arguments:
7477
7476
// arg - argument to assign
7478
7477
// late - whether to use early or late arg
@@ -13892,13 +13891,70 @@ PhaseStatus Compiler::fgMorphBlocks()
13892
13891
13893
13892
// Morph all blocks.
13894
13893
//
13895
- // Note morph can add blocks downstream from the current block,
13896
- // and alter (but not null out) the current block's bbNext;
13897
- // this iterator ensures they all get visited.
13898
- //
13899
- for (BasicBlock* block : Blocks())
13894
+ if (!optLocalAssertionProp)
13900
13895
{
13901
- fgMorphBlock(block);
13896
+ // If we aren't optimizing, we just morph in normal bbNext order.
13897
+ //
13898
+ // Note morph can add blocks downstream from the current block,
13899
+ // and alter (but not null out) the current block's bbNext;
13900
+ // this iterator ensures they all get visited.
13901
+ //
13902
+ for (BasicBlock* block : Blocks())
13903
+ {
13904
+ fgMorphBlock(block);
13905
+ }
13906
+ }
13907
+ else
13908
+ {
13909
+ // We are optimizing. Process in RPO.
13910
+ //
13911
+ fgRenumberBlocks();
13912
+ EnsureBasicBlockEpoch();
13913
+ fgComputeEnterBlocksSet();
13914
+ fgDfsReversePostorder();
13915
+
13916
+ // Disallow general creation of new blocks or edges as it
13917
+ // would invalidate RPO.
13918
+ //
13919
+ // Removal of edges, or altering dup counts, is OK.
13920
+ //
13921
+ INDEBUG(fgSafeBasicBlockCreation = false;);
13922
+ INDEBUG(fgSafeFlowEdgeCreation = false;);
13923
+
13924
+ // Allow edge creation to genReturnBB (target of return merging)
13925
+ // and the scratch block successor (target for tail call to loop).
13926
+ // This will also disallow dataflow into these blocks.
13927
+ //
13928
+ if (genReturnBB != nullptr)
13929
+ {
13930
+ genReturnBB->bbFlags |= BBF_CAN_ADD_PRED;
13931
+ }
13932
+ if (fgFirstBBisScratch())
13933
+ {
13934
+ fgFirstBB->Next()->bbFlags |= BBF_CAN_ADD_PRED;
13935
+ }
13936
+
13937
+ unsigned const bbNumMax = fgBBNumMax;
13938
+ for (unsigned i = 1; i <= bbNumMax; i++)
13939
+ {
13940
+ BasicBlock* const block = fgBBReversePostorder[i];
13941
+ fgMorphBlock(block);
13942
+ }
13943
+
13944
+ // Re-enable block and edge creation, and revoke
13945
+ // special treatment of genReturnBB and the "first" bb
13946
+ //
13947
+ INDEBUG(fgSafeBasicBlockCreation = true;);
13948
+ INDEBUG(fgSafeFlowEdgeCreation = true;);
13949
+
13950
+ if (genReturnBB != nullptr)
13951
+ {
13952
+ genReturnBB->bbFlags &= ~BBF_CAN_ADD_PRED;
13953
+ }
13954
+ if (fgFirstBBisScratch())
13955
+ {
13956
+ fgFirstBB->Next()->bbFlags &= ~BBF_CAN_ADD_PRED;
13957
+ }
13902
13958
}
13903
13959
13904
13960
// Under OSR, we no longer need to specially protect the original method entry
0 commit comments