Merge pull request #6721 from jashook/disable_jit32_tests
[platform/upstream/coreclr.git] / src / jit / ssabuilder.cpp
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 // ==++==
6 //
7
8 //
9
10 //
11 // ==--==
12
13 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
15 XX                                                                           XX
16 XX                                  SSA                                      XX
17 XX                                                                           XX
18 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
19 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
20 */
21
22 #include "jitpch.h"
23 #include "ssaconfig.h"
24 #include "ssarenamestate.h"
25 #include "ssabuilder.h"
26
27 namespace
28 {
29 /**
30  * Visits basic blocks in the depth first order and arranges them in the order of
31  * their DFS finish time.
32  *
33  * @param block The fgFirstBB or entry block.
34  * @param comp A pointer to compiler.
35  * @param visited In pointer initialized to false and of size at least fgMaxBBNum.
36  * @param count Out pointer for count of all nodes reachable by DFS.
37  * @param postOrder Out poitner to arrange the blocks and of size at least fgMaxBBNum.
38  */
39 static void TopologicalSortHelper(BasicBlock* block, Compiler* comp, bool* visited, int* count, BasicBlock** postOrder)
40 {
41     visited[block->bbNum] = true;
42
43     ArrayStack<BasicBlock*>      blocks(comp);
44     ArrayStack<AllSuccessorIter> iterators(comp);
45     ArrayStack<AllSuccessorIter> ends(comp);
46
47     // there are three stacks used here and all should be same height
48     // the first is for blocks
49     // the second is the iterator to keep track of what succ of the block we are looking at
50     // and the third is the end marker iterator
51     blocks.Push(block);
52     iterators.Push(block->GetAllSuccs(comp).begin());
53     ends.Push(block->GetAllSuccs(comp).end());
54
55     while (blocks.Height() > 0)
56     {
57         block = blocks.Top();
58
59 #ifdef DEBUG
60         if (comp->verboseSsa)
61         {
62             printf("[SsaBuilder::TopologicalSortHelper] Visiting BB%02u: ", block->bbNum);
63             printf("[");
64             unsigned numSucc = block->NumSucc(comp);
65             for (unsigned i = 0; i < numSucc; ++i)
66             {
67                 printf("BB%02u, ", block->GetSucc(i, comp)->bbNum);
68             }
69             EHSuccessorIter end = block->GetEHSuccs(comp).end();
70             for (EHSuccessorIter ehsi = block->GetEHSuccs(comp).begin(); ehsi != end; ++ehsi)
71             {
72                 printf("[EH]BB%02u, ", (*ehsi)->bbNum);
73             }
74             printf("]\n");
75         }
76 #endif
77
78         if (iterators.TopRef() != ends.TopRef())
79         {
80             // if the block on TOS still has unreached successors, visit them
81             AllSuccessorIter& iter = iterators.TopRef();
82             BasicBlock*       succ = *iter;
83             ++iter;
84             // push the child
85
86             if (!visited[succ->bbNum])
87             {
88                 blocks.Push(succ);
89                 iterators.Push(succ->GetAllSuccs(comp).begin());
90                 ends.Push(succ->GetAllSuccs(comp).end());
91                 visited[succ->bbNum] = true;
92             }
93         }
94         else
95         {
96             // all successors have been visited
97             blocks.Pop();
98             iterators.Pop();
99             ends.Pop();
100
101             postOrder[*count]     = block;
102             block->bbPostOrderNum = *count;
103             *count += 1;
104
105             DBG_SSA_JITDUMP("postOrder[%d] = [%p] and BB%02u\n", *count, dspPtr(block), block->bbNum);
106         }
107     }
108 }
109
110 /**
111  * Method that finds a common IDom parent, much like least common ancestor.
112  *
113  * @param finger1 A basic block that might share IDom ancestor with finger2.
114  * @param finger2 A basic block that might share IDom ancestor with finger1.
115  *
116  * @see "A simple, fast dominance algorithm" by Keith D. Cooper, Timothy J. Harvey, Ken Kennedy.
117  *
118  * @return A basic block whose IDom is the dominator for finger1 and finger2,
119  * or else NULL.  This may be called while immediate dominators are being
120  * computed, and if the input values are members of the same loop (each reachable from the other),
121  * then one may not yet have its immediate dominator computed when we are attempting
122  * to find the immediate dominator of the other.  So a NULL return value means that the
123  * the two inputs are in a cycle, not that they don't have a common dominator ancestor.
124  */
125 static inline BasicBlock* IntersectDom(BasicBlock* finger1, BasicBlock* finger2)
126 {
127     while (finger1 != finger2)
128     {
129         if (finger1 == nullptr || finger2 == nullptr)
130         {
131             return nullptr;
132         }
133         while (finger1 != nullptr && finger1->bbPostOrderNum < finger2->bbPostOrderNum)
134         {
135             finger1 = finger1->bbIDom;
136         }
137         if (finger1 == nullptr)
138         {
139             return nullptr;
140         }
141         while (finger2 != nullptr && finger2->bbPostOrderNum < finger1->bbPostOrderNum)
142         {
143             finger2 = finger2->bbIDom;
144         }
145     }
146     return finger1;
147 }
148
149 } // end of anonymous namespace.
150
151 // =================================================================================
152 //                                      SSA
153 // =================================================================================
154
155 void Compiler::fgSsaBuild()
156 {
157     IAllocator* pIAllocator = new (this, CMK_SSA) CompAllocator(this, CMK_SSA);
158
159     // If this is not the first invocation, reset data structures for SSA.
160     if (fgSsaPassesCompleted > 0)
161     {
162         fgResetForSsa();
163     }
164
165     SsaBuilder builder(this, pIAllocator);
166     builder.Build();
167     fgSsaPassesCompleted++;
168 #ifdef DEBUG
169     JitTestCheckSSA();
170 #endif // DEBUG
171
172 #ifdef DEBUG
173     if (verbose)
174     {
175         JITDUMP("\nAfter fgSsaBuild:\n");
176         fgDispBasicBlocks(/*dumpTrees*/ true);
177     }
178 #endif // DEBUG
179 }
180
181 void Compiler::fgResetForSsa()
182 {
183     for (unsigned i = 0; i < lvaCount; ++i)
184     {
185         lvaTable[i].lvPerSsaData.Reset();
186     }
187     for (BasicBlock* blk = fgFirstBB; blk != nullptr; blk = blk->bbNext)
188     {
189         // Eliminate phis.
190         blk->bbHeapSsaPhiFunc = nullptr;
191         if (blk->bbTreeList != nullptr)
192         {
193             GenTreePtr last = blk->bbTreeList->gtPrev;
194             blk->bbTreeList = blk->FirstNonPhiDef();
195             if (blk->bbTreeList != nullptr)
196             {
197                 blk->bbTreeList->gtPrev = last;
198             }
199         }
200     }
201 }
202
203 /**
204  *  Constructor for the SSA builder.
205  *
206  *  @param pCompiler Current compiler instance.
207  *
208  *  @remarks Initializes the class and member pointers/objects that use constructors.
209  */
210 SsaBuilder::SsaBuilder(Compiler* pCompiler, IAllocator* pIAllocator)
211     : m_pCompiler(pCompiler)
212     , m_allocator(pIAllocator)
213
214 #ifdef SSA_FEATURE_DOMARR
215     , m_pDomPreOrder(NULL)
216     , m_pDomPostOrder(NULL)
217 #endif
218 #ifdef SSA_FEATURE_USEDEF
219     , m_uses(jitstd::allocator<void>(pIAllocator))
220     , m_defs(jitstd::allocator<void>(pIAllocator))
221 #endif
222 {
223 }
224
225 /**
226  *  Topologically sort the graph and return the number of nodes visited.
227  *
228  *  @param postOrder The array in which the arranged basic blocks have to be returned.
229  *  @param count The size of the postOrder array.
230  *
231  *  @return The number of nodes visited while performing DFS on the graph.
232  */
233 int SsaBuilder::TopologicalSort(BasicBlock** postOrder, int count)
234 {
235     // Allocate and initialize visited flags.
236     bool* visited = (bool*)alloca(count * sizeof(bool));
237     memset(visited, 0, count * sizeof(bool));
238
239     // Display basic blocks.
240     DBEXEC(VERBOSE, m_pCompiler->fgDispBasicBlocks());
241     DBEXEC(VERBOSE, m_pCompiler->fgDispHandlerTab());
242
243     // Call the recursive helper.
244     int postIndex = 0;
245     TopologicalSortHelper(m_pCompiler->fgFirstBB, m_pCompiler, visited, &postIndex, postOrder);
246
247     // In the absence of EH (because catch/finally have no preds), this should be valid.
248     // assert(postIndex == (count - 1));
249
250     return postIndex;
251 }
252
253 /**
254  * Computes the immediate dominator IDom for each block iteratively.
255  *
256  * @param postOrder The array of basic blocks arranged in postOrder.
257  * @param count The size of valid elements in the postOrder array.
258  *
259  * @see "A simple, fast dominance algorithm." paper.
260  */
261 void SsaBuilder::ComputeImmediateDom(BasicBlock** postOrder, int count)
262 {
263     JITDUMP("[SsaBuilder::ComputeImmediateDom]\n");
264
265     // TODO-Cleanup: We currently have two dominance computations happening.  We should unify them; for
266     // now, at least forget the results of the first.
267     for (BasicBlock* blk = m_pCompiler->fgFirstBB; blk != nullptr; blk = blk->bbNext)
268     {
269         blk->bbIDom = nullptr;
270     }
271
272     // Add entry point to processed as its IDom is NULL.
273     BitVecTraits traits(m_pCompiler->fgBBNumMax + 1, m_pCompiler);
274     BitVec       BITVEC_INIT_NOCOPY(processed, BitVecOps::MakeEmpty(&traits));
275
276     BitVecOps::AddElemD(&traits, processed, m_pCompiler->fgFirstBB->bbNum);
277     assert(postOrder[count - 1] == m_pCompiler->fgFirstBB);
278
279     bool changed = true;
280     while (changed)
281     {
282         changed = false;
283
284         // In reverse post order, except for the entry block (count - 1 is entry BB).
285         for (int i = count - 2; i >= 0; --i)
286         {
287             BasicBlock* block = postOrder[i];
288
289             DBG_SSA_JITDUMP("Visiting in reverse post order: BB%02u.\n", block->bbNum);
290
291             // Find the first processed predecessor block.
292             BasicBlock* predBlock = nullptr;
293             for (flowList* pred = m_pCompiler->BlockPredsWithEH(block); pred; pred = pred->flNext)
294             {
295                 if (BitVecOps::IsMember(&traits, processed, pred->flBlock->bbNum))
296                 {
297                     predBlock = pred->flBlock;
298                     break;
299                 }
300             }
301
302             // There could just be a single basic block, so just check if there were any preds.
303             if (predBlock != nullptr)
304             {
305                 DBG_SSA_JITDUMP("Pred block is BB%02u.\n", predBlock->bbNum);
306             }
307
308             // Intersect DOM, if computed, for all predecessors.
309             BasicBlock* bbIDom = predBlock;
310             for (flowList* pred = m_pCompiler->BlockPredsWithEH(block); pred; pred = pred->flNext)
311             {
312                 if (predBlock != pred->flBlock)
313                 {
314                     BasicBlock* domAncestor = IntersectDom(pred->flBlock, bbIDom);
315                     // The result may be NULL if "block" and "pred->flBlock" are part of a
316                     // cycle -- neither is guaranteed ordered wrt the other in reverse postorder,
317                     // so we may be computing the IDom of "block" before the IDom of "pred->flBlock" has
318                     // been computed.  But that's OK -- if they're in a cycle, they share the same immediate
319                     // dominator, so the contribution of "pred->flBlock" is not necessary to compute
320                     // the result.
321                     if (domAncestor != nullptr)
322                     {
323                         bbIDom = domAncestor;
324                     }
325                 }
326             }
327
328             // Did we change the bbIDom value?  If so, we go around the outer loop again.
329             if (block->bbIDom != bbIDom)
330             {
331                 changed = true;
332
333                 // IDom has changed, update it.
334                 DBG_SSA_JITDUMP("bbIDom of BB%02u becomes BB%02u.\n", block->bbNum, bbIDom ? bbIDom->bbNum : 0);
335                 block->bbIDom = bbIDom;
336             }
337
338             // Mark the current block as processed.
339             BitVecOps::AddElemD(&traits, processed, block->bbNum);
340
341             DBG_SSA_JITDUMP("Marking block BB%02u as processed.\n", block->bbNum);
342         }
343     }
344 }
345
346 #ifdef SSA_FEATURE_DOMARR
347 /**
348  * Walk the DOM tree and compute pre and post-order arrangement of the tree.
349  *
350  * @param curBlock The current block being operated on at some recursive level.
351  * @param domTree The DOM tree as a map (block -> set of child blocks.)
352  * @param preIndex The initial index given to the first block visited in pre order.
353  * @param postIndex The initial index given to the first block visited in post order.
354  *
355  * @remarks This would help us answer queries such as "a dom b?" in constant time.
356  *          For example, if a dominated b, then Pre[a] < Pre[b] but Post[a] > Post[b]
357  */
358 void SsaBuilder::DomTreeWalk(BasicBlock* curBlock, BlkToBlkSetMap* domTree, int* preIndex, int* postIndex)
359 {
360     JITDUMP("[SsaBuilder::DomTreeWalk] block [%p], BB%02u:\n", dspPtr(curBlock), curBlock->bbNum);
361
362     // Store the order number at the block number in the pre order list.
363     m_pDomPreOrder[curBlock->bbNum] = *preIndex;
364     ++(*preIndex);
365
366     BlkSet* pBlkSet;
367     if (domTree->Lookup(curBlock, &pBlkSet))
368     {
369         for (BlkSet::KeyIterator ki = pBlkSet->Begin(); !ki.Equal(pBlkSet->End()); ++ki)
370         {
371             if (curBlock != ki.Get())
372             {
373                 DomTreeWalk(ki.Get(), domTree, preIndex, postIndex);
374             }
375         }
376     }
377
378     // Store the order number at the block number in the post order list.
379     m_pDomPostOrder[curBlock->bbNum] = *postIndex;
380     ++(*postIndex);
381 }
382 #endif
383
384 /**
385  * Using IDom of each basic block, add a mapping from block->IDom -> block.
386  * @param pCompiler Compiler instance
387  * @param block The basic block that will become the child node of it's iDom.
388  * @param domTree The output domTree which will hold the mapping "block->bbIDom" -> "block"
389  *
390  */
391 /* static */
392 void SsaBuilder::ConstructDomTreeForBlock(Compiler* pCompiler, BasicBlock* block, BlkToBlkSetMap* domTree)
393 {
394     BasicBlock* bbIDom = block->bbIDom;
395
396     // bbIDom for (only) fgFirstBB will be NULL.
397     if (bbIDom == nullptr)
398     {
399         return;
400     }
401
402     // If the bbIDom map key doesn't exist, create one.
403     BlkSet* pBlkSet;
404     if (!domTree->Lookup(bbIDom, &pBlkSet))
405     {
406         pBlkSet = new (pCompiler->getAllocator()) BlkSet(pCompiler->getAllocator());
407         domTree->Set(bbIDom, pBlkSet);
408     }
409
410     DBG_SSA_JITDUMP("Inserting BB%02u as dom child of BB%02u.\n", block->bbNum, bbIDom->bbNum);
411     // Insert the block into the block's set.
412     pBlkSet->Set(block, true);
413 }
414
415 /**
416  * Using IDom of each basic block, compute the whole tree. If a block "b" has IDom "i",
417  * then, block "b" is dominated by "i". The mapping then is i -> { ..., b, ... }, in
418  * other words, "domTree" is a tree represented by nodes mapped to their children.
419  *
420  * @param pCompiler Compiler instance
421  * @param domTree The output domTree which will hold the mapping "block->bbIDom" -> "block"
422  *
423  */
424 /* static */
425 void SsaBuilder::ComputeDominators(Compiler* pCompiler, BlkToBlkSetMap* domTree)
426 {
427     JITDUMP("*************** In SsaBuilder::ComputeDominators(Compiler*, ...)\n");
428
429     // Construct the DOM tree from bbIDom
430     for (BasicBlock* block = pCompiler->fgFirstBB; block != nullptr; block = block->bbNext)
431     {
432         ConstructDomTreeForBlock(pCompiler, block, domTree);
433     }
434
435     DBEXEC(pCompiler->verboseSsa, DisplayDominators(domTree));
436 }
437
438 /**
439  * Compute the DOM tree into a map(block -> set of blocks) adjacency representation.
440  *
441  * Using IDom of each basic block, compute the whole tree. If a block "b" has IDom "i",
442  * then, block "b" is dominated by "i". The mapping then is i -> { ..., b, ... }
443  *
444  * @param postOrder The array of basic blocks arranged in postOrder.
445  * @param count The size of valid elements in the postOrder array.
446  * @param domTree A map of (block -> set of blocks) tree representation that is empty.
447  *
448  */
449 void SsaBuilder::ComputeDominators(BasicBlock** postOrder, int count, BlkToBlkSetMap* domTree)
450 {
451     JITDUMP("*************** In SsaBuilder::ComputeDominators(BasicBlock** postOrder, int count, ...)\n");
452
453     // Construct the DOM tree from bbIDom
454     for (int i = 0; i < count; ++i)
455     {
456         ConstructDomTreeForBlock(m_pCompiler, postOrder[i], domTree);
457     }
458
459     DBEXEC(m_pCompiler->verboseSsa, DisplayDominators(domTree));
460
461 #ifdef SSA_FEATURE_DOMARR
462     // Allocate space for constant time computation of (a DOM b?) query.
463     unsigned bbArrSize = m_pCompiler->fgBBNumMax + 1; // We will use 1-based bbNums as indices into these arrays, so
464                                                       // add 1.
465     m_pDomPreOrder  = jitstd::utility::allocate<int>(m_allocator, bbArrSize);
466     m_pDomPostOrder = jitstd::utility::allocate<int>(m_allocator, bbArrSize);
467
468     // Initial counters.
469     int preIndex  = 0;
470     int postIndex = 0;
471
472     // Populate the pre and post order of the tree.
473     DomTreeWalk(m_pCompiler->fgFirstBB, domTree, &preIndex, &postIndex);
474 #endif
475 }
476
477 #ifdef DEBUG
478
479 /**
480  * Display the DOM tree.
481  *
482  * @param domTree A map of (block -> set of blocks) tree representation.
483  */
484 /* static */
485 void SsaBuilder::DisplayDominators(BlkToBlkSetMap* domTree)
486 {
487     printf("After computing dominator tree: \n");
488     for (BlkToBlkSetMap::KeyIterator nodes = domTree->Begin(); !nodes.Equal(domTree->End()); ++nodes)
489     {
490         printf("BB%02u := {", nodes.Get()->bbNum);
491
492         BlkSet* pBlkSet = nodes.GetValue();
493         for (BlkSet::KeyIterator ki = pBlkSet->Begin(); !ki.Equal(pBlkSet->End()); ++ki)
494         {
495             if (!ki.Equal(pBlkSet->Begin()))
496             {
497                 printf(",");
498             }
499             printf("BB%02u", ki.Get()->bbNum);
500         }
501         printf("}\n");
502     }
503 }
504
505 #endif // DEBUG
506
507 // (Spec comment at declaration.)
508 // See "A simple, fast dominance algorithm", by Cooper, Harvey, and Kennedy.
509 // First we compute the dominance frontier for each block, then we convert these to iterated
510 // dominance frontiers by a closure operation.
511 BlkToBlkSetMap* SsaBuilder::ComputeIteratedDominanceFrontier(BasicBlock** postOrder, int count)
512 {
513     BlkToBlkSetMap* frontier = new (m_pCompiler->getAllocator()) BlkToBlkSetMap(m_pCompiler->getAllocator());
514
515     DBG_SSA_JITDUMP("Computing IDF: First computing DF.\n");
516
517     for (int i = 0; i < count; ++i)
518     {
519         BasicBlock* block = postOrder[i];
520
521         DBG_SSA_JITDUMP("Considering block BB%02u.\n", block->bbNum);
522
523         // Recall that B3 is in the dom frontier of B1 if there exists a B2
524         // such that B1 dom B2, !(B1 dom B3), and B3 is an immediate successor
525         // of B2.  (Note that B1 might be the same block as B2.)
526         // In that definition, we're considering "block" to be B3, and trying
527         // to find B1's.  To do so, first we consider the predecessors of "block",
528         // searching for candidate B2's -- "block" is obviously an immediate successor
529         // of its immediate predecessors.  If there are zero or one preds, then there
530         // is no pred, or else the single pred dominates "block", so no B2 exists.
531
532         flowList* blockPreds = m_pCompiler->BlockPredsWithEH(block);
533
534         // If block has more 0/1 predecessor, skip.
535         if (blockPreds == nullptr || blockPreds->flNext == nullptr)
536         {
537             DBG_SSA_JITDUMP("   Has %d preds; skipping.\n", blockPreds == nullptr ? 0 : 1);
538             continue;
539         }
540
541         // Otherwise, there are > 1 preds.  Each is a candidate B2 in the definition --
542         // *unless* it dominates "block"/B3.
543
544         for (flowList* pred = blockPreds; pred; pred = pred->flNext)
545         {
546             DBG_SSA_JITDUMP("   Considering predecessor BB%02u.\n", pred->flBlock->bbNum);
547
548             // If we've found a B2, then consider the possible B1's.  We start with
549             // B2, since a block dominates itself, then traverse upwards in the dominator
550             // tree, stopping when we reach the root, or the immediate dominator of "block"/B3.
551             // (Note that we are guaranteed to encounter this immediate dominator of "block"/B3:
552             // a predecessor must be dominated by B3's immediate dominator.)
553             // Along this way, make "block"/B3 part of the dom frontier of the B1.
554             // When we reach this immediate dominator, the definition no longer applies, since this
555             // potential B1 *does* dominate "block"/B3, so we stop.
556             for (BasicBlock* b1 = pred->flBlock; (b1 != nullptr) && (b1 != block->bbIDom); // !root && !loop
557                  b1             = b1->bbIDom)
558             {
559                 DBG_SSA_JITDUMP("      Adding BB%02u to dom frontier of pred dom BB%02u.\n", block->bbNum, b1->bbNum);
560                 BlkSet* pBlkSet;
561                 if (!frontier->Lookup(b1, &pBlkSet))
562                 {
563                     pBlkSet = new (m_pCompiler->getAllocator()) BlkSet(m_pCompiler->getAllocator());
564                     frontier->Set(b1, pBlkSet);
565                 }
566                 pBlkSet->Set(block, true);
567             }
568         }
569     }
570
571 #ifdef DEBUG
572     if (m_pCompiler->verboseSsa)
573     {
574         printf("\nComputed DF:\n");
575         for (int i = 0; i < count; ++i)
576         {
577             BasicBlock* block = postOrder[i];
578             printf("Block BB%02u := {", block->bbNum);
579
580             bool    first = true;
581             BlkSet* blkDf;
582             if (frontier->Lookup(block, &blkDf))
583             {
584                 for (BlkSet::KeyIterator blkDfIter = blkDf->Begin(); !blkDfIter.Equal(blkDf->End()); blkDfIter++)
585                 {
586                     if (!first)
587                     {
588                         printf(",");
589                     }
590                     printf("BB%02u", blkDfIter.Get()->bbNum);
591                     first = false;
592                 }
593             }
594             printf("}\n");
595         }
596     }
597 #endif
598
599     // Now do the closure operation to make the dominance frontier into an IDF.
600     // There's probably a better way to do this...
601     BlkToBlkSetMap* idf = new (m_pCompiler->getAllocator()) BlkToBlkSetMap(m_pCompiler->getAllocator());
602     for (BlkToBlkSetMap::KeyIterator kiFrontBlks = frontier->Begin(); !kiFrontBlks.Equal(frontier->End());
603          kiFrontBlks++)
604     {
605         // Create IDF(b)
606         BlkSet* blkIdf = new (m_pCompiler->getAllocator()) BlkSet(m_pCompiler->getAllocator());
607         idf->Set(kiFrontBlks.Get(), blkIdf);
608
609         // Keep track of what got newly added to the IDF, so we can go after their DFs.
610         BlkSet* delta = new (m_pCompiler->getAllocator()) BlkSet(m_pCompiler->getAllocator());
611         delta->Set(kiFrontBlks.Get(), true);
612
613         // Now transitively add DF+(delta) to IDF(b), each step gathering new "delta."
614         while (delta->GetCount() > 0)
615         {
616             // Extract a block x to be worked on.
617             BlkSet::KeyIterator ki     = delta->Begin();
618             BasicBlock*         curBlk = ki.Get();
619             // TODO-Cleanup: Remove(ki) doesn't work correctly in SimplerHash.
620             delta->Remove(curBlk);
621
622             // Get DF(x).
623             BlkSet* blkDf;
624             if (frontier->Lookup(curBlk, &blkDf))
625             {
626                 // Add DF(x) to IDF(b) and update "delta" i.e., new additions to IDF(b).
627                 for (BlkSet::KeyIterator ki = blkDf->Begin(); !ki.Equal(blkDf->End()); ki++)
628                 {
629                     if (!blkIdf->Lookup(ki.Get()))
630                     {
631                         delta->Set(ki.Get(), true);
632                         blkIdf->Set(ki.Get(), true);
633                     }
634                 }
635             }
636         }
637     }
638
639 #ifdef DEBUG
640     if (m_pCompiler->verboseSsa)
641     {
642         printf("\nComputed IDF:\n");
643         for (int i = 0; i < count; ++i)
644         {
645             BasicBlock* block = postOrder[i];
646             printf("Block BB%02u := {", block->bbNum);
647
648             bool    first = true;
649             BlkSet* blkIdf;
650             if (idf->Lookup(block, &blkIdf))
651             {
652                 for (BlkSet::KeyIterator ki = blkIdf->Begin(); !ki.Equal(blkIdf->End()); ki++)
653                 {
654                     if (!first)
655                     {
656                         printf(",");
657                     }
658                     printf("BB%02u", ki.Get()->bbNum);
659                     first = false;
660                 }
661             }
662             printf("}\n");
663         }
664     }
665 #endif
666
667     return idf;
668 }
669
670 /**
671  * Returns the phi GT_PHI node if the variable already has a phi node.
672  *
673  * @param block The block for which the existence of a phi node needs to be checked.
674  * @param lclNum The lclNum for which the occurrence of a phi node needs to be checked.
675  *
676  * @return If there is a phi node for the lclNum, returns the GT_PHI tree, else NULL.
677  */
678 static GenTree* GetPhiNode(BasicBlock* block, unsigned lclNum)
679 {
680     // Walk the statements for phi nodes.
681     for (GenTreePtr stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
682     {
683         // A prefix of the statements of the block are phi definition nodes. If we complete processing
684         // that prefix, exit.
685         if (!stmt->IsPhiDefnStmt())
686         {
687             break;
688         }
689
690         GenTreePtr tree = stmt->gtStmt.gtStmtExpr;
691
692         GenTreePtr phiLhs = tree->gtOp.gtOp1;
693         assert(phiLhs->OperGet() == GT_LCL_VAR);
694         if (phiLhs->gtLclVarCommon.gtLclNum == lclNum)
695         {
696             return tree->gtOp.gtOp2;
697         }
698     }
699     return nullptr;
700 }
701
702 /**
703  * Inserts phi functions at DF(b) for variables v that are live after the phi
704  * insertion point i.e., v in live-in(b).
705  *
706  * To do so, the function computes liveness, dominance frontier and inserts a phi node,
707  * if we have var v in def(b) and live-in(l) and l is in DF(b).
708  *
709  * @param postOrder The array of basic blocks arranged in postOrder.
710  * @param count The size of valid elements in the postOrder array.
711  */
712 void SsaBuilder::InsertPhiFunctions(BasicBlock** postOrder, int count)
713 {
714     JITDUMP("*************** In SsaBuilder::InsertPhiFunctions()\n");
715
716     // Compute liveness on the graph.
717     m_pCompiler->fgLocalVarLiveness();
718     EndPhase(PHASE_BUILD_SSA_LIVENESS);
719
720     // Compute dominance frontier.
721     BlkToBlkSetMap* frontier = ComputeIteratedDominanceFrontier(postOrder, count);
722     EndPhase(PHASE_BUILD_SSA_IDF);
723
724     JITDUMP("Inserting phi functions:\n");
725
726     for (int i = 0; i < count; ++i)
727     {
728         BasicBlock* block = postOrder[i];
729         DBG_SSA_JITDUMP("Considering dominance frontier of block BB%02u:\n", block->bbNum);
730
731         // If the block's dominance frontier is empty, go on to the next block.
732         BlkSet* blkIdf;
733         if (!frontier->Lookup(block, &blkIdf))
734         {
735             continue;
736         }
737
738         // For each local var number "lclNum" that "block" assigns to...
739         VARSET_ITER_INIT(m_pCompiler, defVars, block->bbVarDef, varIndex);
740         while (defVars.NextElem(m_pCompiler, &varIndex))
741         {
742             unsigned lclNum = m_pCompiler->lvaTrackedToVarNum[varIndex];
743             DBG_SSA_JITDUMP("  Considering local var V%02u:\n", lclNum);
744
745             if (m_pCompiler->fgExcludeFromSsa(lclNum))
746             {
747                 DBG_SSA_JITDUMP("  Skipping because it is excluded.\n");
748                 continue;
749             }
750
751             // For each block "bbInDomFront" that is in the dominance frontier of "block"...
752             for (BlkSet::KeyIterator iterBlk = blkIdf->Begin(); !iterBlk.Equal(blkIdf->End()); ++iterBlk)
753             {
754                 BasicBlock* bbInDomFront = iterBlk.Get();
755                 DBG_SSA_JITDUMP("     Considering BB%02u in dom frontier of BB%02u:\n", bbInDomFront->bbNum,
756                                 block->bbNum);
757
758                 // Check if variable "lclNum" is live in block "*iterBlk".
759                 if (!VarSetOps::IsMember(m_pCompiler, bbInDomFront->bbLiveIn, varIndex))
760                 {
761                     continue;
762                 }
763
764                 // Check if we've already inserted a phi node.
765                 if (GetPhiNode(bbInDomFront, lclNum) == nullptr)
766                 {
767                     // We have a variable i that is defined in block j and live at l, and l belongs to dom frontier of
768                     // j. So insert a phi node at l.
769                     JITDUMP("Inserting phi definition for V%02u at start of BB%02u.\n", lclNum, bbInDomFront->bbNum);
770
771                     GenTreePtr phiLhs = m_pCompiler->gtNewLclvNode(lclNum, m_pCompiler->lvaTable[lclNum].TypeGet());
772
773                     // Create 'phiRhs' as a GT_PHI node for 'lclNum', it will eventually hold a GT_LIST of GT_PHI_ARG
774                     // nodes. However we have to construct this list so for now the gtOp1 of 'phiRhs' is a nullptr.
775                     // It will get replaced with a GT_LIST of GT_PHI_ARG nodes in
776                     // SsaBuilder::AssignPhiNodeRhsVariables() and in SsaBuilder::AddDefToHandlerPhis()
777
778                     GenTreePtr phiRhs =
779                         m_pCompiler->gtNewOperNode(GT_PHI, m_pCompiler->lvaTable[lclNum].TypeGet(), nullptr);
780
781                     GenTreePtr phiAsg = m_pCompiler->gtNewAssignNode(phiLhs, phiRhs);
782
783                     GenTreePtr stmt = m_pCompiler->fgInsertStmtAtBeg(bbInDomFront, phiAsg);
784                     m_pCompiler->gtSetStmtInfo(stmt);
785                     m_pCompiler->fgSetStmtSeq(stmt);
786                 }
787             }
788         }
789
790         // Now make a similar phi definition if the block defines Heap.
791         if (block->bbHeapDef)
792         {
793             // For each block "bbInDomFront" that is in the dominance frontier of "block".
794             for (BlkSet::KeyIterator iterBlk = blkIdf->Begin(); !iterBlk.Equal(blkIdf->End()); ++iterBlk)
795             {
796                 BasicBlock* bbInDomFront = iterBlk.Get();
797                 DBG_SSA_JITDUMP("     Considering BB%02u in dom frontier of BB%02u for Heap phis:\n",
798                                 bbInDomFront->bbNum, block->bbNum);
799
800                 // Check if Heap is live into block "*iterBlk".
801                 if (!bbInDomFront->bbHeapLiveIn)
802                 {
803                     continue;
804                 }
805
806                 // Check if we've already inserted a phi node.
807                 if (bbInDomFront->bbHeapSsaPhiFunc == nullptr)
808                 {
809                     // We have a variable i that is defined in block j and live at l, and l belongs to dom frontier of
810                     // j. So insert a phi node at l.
811                     JITDUMP("Inserting phi definition for Heap at start of BB%02u.\n", bbInDomFront->bbNum);
812                     bbInDomFront->bbHeapSsaPhiFunc = BasicBlock::EmptyHeapPhiDef;
813                 }
814             }
815         }
816     }
817     EndPhase(PHASE_BUILD_SSA_INSERT_PHIS);
818 }
819
820 #ifdef SSA_FEATURE_USEDEF
821 /**
822  * Record a use point of a variable.
823  *
824  * The use point is just the tree that is a local variable use.
825  *
826  * @param tree Tree node where an SSA variable is used.
827  *
828  * @remarks The result is in the m_uses map :: [lclNum, ssaNum] -> tree.
829  */
830 void SsaBuilder::AddUsePoint(GenTree* tree)
831 {
832     assert(tree->IsLocal());
833     SsaVarName          key(tree->gtLclVarCommon.gtLclNum, tree->gtLclVarCommon.gtSsaNum);
834     VarToUses::iterator iter = m_uses.find(key);
835     if (iter == m_uses.end())
836     {
837         iter = m_uses.insert(key, VarToUses::mapped_type(m_uses.get_allocator()));
838     }
839     (*iter).second.push_back(tree);
840 }
841 #endif // !SSA_FEATURE_USEDEF
842
843 /**
844  * Record a def point of a variable.
845  *
846  * The def point is just the tree that is a local variable def.
847  *
848  * @param tree Tree node where an SSA variable is def'ed.
849  *
850  * @remarks The result is in the m_defs map :: [lclNum, ssaNum] -> tree.
851  */
852 void SsaBuilder::AddDefPoint(GenTree* tree, BasicBlock* blk)
853 {
854     Compiler::IndirectAssignmentAnnotation* pIndirAnnot;
855     // In the case of an "indirect assignment", where the LHS is IND of a byref to the local actually being assigned,
856     // we make the ASG tree the def point.
857     assert(tree->IsLocal() || IsIndirectAssign(tree, &pIndirAnnot));
858     unsigned lclNum;
859     unsigned defSsaNum;
860     if (tree->IsLocal())
861     {
862         lclNum    = tree->gtLclVarCommon.gtLclNum;
863         defSsaNum = m_pCompiler->GetSsaNumForLocalVarDef(tree);
864     }
865     else
866     {
867         bool b = m_pCompiler->GetIndirAssignMap()->Lookup(tree, &pIndirAnnot);
868         assert(b);
869         lclNum    = pIndirAnnot->m_lclNum;
870         defSsaNum = pIndirAnnot->m_defSsaNum;
871     }
872 #ifdef DEBUG
873     // Record that there's a new SSA def.
874     m_pCompiler->lvaTable[lclNum].lvNumSsaNames++;
875 #endif
876     // Record where the defn happens.
877     LclSsaVarDsc* ssaDef    = m_pCompiler->lvaTable[lclNum].GetPerSsaData(defSsaNum);
878     ssaDef->m_defLoc.m_blk  = blk;
879     ssaDef->m_defLoc.m_tree = tree;
880
881 #ifdef SSA_FEATURE_USEDEF
882     SsaVarName         key(lclNum, defSsaNum);
883     VarToDef::iterator iter = m_defs.find(key);
884     if (iter == m_defs.end())
885     {
886         iter = m_defs.insert(key, tree);
887         return;
888     }
889     // There can only be a single definition for an SSA var.
890     unreached();
891 #endif
892 }
893
894 bool SsaBuilder::IsIndirectAssign(GenTreePtr tree, Compiler::IndirectAssignmentAnnotation** ppIndirAssign)
895 {
896     return tree->OperGet() == GT_ASG && m_pCompiler->m_indirAssignMap != nullptr &&
897            m_pCompiler->GetIndirAssignMap()->Lookup(tree, ppIndirAssign);
898 }
899
900 /**
901  * Rename the local variable tree node.
902  *
903  * If the given tree node is a local variable, then for a def give a new count, if use,
904  * then give the count in the top of stack, i.e., current count (used for last def.)
905  *
906  * @param tree Tree node where an SSA variable is used or def'ed.
907  * @param pRenameState The incremental rename information stored during renaming process.
908  *
909  * @remarks This method has to maintain parity with TreePopStacks corresponding to pushes
910  *          it makes for defs.
911  */
912 void SsaBuilder::TreeRenameVariables(GenTree* tree, BasicBlock* block, SsaRenameState* pRenameState, bool isPhiDefn)
913 {
914     // This is perhaps temporary -- maybe should be done elsewhere.  Label GT_INDs on LHS of assignments, so we
915     // can skip these during (at least) value numbering.
916     if (tree->OperIsAssignment())
917     {
918         GenTreePtr lhs     = tree->gtOp.gtOp1->gtEffectiveVal(/*commaOnly*/ true);
919         GenTreePtr trueLhs = lhs->gtEffectiveVal(/*commaOnly*/ true);
920         if (trueLhs->OperGet() == GT_IND)
921         {
922             trueLhs->gtFlags |= GTF_IND_ASG_LHS;
923         }
924         else if (trueLhs->OperGet() == GT_CLS_VAR)
925         {
926             trueLhs->gtFlags |= GTF_CLS_VAR_ASG_LHS;
927         }
928     }
929
930     // Figure out if "tree" may make a new heap state (if we care for this block).
931     if (!block->bbHeapHavoc)
932     {
933         if (tree->OperIsAssignment() || tree->OperIsBlkOp())
934         {
935             if (m_pCompiler->ehBlockHasExnFlowDsc(block))
936             {
937                 GenTreeLclVarCommon* lclVarNode;
938                 if (!tree->DefinesLocal(m_pCompiler, &lclVarNode))
939                 {
940                     // It *may* define the heap in a non-havoc way.  Make a new SSA # -- associate with this node.
941                     unsigned count = pRenameState->CountForHeapDef();
942                     pRenameState->PushHeap(block, count);
943                     m_pCompiler->GetHeapSsaMap()->Set(tree, count);
944 #ifdef DEBUG
945                     if (JitTls::GetCompiler()->verboseSsa)
946                     {
947                         printf("Node ");
948                         Compiler::printTreeID(tree);
949                         printf(" (in try block) may define heap; ssa # = %d.\n", count);
950                     }
951 #endif // DEBUG
952
953                     // Now add this SSA # to all phis of the reachable catch blocks.
954                     AddHeapDefToHandlerPhis(block, count);
955                 }
956             }
957         }
958     }
959
960     Compiler::IndirectAssignmentAnnotation* pIndirAssign = nullptr;
961     if (!tree->IsLocal() && !IsIndirectAssign(tree, &pIndirAssign))
962     {
963         return;
964     }
965
966     if (pIndirAssign != nullptr)
967     {
968         unsigned lclNum = pIndirAssign->m_lclNum;
969         // Is this a variable we exclude from SSA?
970         if (m_pCompiler->fgExcludeFromSsa(lclNum))
971         {
972             pIndirAssign->m_defSsaNum = SsaConfig::RESERVED_SSA_NUM;
973             return;
974         }
975         // Otherwise...
976         if (!pIndirAssign->m_isEntire)
977         {
978             pIndirAssign->m_useSsaNum = pRenameState->CountForUse(lclNum);
979         }
980         unsigned count            = pRenameState->CountForDef(lclNum);
981         pIndirAssign->m_defSsaNum = count;
982         pRenameState->Push(block, lclNum, count);
983         AddDefPoint(tree, block);
984     }
985     else
986     {
987         unsigned lclNum = tree->gtLclVarCommon.gtLclNum;
988         // Is this a variable we exclude from SSA?
989         if (m_pCompiler->fgExcludeFromSsa(lclNum))
990         {
991             tree->gtLclVarCommon.SetSsaNum(SsaConfig::RESERVED_SSA_NUM);
992             return;
993         }
994
995         if (tree->gtFlags & GTF_VAR_DEF)
996         {
997             if (tree->gtFlags & GTF_VAR_USEASG)
998             {
999                 // This the "x" in something like "x op= y"; it is both a use (first), then a def.
1000                 // The def will define a new SSA name, and record that in "x".  If we need the SSA
1001                 // name of the use, we record it in a map reserved for that purpose.
1002                 unsigned count = pRenameState->CountForUse(lclNum);
1003                 tree->gtLclVarCommon.SetSsaNum(count);
1004 #ifdef SSA_FEATURE_USEDEF
1005                 AddUsePoint(tree);
1006 #endif
1007             }
1008
1009             // Give a count and increment.
1010             unsigned count = pRenameState->CountForDef(lclNum);
1011             if (tree->gtFlags & GTF_VAR_USEASG)
1012             {
1013                 m_pCompiler->GetOpAsgnVarDefSsaNums()->Set(tree, count);
1014             }
1015             else
1016             {
1017                 tree->gtLclVarCommon.SetSsaNum(count);
1018             }
1019             pRenameState->Push(block, lclNum, count);
1020             AddDefPoint(tree, block);
1021
1022             // If necessary, add "lclNum/count" to the arg list of a phi def in any
1023             // handlers for try blocks that "block" is within.  (But only do this for "real" definitions,
1024             // not phi definitions.)
1025             if (!isPhiDefn)
1026             {
1027                 AddDefToHandlerPhis(block, lclNum, count);
1028             }
1029         }
1030         else if (!isPhiDefn) // Phi args already have ssa numbers.
1031         {
1032             // This case is obviated by the short-term "early-out" above...but it's in the right direction.
1033             // Is it a promoted struct local?
1034             if (m_pCompiler->lvaTable[lclNum].lvPromoted)
1035             {
1036                 assert(tree->TypeGet() == TYP_STRUCT);
1037                 LclVarDsc* varDsc = &m_pCompiler->lvaTable[lclNum];
1038                 // If has only a single field var, treat this as a use of that field var.
1039                 // Otherwise, we don't give SSA names to uses of promoted struct vars.
1040                 if (varDsc->lvFieldCnt == 1)
1041                 {
1042                     lclNum = varDsc->lvFieldLclStart;
1043                 }
1044                 else
1045                 {
1046                     tree->gtLclVarCommon.SetSsaNum(SsaConfig::RESERVED_SSA_NUM);
1047                     return;
1048                 }
1049             }
1050             // Give the count as top of stack.
1051             unsigned count = pRenameState->CountForUse(lclNum);
1052             tree->gtLclVarCommon.SetSsaNum(count);
1053 #ifdef SSA_FEATURE_USEDEF
1054             AddUsePoint(tree);
1055 #endif
1056         }
1057     }
1058 }
1059
1060 void SsaBuilder::AddDefToHandlerPhis(BasicBlock* block, unsigned lclNum, unsigned count)
1061 {
1062     assert(m_pCompiler->lvaTable[lclNum].lvTracked); // Precondition.
1063     unsigned lclIndex = m_pCompiler->lvaTable[lclNum].lvVarIndex;
1064
1065     EHblkDsc* tryBlk = m_pCompiler->ehGetBlockExnFlowDsc(block);
1066     if (tryBlk != nullptr)
1067     {
1068         DBG_SSA_JITDUMP(
1069             "Definition of local V%02u/d:%d in block BB%02u has exn handler; adding as phi arg to handlers.\n", lclNum,
1070             count, block->bbNum);
1071         while (true)
1072         {
1073             BasicBlock* handler = tryBlk->ExFlowBlock();
1074
1075             // Is "lclNum" live on entry to the handler?
1076             if (VarSetOps::IsMember(m_pCompiler, handler->bbLiveIn, lclIndex))
1077             {
1078 #ifdef DEBUG
1079                 bool phiFound = false;
1080 #endif
1081                 // A prefix of blocks statements will be SSA definitions.  Search those for "lclNum".
1082                 for (GenTreePtr stmt = handler->bbTreeList; stmt; stmt = stmt->gtNext)
1083                 {
1084                     // If the tree is not an SSA def, break out of the loop: we're done.
1085                     if (!stmt->IsPhiDefnStmt())
1086                     {
1087                         break;
1088                     }
1089
1090                     GenTreePtr tree = stmt->gtStmt.gtStmtExpr;
1091
1092                     assert(tree->IsPhiDefn());
1093
1094                     if (tree->gtOp.gtOp1->gtLclVar.gtLclNum == lclNum)
1095                     {
1096                         // It's the definition for the right local.  Add "count" to the RHS.
1097                         GenTreePtr      phi  = tree->gtOp.gtOp2;
1098                         GenTreeArgList* args = nullptr;
1099                         if (phi->gtOp.gtOp1 != nullptr)
1100                         {
1101                             args = phi->gtOp.gtOp1->AsArgList();
1102                         }
1103 #ifdef DEBUG
1104                         // Make sure it isn't already present: we should only add each definition once.
1105                         for (GenTreeArgList* curArgs = args; curArgs != nullptr; curArgs = curArgs->Rest())
1106                         {
1107                             GenTreePhiArg* phiArg = curArgs->Current()->AsPhiArg();
1108                             assert(phiArg->gtSsaNum != count);
1109                         }
1110 #endif
1111                         var_types      typ = m_pCompiler->lvaTable[lclNum].TypeGet();
1112                         GenTreePhiArg* newPhiArg =
1113                             new (m_pCompiler, GT_PHI_ARG) GenTreePhiArg(typ, lclNum, count, block);
1114
1115                         phi->gtOp.gtOp1 = new (m_pCompiler, GT_LIST) GenTreeArgList(newPhiArg, args);
1116                         m_pCompiler->gtSetStmtInfo(stmt);
1117                         m_pCompiler->fgSetStmtSeq(stmt);
1118 #ifdef DEBUG
1119                         phiFound = true;
1120 #endif
1121                         DBG_SSA_JITDUMP("   Added phi arg u:%d for V%02u to phi defn in handler block BB%02u.\n", count,
1122                                         lclNum, handler->bbNum);
1123                         break;
1124                     }
1125                 }
1126                 assert(phiFound);
1127             }
1128
1129             unsigned nextTryIndex = tryBlk->ebdEnclosingTryIndex;
1130             if (nextTryIndex == EHblkDsc::NO_ENCLOSING_INDEX)
1131             {
1132                 break;
1133             }
1134
1135             tryBlk = m_pCompiler->ehGetDsc(nextTryIndex);
1136         }
1137     }
1138 }
1139
1140 void SsaBuilder::AddHeapDefToHandlerPhis(BasicBlock* block, unsigned count)
1141 {
1142     if (m_pCompiler->ehBlockHasExnFlowDsc(block))
1143     {
1144         // Don't do anything for a compiler-inserted BBJ_ALWAYS that is a "leave helper".
1145         if (block->bbJumpKind == BBJ_ALWAYS && (block->bbFlags & BBF_INTERNAL) && (block->bbPrev->isBBCallAlwaysPair()))
1146         {
1147             return;
1148         }
1149
1150         // Otherwise...
1151         DBG_SSA_JITDUMP("Definition of Heap/d:%d in block BB%02u has exn handler; adding as phi arg to handlers.\n",
1152                         count, block->bbNum);
1153         EHblkDsc* tryBlk = m_pCompiler->ehGetBlockExnFlowDsc(block);
1154         while (true)
1155         {
1156             BasicBlock* handler = tryBlk->ExFlowBlock();
1157
1158             // Is Heap live on entry to the handler?
1159             if (handler->bbHeapLiveIn)
1160             {
1161                 assert(handler->bbHeapSsaPhiFunc != nullptr);
1162
1163                 // Add "count" to the phi args of Heap.
1164                 if (handler->bbHeapSsaPhiFunc == BasicBlock::EmptyHeapPhiDef)
1165                 {
1166                     handler->bbHeapSsaPhiFunc = new (m_pCompiler) BasicBlock::HeapPhiArg(count);
1167                 }
1168                 else
1169                 {
1170 #ifdef DEBUG
1171                     BasicBlock::HeapPhiArg* curArg = handler->bbHeapSsaPhiFunc;
1172                     while (curArg != nullptr)
1173                     {
1174                         assert(curArg->GetSsaNum() != count);
1175                         curArg = curArg->m_nextArg;
1176                     }
1177 #endif // DEBUG
1178                     handler->bbHeapSsaPhiFunc =
1179                         new (m_pCompiler) BasicBlock::HeapPhiArg(count, handler->bbHeapSsaPhiFunc);
1180                 }
1181
1182                 DBG_SSA_JITDUMP("   Added phi arg u:%d for Heap to phi defn in handler block BB%02u.\n", count,
1183                                 handler->bbNum);
1184             }
1185             unsigned tryInd = tryBlk->ebdEnclosingTryIndex;
1186             if (tryInd == EHblkDsc::NO_ENCLOSING_INDEX)
1187             {
1188                 break;
1189             }
1190             tryBlk = m_pCompiler->ehGetDsc(tryInd);
1191         }
1192     }
1193 }
1194
1195 /**
1196  * Walk the block's tree in the evaluation order and give var definitions and uses their
1197  * SSA names.
1198  *
1199  * @param block Block for which SSA variables have to be renamed.
1200  * @param pRenameState The incremental rename information stored during renaming process.
1201  *
1202  */
1203 void SsaBuilder::BlockRenameVariables(BasicBlock* block, SsaRenameState* pRenameState)
1204 {
1205     // Walk the statements of the block and rename the tree variables.
1206
1207     // First handle the incoming Heap state.
1208
1209     // Is there an Phi definition for heap at the start of this block?
1210     if (block->bbHeapSsaPhiFunc != nullptr)
1211     {
1212         unsigned count = pRenameState->CountForHeapDef();
1213         pRenameState->PushHeap(block, count);
1214
1215         DBG_SSA_JITDUMP("Ssa # for Heap phi on entry to BB%02u is %d.\n", block->bbNum, count);
1216     }
1217
1218     // Record the "in" Ssa # for Heap.
1219     block->bbHeapSsaNumIn = pRenameState->CountForHeapUse();
1220
1221     // We need to iterate over phi definitions, to give them SSA names, but we need
1222     // to know which are which, so we don't add phi definitions to handler phi arg lists.
1223     // Statements are phi defns until they aren't.
1224     bool       isPhiDefn   = true;
1225     GenTreePtr firstNonPhi = block->FirstNonPhiDef();
1226     for (GenTreePtr stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
1227     {
1228         if (stmt == firstNonPhi)
1229         {
1230             isPhiDefn = false;
1231         }
1232
1233         for (GenTreePtr tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
1234         {
1235             TreeRenameVariables(tree, block, pRenameState, isPhiDefn);
1236         }
1237     }
1238
1239     // Now handle the final heap state.
1240
1241     // If the block defines Heap, allocate an SSA variable for the final heap state in the block.
1242     // (This may be redundant with the last SSA var explicitly created, but there's no harm in that.)
1243     if (block->bbHeapDef)
1244     {
1245         unsigned count = pRenameState->CountForHeapDef();
1246         pRenameState->PushHeap(block, count);
1247         AddHeapDefToHandlerPhis(block, count);
1248     }
1249
1250     // Record the "out" Ssa" # for Heap.
1251     block->bbHeapSsaNumOut = pRenameState->CountForHeapUse();
1252
1253     DBG_SSA_JITDUMP("Ssa # for Heap on entry to BB%02u is %d; on exit is %d.\n", block->bbNum, block->bbHeapSsaNumIn,
1254                     block->bbHeapSsaNumOut);
1255 }
1256
1257 /**
1258  * Walk through the phi nodes of a given block and assign rhs variables to them.
1259  *
1260  * Also renumber the rhs variables from top of the stack.
1261  *
1262  * @param block Block for which phi nodes have to be assigned their rhs arguments.
1263  * @param pRenameState The incremental rename information stored during renaming process.
1264  *
1265  */
1266 void SsaBuilder::AssignPhiNodeRhsVariables(BasicBlock* block, SsaRenameState* pRenameState)
1267 {
1268     BasicBlock::AllSuccs allSuccs    = block->GetAllSuccs(m_pCompiler);
1269     AllSuccessorIter     allSuccsEnd = allSuccs.end();
1270     for (AllSuccessorIter allSuccsIter = allSuccs.begin(); allSuccsIter != allSuccsEnd; ++allSuccsIter)
1271     {
1272         BasicBlock* succ = (*allSuccsIter);
1273         // Walk the statements for phi nodes.
1274         for (GenTreePtr stmt = succ->bbTreeList; stmt != nullptr && stmt->IsPhiDefnStmt(); stmt = stmt->gtNext)
1275         {
1276             GenTreePtr tree = stmt->gtStmt.gtStmtExpr;
1277             assert(tree->IsPhiDefn());
1278
1279             // Get the phi node from GT_ASG.
1280             GenTreePtr phiNode = tree->gtOp.gtOp2;
1281             assert(phiNode->gtOp.gtOp1 == nullptr || phiNode->gtOp.gtOp1->OperGet() == GT_LIST);
1282
1283             unsigned lclNum = tree->gtOp.gtOp1->gtLclVar.gtLclNum;
1284             unsigned ssaNum = pRenameState->CountForUse(lclNum);
1285             // Search the arglist for an existing definition for ssaNum.
1286             // (Can we assert that its the head of the list?  This should only happen when we add
1287             // during renaming for a definition that occurs within a try, and then that's the last
1288             // value of the var within that basic block.)
1289             GenTreeArgList* argList = (phiNode->gtOp.gtOp1 == nullptr ? nullptr : phiNode->gtOp.gtOp1->AsArgList());
1290             bool            found   = false;
1291             while (argList != nullptr)
1292             {
1293                 if (argList->Current()->AsLclVarCommon()->GetSsaNum() == ssaNum)
1294                 {
1295                     found = true;
1296                     break;
1297                 }
1298                 argList = argList->Rest();
1299             }
1300             if (!found)
1301             {
1302                 GenTreePtr newPhiArg =
1303                     new (m_pCompiler, GT_PHI_ARG) GenTreePhiArg(tree->gtOp.gtOp1->TypeGet(), lclNum, ssaNum, block);
1304                 argList             = (phiNode->gtOp.gtOp1 == nullptr ? nullptr : phiNode->gtOp.gtOp1->AsArgList());
1305                 phiNode->gtOp.gtOp1 = new (m_pCompiler, GT_LIST) GenTreeArgList(newPhiArg, argList);
1306                 DBG_SSA_JITDUMP("  Added phi arg u:%d for V%02u from BB%02u in BB%02u.\n", ssaNum, lclNum, block->bbNum,
1307                                 succ->bbNum);
1308             }
1309
1310             m_pCompiler->gtSetStmtInfo(stmt);
1311             m_pCompiler->fgSetStmtSeq(stmt);
1312         }
1313
1314         // Now handle Heap.
1315         if (succ->bbHeapSsaPhiFunc != nullptr)
1316         {
1317             if (succ->bbHeapSsaPhiFunc == BasicBlock::EmptyHeapPhiDef)
1318             {
1319                 succ->bbHeapSsaPhiFunc = new (m_pCompiler) BasicBlock::HeapPhiArg(block);
1320             }
1321             else
1322             {
1323                 BasicBlock::HeapPhiArg* curArg = succ->bbHeapSsaPhiFunc;
1324                 bool                    found  = false;
1325                 // This is a quadratic algorithm.  We might need to consider some switch over to a hash table
1326                 // representation for the arguments of a phi node, to make this linear.
1327                 while (curArg != nullptr)
1328                 {
1329                     if (curArg->m_predBB == block)
1330                     {
1331                         found = true;
1332                         break;
1333                     }
1334                     curArg = curArg->m_nextArg;
1335                 }
1336                 if (!found)
1337                 {
1338                     succ->bbHeapSsaPhiFunc = new (m_pCompiler) BasicBlock::HeapPhiArg(block, succ->bbHeapSsaPhiFunc);
1339                 }
1340             }
1341             DBG_SSA_JITDUMP("  Added phi arg for Heap from BB%02u in BB%02u.\n", block->bbNum, succ->bbNum);
1342         }
1343
1344         // If "succ" is the first block of a try block (and "block" is not also in that try block)
1345         // then we must look at the vars that have phi defs in the corresponding handler;
1346         // the current SSA name for such vars must be included as an argument to that phi.
1347         if (m_pCompiler->bbIsTryBeg(succ))
1348         {
1349             assert(succ->hasTryIndex());
1350             unsigned tryInd = succ->getTryIndex();
1351
1352             while (tryInd != EHblkDsc::NO_ENCLOSING_INDEX)
1353             {
1354                 // Check if the predecessor "block" is within the same try block.
1355                 if (block->hasTryIndex())
1356                 {
1357                     for (unsigned blockTryInd = block->getTryIndex(); blockTryInd != EHblkDsc::NO_ENCLOSING_INDEX;
1358                          blockTryInd          = m_pCompiler->ehGetEnclosingTryIndex(blockTryInd))
1359                     {
1360                         if (blockTryInd == tryInd)
1361                         {
1362                             // It is; don't execute the loop below.
1363                             tryInd = EHblkDsc::NO_ENCLOSING_INDEX;
1364                             break;
1365                         }
1366                     }
1367
1368                     // The loop just above found that the predecessor "block" is within the same
1369                     // try block as "succ."  So we don't need to process this try, or any
1370                     // further outer try blocks here, since they would also contain both "succ"
1371                     // and "block".
1372                     if (tryInd == EHblkDsc::NO_ENCLOSING_INDEX)
1373                     {
1374                         break;
1375                     }
1376                 }
1377
1378                 EHblkDsc* succTry = m_pCompiler->ehGetDsc(tryInd);
1379                 // This is necessarily true on the first iteration, but not
1380                 // necessarily on the second and subsequent.
1381                 if (succTry->ebdTryBeg != succ)
1382                 {
1383                     break;
1384                 }
1385
1386                 // succ is the first block of this try.  Look at phi defs in the handler.
1387                 // For a filter, we consider the filter to be the "real" handler.
1388                 BasicBlock* handlerStart = succTry->ExFlowBlock();
1389
1390                 for (GenTreePtr stmt = handlerStart->bbTreeList; stmt; stmt = stmt->gtNext)
1391                 {
1392                     GenTreePtr tree = stmt->gtStmt.gtStmtExpr;
1393
1394                     // Check if the first n of the statements are phi nodes. If not, exit.
1395                     if (tree->OperGet() != GT_ASG || tree->gtOp.gtOp2 == nullptr ||
1396                         tree->gtOp.gtOp2->OperGet() != GT_PHI)
1397                     {
1398                         break;
1399                     }
1400
1401                     // Get the phi node from GT_ASG.
1402                     GenTreePtr lclVar = tree->gtOp.gtOp1;
1403                     unsigned   lclNum = lclVar->gtLclVar.gtLclNum;
1404
1405                     // If the variable is live-out of "blk", and is therefore live on entry to the try-block-start
1406                     // "succ", then we make sure the current SSA name for the
1407                     // var is one of the args of the phi node.  If not, go on.
1408                     LclVarDsc* lclVarDsc = &m_pCompiler->lvaTable[lclNum];
1409                     if (!lclVarDsc->lvTracked ||
1410                         !VarSetOps::IsMember(m_pCompiler, block->bbLiveOut, lclVarDsc->lvVarIndex))
1411                     {
1412                         continue;
1413                     }
1414
1415                     GenTreePtr phiNode = tree->gtOp.gtOp2;
1416                     assert(phiNode->gtOp.gtOp1 == nullptr || phiNode->gtOp.gtOp1->OperGet() == GT_LIST);
1417                     GenTreeArgList* argList = reinterpret_cast<GenTreeArgList*>(phiNode->gtOp.gtOp1);
1418
1419                     // What is the current SSAName from the predecessor for this local?
1420                     unsigned ssaNum = pRenameState->CountForUse(lclNum);
1421
1422                     // See if this ssaNum is already an arg to the phi.
1423                     bool alreadyArg = false;
1424                     for (GenTreeArgList* curArgs = argList; curArgs != nullptr; curArgs = curArgs->Rest())
1425                     {
1426                         if (curArgs->Current()->gtPhiArg.gtSsaNum == ssaNum)
1427                         {
1428                             alreadyArg = true;
1429                             break;
1430                         }
1431                     }
1432                     if (!alreadyArg)
1433                     {
1434                         // Add the new argument.
1435                         GenTreePtr newPhiArg =
1436                             new (m_pCompiler, GT_PHI_ARG) GenTreePhiArg(lclVar->TypeGet(), lclNum, ssaNum, block);
1437                         phiNode->gtOp.gtOp1 = new (m_pCompiler, GT_LIST) GenTreeArgList(newPhiArg, argList);
1438
1439                         DBG_SSA_JITDUMP("  Added phi arg u:%d for V%02u from BB%02u in BB%02u.\n", ssaNum, lclNum,
1440                                         block->bbNum, handlerStart->bbNum);
1441
1442                         m_pCompiler->gtSetStmtInfo(stmt);
1443                         m_pCompiler->fgSetStmtSeq(stmt);
1444                     }
1445                 }
1446
1447                 // Now handle Heap.
1448                 if (handlerStart->bbHeapSsaPhiFunc != nullptr)
1449                 {
1450                     if (handlerStart->bbHeapSsaPhiFunc == BasicBlock::EmptyHeapPhiDef)
1451                     {
1452                         handlerStart->bbHeapSsaPhiFunc = new (m_pCompiler) BasicBlock::HeapPhiArg(block);
1453                     }
1454                     else
1455                     {
1456 #ifdef DEBUG
1457                         BasicBlock::HeapPhiArg* curArg = handlerStart->bbHeapSsaPhiFunc;
1458                         while (curArg != nullptr)
1459                         {
1460                             assert(curArg->m_predBB != block);
1461                             curArg = curArg->m_nextArg;
1462                         }
1463 #endif // DEBUG
1464                         handlerStart->bbHeapSsaPhiFunc =
1465                             new (m_pCompiler) BasicBlock::HeapPhiArg(block, handlerStart->bbHeapSsaPhiFunc);
1466                     }
1467                     DBG_SSA_JITDUMP("  Added phi arg for Heap from BB%02u in BB%02u.\n", block->bbNum,
1468                                     handlerStart->bbNum);
1469                 }
1470
1471                 tryInd = succTry->ebdEnclosingTryIndex;
1472             }
1473         }
1474     }
1475 }
1476
1477 /**
1478  * Walk the block's tree in the evaluation order and reclaim rename stack for var definitions.
1479  *
1480  * @param block Block for which SSA variables have to be renamed.
1481  * @param pRenameState The incremental rename information stored during renaming process.
1482  *
1483  */
1484 void SsaBuilder::BlockPopStacks(BasicBlock* block, SsaRenameState* pRenameState)
1485 {
1486     // Pop the names given to the non-phi nodes.
1487     pRenameState->PopBlockStacks(block);
1488
1489     // And for Heap.
1490     pRenameState->PopBlockHeapStack(block);
1491 }
1492
1493 /**
1494  * Perform variable renaming.
1495  *
1496  * Walks the blocks and renames all var defs with ssa numbers and all uses with the
1497  * current count that is in the top of the stack. Assigns phi node rhs variables
1498  * (i.e., the arguments to the phi.) Then, calls the function recursively on child
1499  * nodes in the DOM tree to continue the renaming process.
1500  *
1501  * @param block Block for which SSA variables have to be renamed.
1502  * @param pRenameState The incremental rename information stored during renaming process.
1503  *
1504  * @remarks At the end of the method, m_uses and m_defs should be populated linking the
1505  *          uses and defs.
1506  *
1507  * @see Briggs, Cooper, Harvey and Simpson "Practical Improvements to the Construction
1508  *      and Destruction of Static Single Assignment Form."
1509  */
1510
1511 void SsaBuilder::RenameVariables(BlkToBlkSetMap* domTree, SsaRenameState* pRenameState)
1512 {
1513     JITDUMP("*************** In SsaBuilder::RenameVariables()\n");
1514
1515     // The first thing we do is treat parameters and must-init variables as if they have a
1516     // virtual definition before entry -- they start out at SSA name 1.
1517     for (unsigned i = 0; i < m_pCompiler->lvaCount; i++)
1518     {
1519         LclVarDsc* varDsc = &m_pCompiler->lvaTable[i];
1520
1521 #ifdef DEBUG
1522         varDsc->lvNumSsaNames = SsaConfig::UNINIT_SSA_NUM; // Start off fresh...
1523 #endif
1524
1525         if (varDsc->lvIsParam || m_pCompiler->info.compInitMem || varDsc->lvMustInit ||
1526             (varDsc->lvTracked &&
1527              VarSetOps::IsMember(m_pCompiler, m_pCompiler->fgFirstBB->bbLiveIn, varDsc->lvVarIndex)))
1528         {
1529             unsigned count = pRenameState->CountForDef(i);
1530
1531             // In ValueNum we'd assume un-inited variables get FIRST_SSA_NUM.
1532             assert(count == SsaConfig::FIRST_SSA_NUM);
1533 #ifdef DEBUG
1534             varDsc->lvNumSsaNames++;
1535 #endif
1536             pRenameState->Push(nullptr, i, count);
1537         }
1538     }
1539     // In ValueNum we'd assume un-inited heap gets FIRST_SSA_NUM.
1540     // The heap is a parameter.  Use FIRST_SSA_NUM as first SSA name.
1541     unsigned initHeapCount = pRenameState->CountForHeapDef();
1542     assert(initHeapCount == SsaConfig::FIRST_SSA_NUM);
1543     pRenameState->PushHeap(m_pCompiler->fgFirstBB, initHeapCount);
1544
1545     // Initialize the heap ssa numbers for unreachable blocks. ValueNum expects
1546     // heap ssa numbers to have some intitial value.
1547     for (BasicBlock* block = m_pCompiler->fgFirstBB; block; block = block->bbNext)
1548     {
1549         if (block->bbIDom == nullptr)
1550         {
1551             block->bbHeapSsaNumIn  = initHeapCount;
1552             block->bbHeapSsaNumOut = initHeapCount;
1553         }
1554     }
1555
1556     struct BlockWork
1557     {
1558         BasicBlock* m_blk;
1559         bool        m_processed; // Whether the this block have already been processed: its var renamed, and children
1560                                  // processed.
1561                                  // If so, awaiting only BlockPopStacks.
1562         BlockWork(BasicBlock* blk, bool processed = false) : m_blk(blk), m_processed(processed)
1563         {
1564         }
1565     };
1566     typedef jitstd::vector<BlockWork> BlockWorkStack;
1567     BlockWorkStack*                   blocksToDo =
1568         new (jitstd::utility::allocate<BlockWorkStack>(m_allocator), jitstd::placement_t()) BlockWorkStack(m_allocator);
1569
1570     blocksToDo->push_back(BlockWork(m_pCompiler->fgFirstBB)); // Probably have to include other roots of dom tree.
1571
1572     while (blocksToDo->size() != 0)
1573     {
1574         BlockWork blockWrk = blocksToDo->back();
1575         blocksToDo->pop_back();
1576         BasicBlock* block = blockWrk.m_blk;
1577
1578         DBG_SSA_JITDUMP("[SsaBuilder::RenameVariables](BB%02u, processed = %d)\n", block->bbNum, blockWrk.m_processed);
1579
1580         if (!blockWrk.m_processed)
1581         {
1582             // Push the block back on the stack with "m_processed" true, to record the fact that when its children have
1583             // been (recursively) processed, we still need to call BlockPopStacks on it.
1584             blocksToDo->push_back(BlockWork(block, true));
1585
1586             // Walk the block give counts to DEFs and give top of stack count for USEs.
1587             BlockRenameVariables(block, pRenameState);
1588
1589             // Assign arguments to the phi node of successors, corresponding to the block's index.
1590             AssignPhiNodeRhsVariables(block, pRenameState);
1591
1592             // Recurse with the block's DOM children.
1593             BlkSet* pBlkSet;
1594             if (domTree->Lookup(block, &pBlkSet))
1595             {
1596                 for (BlkSet::KeyIterator child = pBlkSet->Begin(); !child.Equal(pBlkSet->End()); ++child)
1597                 {
1598                     DBG_SSA_JITDUMP("[SsaBuilder::RenameVariables](pushing dom child BB%02u)\n", child.Get()->bbNum);
1599                     blocksToDo->push_back(BlockWork(child.Get()));
1600                 }
1601             }
1602         }
1603         else
1604         {
1605             // Done, pop all the stack count, if there is one for this block.
1606             BlockPopStacks(block, pRenameState);
1607             DBG_SSA_JITDUMP("[SsaBuilder::RenameVariables] done with BB%02u\n", block->bbNum);
1608         }
1609     }
1610
1611     // Remember the number of Heap SSA names.
1612     m_pCompiler->lvHeapNumSsaNames = pRenameState->HeapCount();
1613 }
1614
1615 #ifdef DEBUG
1616 /**
1617  * Print the blocks, the phi nodes get printed as well.
1618  * @example:
1619  * After SSA BB02:
1620  *                [0027CC0C] -----------                 stmtExpr  void  (IL 0x019...0x01B)
1621  * N001 (  1,  1)       [0027CB70] -----------                 const     int    23
1622  * N003 (  3,  3)    [0027CBD8] -A------R--                 =         int
1623  * N002 (  1,  1)       [0027CBA4] D------N---                 lclVar    int    V01 arg1         d:5
1624  *
1625  * After SSA BB04:
1626  *                [0027D530] -----------                 stmtExpr  void  (IL   ???...  ???)
1627  * N002 (  0,  0)       [0027D4C8] -----------                 phi       int
1628  *                            [0027D8CC] -----------                 lclVar    int    V01 arg1         u:5
1629  *                            [0027D844] -----------                 lclVar    int    V01 arg1         u:4
1630  * N004 (  2,  2)    [0027D4FC] -A------R--                 =         int
1631  * N003 (  1,  1)       [0027D460] D------N---                 lclVar    int    V01 arg1         d:3
1632  */
1633 void SsaBuilder::Print(BasicBlock** postOrder, int count)
1634 {
1635     for (int i = count - 1; i >= 0; --i)
1636     {
1637         printf("After SSA BB%02u:\n", postOrder[i]->bbNum);
1638         m_pCompiler->gtDispTreeList(postOrder[i]->bbTreeList);
1639     }
1640 }
1641 #endif // DEBUG
1642
1643 /**
1644  * Build SSA form.
1645  *
1646  * Sorts the graph topologically.
1647  *   - Collects them in postOrder array.
1648  *
1649  * Identifies each block's immediate dominator.
1650  *   - Computes this in bbIDom of each BasicBlock.
1651  *
1652  * Computes DOM tree relation.
1653  *   - Computes domTree as block -> set of blocks.
1654  *   - Computes pre/post order traversal of the DOM tree.
1655  *
1656  * Inserts phi nodes.
1657  *   - Computes dominance frontier as block -> set of blocks.
1658  *   - Allocates block use/def/livein/liveout and computes it.
1659  *   - Inserts phi nodes with only rhs at the beginning of the blocks.
1660  *
1661  * Renames variables.
1662  *   - Walks blocks in evaluation order and gives uses and defs names.
1663  *   - Gives empty phi nodes their rhs arguments as they become known while renaming.
1664  *
1665  * @return true if successful, for now, this must always be true.
1666  *
1667  * @see "A simple, fast dominance algorithm" by Keith D. Cooper, Timothy J. Harvey, Ken Kennedy.
1668  * @see Briggs, Cooper, Harvey and Simpson "Practical Improvements to the Construction
1669  *      and Destruction of Static Single Assignment Form."
1670  */
1671 void SsaBuilder::Build()
1672 {
1673 #ifdef DEBUG
1674     if (m_pCompiler->verbose)
1675     {
1676         printf("*************** In SsaBuilder::Build()\n");
1677     }
1678 #endif
1679
1680     // Ensure that there's a first block outside a try, so that the dominator tree has a unique root.
1681     SetupBBRoot();
1682
1683     // Just to keep block no. & index same add 1.
1684     int blockCount = m_pCompiler->fgBBNumMax + 1;
1685
1686     JITDUMP("[SsaBuilder] Max block count is %d.\n", blockCount);
1687
1688     // Allocate the postOrder array for the graph.
1689     BasicBlock** postOrder = (BasicBlock**)alloca(blockCount * sizeof(BasicBlock*));
1690
1691     // Topologically sort the graph.
1692     int count = TopologicalSort(postOrder, blockCount);
1693     JITDUMP("[SsaBuilder] Topologically sorted the graph.\n");
1694     EndPhase(PHASE_BUILD_SSA_TOPOSORT);
1695
1696     // Compute IDom(b).
1697     ComputeImmediateDom(postOrder, count);
1698
1699     // Compute the dominator tree.
1700     BlkToBlkSetMap* domTree = new (m_pCompiler->getAllocator()) BlkToBlkSetMap(m_pCompiler->getAllocator());
1701     ComputeDominators(postOrder, count, domTree);
1702     EndPhase(PHASE_BUILD_SSA_DOMS);
1703
1704     // Insert phi functions.
1705     InsertPhiFunctions(postOrder, count);
1706
1707     // Rename local variables and collect UD information for each ssa var.
1708     SsaRenameState* pRenameState = new (jitstd::utility::allocate<SsaRenameState>(m_allocator), jitstd::placement_t())
1709         SsaRenameState(m_allocator, m_pCompiler->lvaCount);
1710     RenameVariables(domTree, pRenameState);
1711     EndPhase(PHASE_BUILD_SSA_RENAME);
1712
1713 #ifdef DEBUG
1714     // At this point we are in SSA form. Print the SSA form.
1715     if (m_pCompiler->verboseSsa)
1716     {
1717         Print(postOrder, count);
1718     }
1719 #endif
1720 }
1721
1722 void SsaBuilder::SetupBBRoot()
1723 {
1724     // Allocate a bbroot, if necessary.
1725     // We need a unique block to be the root of the dominator tree.
1726     // This can be violated if the first block is in a try, or if it is the first block of
1727     // a loop (which would necessarily be an infinite loop) -- i.e., it has a predecessor.
1728
1729     // If neither condition holds, no reason to make a new block.
1730     if (!m_pCompiler->fgFirstBB->hasTryIndex() && m_pCompiler->fgFirstBB->bbPreds == nullptr)
1731     {
1732         return;
1733     }
1734
1735     BasicBlock* bbRoot = m_pCompiler->bbNewBasicBlock(BBJ_NONE);
1736     bbRoot->bbFlags |= BBF_INTERNAL;
1737
1738     // May need to fix up preds list, so remember the old first block.
1739     BasicBlock* oldFirst = m_pCompiler->fgFirstBB;
1740
1741     // Copy the liveness information from the first basic block.
1742     if (m_pCompiler->fgLocalVarLivenessDone)
1743     {
1744         VarSetOps::Assign(m_pCompiler, bbRoot->bbLiveIn, oldFirst->bbLiveIn);
1745         VarSetOps::Assign(m_pCompiler, bbRoot->bbLiveOut, oldFirst->bbLiveIn);
1746     }
1747
1748     // Copy the bbWeight.  (This is technically wrong, if the first block is a loop head, but
1749     // it shouldn't matter...)
1750     bbRoot->inheritWeight(oldFirst);
1751
1752     // There's an artifical incoming reference count for the first BB.  We're about to make it no longer
1753     // the first BB, so decrement that.
1754     assert(oldFirst->bbRefs > 0);
1755     oldFirst->bbRefs--;
1756
1757     m_pCompiler->fgInsertBBbefore(m_pCompiler->fgFirstBB, bbRoot);
1758
1759     assert(m_pCompiler->fgFirstBB == bbRoot);
1760     if (m_pCompiler->fgComputePredsDone)
1761     {
1762         m_pCompiler->fgAddRefPred(oldFirst, bbRoot);
1763     }
1764 }
1765
1766 #ifdef DEBUG
1767 // This method asserts that SSA name constraints specified are satisfied.
1768 void Compiler::JitTestCheckSSA()
1769 {
1770     struct SSAName
1771     {
1772         unsigned m_lvNum;
1773         unsigned m_ssaNum;
1774
1775         static unsigned GetHashCode(SSAName ssaNm)
1776         {
1777             return ssaNm.m_lvNum << 16 | ssaNm.m_ssaNum;
1778         }
1779
1780         static bool Equals(SSAName ssaNm1, SSAName ssaNm2)
1781         {
1782             return ssaNm1.m_lvNum == ssaNm2.m_lvNum && ssaNm1.m_ssaNum == ssaNm2.m_ssaNum;
1783         }
1784     };
1785
1786     typedef SimplerHashTable<ssize_t, SmallPrimitiveKeyFuncs<ssize_t>, SSAName, JitSimplerHashBehavior>
1787         LabelToSSANameMap;
1788     typedef SimplerHashTable<SSAName, SSAName, ssize_t, JitSimplerHashBehavior> SSANameToLabelMap;
1789
1790     // If we have no test data, early out.
1791     if (m_nodeTestData == nullptr)
1792     {
1793         return;
1794     }
1795
1796     NodeToTestDataMap* testData = GetNodeTestData();
1797
1798     // First we have to know which nodes in the tree are reachable.
1799     NodeToIntMap* reachable = FindReachableNodesInNodeTestData();
1800
1801     LabelToSSANameMap* labelToSSA = new (getAllocatorDebugOnly()) LabelToSSANameMap(getAllocatorDebugOnly());
1802     SSANameToLabelMap* ssaToLabel = new (getAllocatorDebugOnly()) SSANameToLabelMap(getAllocatorDebugOnly());
1803
1804     if (verbose)
1805     {
1806         printf("\nJit Testing: SSA names.\n");
1807     }
1808     for (NodeToTestDataMap::KeyIterator ki = testData->Begin(); !ki.Equal(testData->End()); ++ki)
1809     {
1810         TestLabelAndNum tlAndN;
1811         GenTreePtr      node = ki.Get();
1812         bool            b    = testData->Lookup(node, &tlAndN);
1813         assert(b);
1814         if (tlAndN.m_tl == TL_SsaName)
1815         {
1816             if (node->OperGet() != GT_LCL_VAR)
1817             {
1818                 printf("SSAName constraint put on non-lcl-var expression ");
1819                 printTreeID(node);
1820                 printf(" (of type %s).\n", varTypeName(node->TypeGet()));
1821                 unreached();
1822             }
1823             GenTreeLclVarCommon* lcl = node->AsLclVarCommon();
1824
1825             int dummy;
1826             if (!reachable->Lookup(lcl, &dummy))
1827             {
1828                 printf("Node ");
1829                 printTreeID(lcl);
1830                 printf(" had a test constraint declared, but has become unreachable at the time the constraint is "
1831                        "tested.\n"
1832                        "(This is probably as a result of some optimization -- \n"
1833                        "you may need to modify the test case to defeat this opt.)\n");
1834                 unreached();
1835             }
1836
1837             if (verbose)
1838             {
1839                 printf("  Node: ");
1840                 printTreeID(lcl);
1841                 printf(", SSA name = <%d, %d> -- SSA name class %d.\n", lcl->gtLclNum, lcl->gtSsaNum, tlAndN.m_num);
1842             }
1843             SSAName ssaNm;
1844             if (labelToSSA->Lookup(tlAndN.m_num, &ssaNm))
1845             {
1846                 if (verbose)
1847                 {
1848                     printf("      Already in hash tables.\n");
1849                 }
1850                 // The mapping(s) must be one-to-one: if the label has a mapping, then the ssaNm must, as well.
1851                 ssize_t num2;
1852                 bool    b = ssaToLabel->Lookup(ssaNm, &num2);
1853                 // And the mappings must be the same.
1854                 if (tlAndN.m_num != num2)
1855                 {
1856                     printf("Node: ");
1857                     printTreeID(lcl);
1858                     printf(", SSA name = <%d, %d> was declared in SSA name class %d,\n", lcl->gtLclNum, lcl->gtSsaNum,
1859                            tlAndN.m_num);
1860                     printf(
1861                         "but this SSA name <%d,%d> has already been associated with a different SSA name class: %d.\n",
1862                         ssaNm.m_lvNum, ssaNm.m_ssaNum, num2);
1863                     unreached();
1864                 }
1865                 // And the current node must be of the specified SSA family.
1866                 if (!(lcl->gtLclNum == ssaNm.m_lvNum && lcl->gtSsaNum == ssaNm.m_ssaNum))
1867                 {
1868                     printf("Node: ");
1869                     printTreeID(lcl);
1870                     printf(", SSA name = <%d, %d> was declared in SSA name class %d,\n", lcl->gtLclNum, lcl->gtSsaNum,
1871                            tlAndN.m_num);
1872                     printf("but that name class was previously bound to a different SSA name: <%d,%d>.\n",
1873                            ssaNm.m_lvNum, ssaNm.m_ssaNum);
1874                     unreached();
1875                 }
1876             }
1877             else
1878             {
1879                 ssaNm.m_lvNum  = lcl->gtLclNum;
1880                 ssaNm.m_ssaNum = lcl->gtSsaNum;
1881                 ssize_t num;
1882                 // The mapping(s) must be one-to-one: if the label has no mapping, then the ssaNm may not, either.
1883                 if (ssaToLabel->Lookup(ssaNm, &num))
1884                 {
1885                     printf("Node: ");
1886                     printTreeID(lcl);
1887                     printf(", SSA name = <%d, %d> was declared in SSA name class %d,\n", lcl->gtLclNum, lcl->gtSsaNum,
1888                            tlAndN.m_num);
1889                     printf("but this SSA name has already been associated with a different name class: %d.\n", num);
1890                     unreached();
1891                 }
1892                 // Add to both mappings.
1893                 labelToSSA->Set(tlAndN.m_num, ssaNm);
1894                 ssaToLabel->Set(ssaNm, tlAndN.m_num);
1895                 if (verbose)
1896                 {
1897                     printf("      added to hash tables.\n");
1898                 }
1899             }
1900         }
1901     }
1902 }
1903 #endif // DEBUG