@@ -13619,13 +13619,12 @@ void Compiler::fgMorphStmtBlockOps(BasicBlock* block, Statement* stmt)
13619
13619
}
13620
13620
}
13621
13621
13622
- /*****************************************************************************
13623
- *
13624
- * Morph the statements of the given block.
13625
- * This function should be called just once for a block. Use fgMorphBlockStmt()
13626
- * for reentrant calls.
13627
- */
13628
-
13622
+ //------------------------------------------------------------------------
13623
+ // fgMorphStmts: Morph all statements in a block
13624
+ //
13625
+ // Arguments:
13626
+ // block - block in question
13627
+ //
13629
13628
void Compiler::fgMorphStmts(BasicBlock* block)
13630
13629
{
13631
13630
fgRemoveRestOfBlock = false;
@@ -13809,36 +13808,65 @@ void Compiler::fgMorphStmts(BasicBlock* block)
13809
13808
fgRemoveRestOfBlock = false;
13810
13809
}
13811
13810
13812
- /*****************************************************************************
13813
- *
13814
- * Morph the blocks of the method.
13815
- * Returns true if the basic block list is modified.
13816
- * This function should be called just once.
13817
- */
13818
-
13819
- void Compiler::fgMorphBlocks()
13811
+ //------------------------------------------------------------------------
13812
+ // fgMorphBlock: Morph a basic block
13813
+ //
13814
+ // Arguments:
13815
+ // block - block in question
13816
+ //
13817
+ void Compiler::fgMorphBlock(BasicBlock* block)
13820
13818
{
13821
- #ifdef DEBUG
13822
- if (verbose)
13819
+ JITDUMP("\nMorphing " FMT_BB "\n", block->bbNum);
13820
+
13821
+ if (optLocalAssertionProp)
13823
13822
{
13824
- printf("\n*************** In fgMorphBlocks()\n");
13823
+ // Clear out any currently recorded assertion candidates
13824
+ // before processing each basic block,
13825
+ // also we must handle QMARK-COLON specially
13826
+ //
13827
+ optAssertionReset(0);
13825
13828
}
13826
- #endif
13827
13829
13828
- /* Since fgMorphTree can be called after various optimizations to re-arrange
13829
- * the nodes we need a global flag to signal if we are during the one-pass
13830
- * global morphing */
13830
+ // Make the current basic block address available globally.
13831
+ compCurBB = block;
13831
13832
13832
- fgGlobalMorph = true;
13833
+ // Process all statement trees in the basic block.
13834
+ fgMorphStmts(block);
13835
+
13836
+ // Do we need to merge the result of this block into a single return block?
13837
+ if (block->KindIs(BBJ_RETURN) && ((block->bbFlags & BBF_HAS_JMP) == 0))
13838
+ {
13839
+ if ((genReturnBB != nullptr) && (genReturnBB != block))
13840
+ {
13841
+ fgMergeBlockReturn(block);
13842
+ }
13843
+ }
13833
13844
13845
+ compCurBB = nullptr;
13846
+ }
13847
+
13848
+ //------------------------------------------------------------------------
13849
+ // fgMorphBlocks: Morph all blocks in the method
13850
+ //
13851
+ // Returns:
13852
+ // Suitable phase status.
13853
+ //
13854
+ // Note:
13855
+ // Morph almost always changes IR, so we don't actually bother to
13856
+ // track if it made any changees.
13857
+ //
13858
+ PhaseStatus Compiler::fgMorphBlocks()
13859
+ {
13860
+ // This is the one and only global morph phase
13834
13861
//
13862
+ fgGlobalMorph = true;
13863
+
13835
13864
// Local assertion prop is enabled if we are optimized
13836
13865
//
13837
13866
optLocalAssertionProp = opts.OptimizationEnabled();
13838
13867
13839
13868
if (optLocalAssertionProp)
13840
13869
{
13841
- //
13842
13870
// Initialize for local assertion prop
13843
13871
//
13844
13872
optAssertionInit(true);
@@ -13862,53 +13890,16 @@ void Compiler::fgMorphBlocks()
13862
13890
fgEnsureFirstBBisScratch();
13863
13891
}
13864
13892
13865
- /*-------------------------------------------------------------------------
13866
- * Process all basic blocks in the function
13867
- */
13868
-
13869
- BasicBlock* block = fgFirstBB;
13870
- noway_assert(block);
13871
-
13872
- do
13893
+ // Morph all blocks.
13894
+ //
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())
13873
13900
{
13874
- #ifdef DEBUG
13875
- if (verbose)
13876
- {
13877
- printf("\nMorphing " FMT_BB " of '%s'\n", block->bbNum, info.compFullName);
13878
- }
13879
- #endif
13880
-
13881
- if (optLocalAssertionProp)
13882
- {
13883
- //
13884
- // Clear out any currently recorded assertion candidates
13885
- // before processing each basic block,
13886
- // also we must handle QMARK-COLON specially
13887
- //
13888
- optAssertionReset(0);
13889
- }
13890
-
13891
- // Make the current basic block address available globally.
13892
- compCurBB = block;
13893
-
13894
- // Process all statement trees in the basic block.
13895
- fgMorphStmts(block);
13896
-
13897
- // Do we need to merge the result of this block into a single return block?
13898
- if (block->KindIs(BBJ_RETURN) && ((block->bbFlags & BBF_HAS_JMP) == 0))
13899
- {
13900
- if ((genReturnBB != nullptr) && (genReturnBB != block))
13901
- {
13902
- fgMergeBlockReturn(block);
13903
- }
13904
- }
13905
-
13906
- block = block->Next();
13907
- } while (block != nullptr);
13908
-
13909
- // We are done with the global morphing phase
13910
- fgGlobalMorph = false;
13911
- compCurBB = nullptr;
13901
+ fgMorphBlock(block);
13902
+ }
13912
13903
13913
13904
// Under OSR, we no longer need to specially protect the original method entry
13914
13905
//
@@ -13924,12 +13915,12 @@ void Compiler::fgMorphBlocks()
13924
13915
fgEntryBB = nullptr;
13925
13916
}
13926
13917
13927
- #ifdef DEBUG
13928
- if (verboseTrees)
13929
- {
13930
- fgDispBasicBlocks(true) ;
13931
- }
13932
- #endif
13918
+ // We are done with the global morphing phase
13919
+ //
13920
+ fgGlobalMorph = false;
13921
+ compCurBB = nullptr ;
13922
+
13923
+ return PhaseStatus::MODIFIED_EVERYTHING;
13933
13924
}
13934
13925
13935
13926
//------------------------------------------------------------------------
0 commit comments