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.
7 #include "ssarenamestate.h"
8 #include "ssabuilder.h"
13 * Method that finds a common IDom parent, much like least common ancestor.
15 * @param finger1 A basic block that might share IDom ancestor with finger2.
16 * @param finger2 A basic block that might share IDom ancestor with finger1.
18 * @see "A simple, fast dominance algorithm" by Keith D. Cooper, Timothy J. Harvey, Ken Kennedy.
20 * @return A basic block whose IDom is the dominator for finger1 and finger2,
21 * or else NULL. This may be called while immediate dominators are being
22 * computed, and if the input values are members of the same loop (each reachable from the other),
23 * then one may not yet have its immediate dominator computed when we are attempting
24 * to find the immediate dominator of the other. So a NULL return value means that the
25 * the two inputs are in a cycle, not that they don't have a common dominator ancestor.
27 static inline BasicBlock* IntersectDom(BasicBlock* finger1, BasicBlock* finger2)
29 while (finger1 != finger2)
31 if (finger1 == nullptr || finger2 == nullptr)
35 while (finger1 != nullptr && finger1->bbPostOrderNum < finger2->bbPostOrderNum)
37 finger1 = finger1->bbIDom;
39 if (finger1 == nullptr)
43 while (finger2 != nullptr && finger2->bbPostOrderNum < finger1->bbPostOrderNum)
45 finger2 = finger2->bbIDom;
51 } // end of anonymous namespace.
53 // =================================================================================
55 // =================================================================================
57 void Compiler::fgSsaBuild()
59 // If this is not the first invocation, reset data structures for SSA.
60 if (fgSsaPassesCompleted > 0)
65 SsaBuilder builder(this);
67 fgSsaPassesCompleted++;
75 JITDUMP("\nAfter fgSsaBuild:\n");
76 fgDispBasicBlocks(/*dumpTrees*/ true);
81 void Compiler::fgResetForSsa()
83 for (unsigned i = 0; i < lvaCount; ++i)
85 lvaTable[i].lvPerSsaData.Reset();
87 lvMemoryPerSsaData.Reset();
88 for (MemoryKind memoryKind : allMemoryKinds())
90 m_memorySsaMap[memoryKind] = nullptr;
93 for (BasicBlock* blk = fgFirstBB; blk != nullptr; blk = blk->bbNext)
96 for (MemoryKind memoryKind : allMemoryKinds())
98 blk->bbMemorySsaPhiFunc[memoryKind] = nullptr;
100 if (blk->bbTreeList != nullptr)
102 GenTree* last = blk->bbTreeList->gtPrev;
103 blk->bbTreeList = blk->FirstNonPhiDef();
104 if (blk->bbTreeList != nullptr)
106 blk->bbTreeList->gtPrev = last;
110 // Clear post-order numbers and SSA numbers; SSA construction will overwrite these,
111 // but only for reachable code, so clear them to avoid analysis getting confused
112 // by stale annotations in unreachable code.
113 blk->bbPostOrderNum = 0;
114 for (GenTreeStmt* stmt = blk->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
116 for (GenTree* tree = stmt->gtStmt.gtStmtList; tree != nullptr; tree = tree->gtNext)
120 tree->gtLclVarCommon.SetSsaNum(SsaConfig::RESERVED_SSA_NUM);
124 Compiler::IndirectAssignmentAnnotation* pIndirAssign = nullptr;
125 if ((tree->OperGet() != GT_ASG) || !GetIndirAssignMap()->Lookup(tree, &pIndirAssign) ||
126 (pIndirAssign == nullptr))
131 pIndirAssign->m_defSsaNum = SsaConfig::RESERVED_SSA_NUM;
132 pIndirAssign->m_useSsaNum = SsaConfig::RESERVED_SSA_NUM;
139 * Constructor for the SSA builder.
141 * @param pCompiler Current compiler instance.
143 * @remarks Initializes the class and member pointers/objects that use constructors.
145 SsaBuilder::SsaBuilder(Compiler* pCompiler)
146 : m_pCompiler(pCompiler)
147 , m_allocator(pCompiler, CMK_SSA)
148 , m_visitedTraits(0, pCompiler) // at this point we do not know the size, SetupBBRoot can add a block
149 #ifdef SSA_FEATURE_DOMARR
150 , m_pDomPreOrder(nullptr)
151 , m_pDomPostOrder(nullptr)
156 //------------------------------------------------------------------------
157 // TopologicalSort: Topologically sort the graph and return the number of nodes visited.
160 // postOrder - The array in which the arranged basic blocks have to be returned.
161 // count - The size of the postOrder array.
164 // The number of nodes visited while performing DFS on the graph.
166 int SsaBuilder::TopologicalSort(BasicBlock** postOrder, int count)
168 Compiler* comp = m_pCompiler;
170 // TopologicalSort is called first so m_visited should already be empty
171 assert(BitVecOps::IsEmpty(&m_visitedTraits, m_visited));
173 // Display basic blocks.
174 DBEXEC(VERBOSE, comp->fgDispBasicBlocks());
175 DBEXEC(VERBOSE, comp->fgDispHandlerTab());
179 BasicBlock* block = comp->fgFirstBB;
180 BitVecOps::AddElemD(&m_visitedTraits, m_visited, block->bbNum);
182 ArrayStack<BasicBlock*> blocks(comp);
183 ArrayStack<AllSuccessorIter> iterators(comp);
184 ArrayStack<AllSuccessorIter> ends(comp);
186 // there are three stacks used here and all should be same height
187 // the first is for blocks
188 // the second is the iterator to keep track of what succ of the block we are looking at
189 // and the third is the end marker iterator
191 iterators.Push(block->GetAllSuccs(comp).begin());
192 ends.Push(block->GetAllSuccs(comp).end());
194 while (blocks.Height() > 0)
196 block = blocks.Top();
199 if (comp->verboseSsa)
201 printf("[SsaBuilder::TopologicalSort] Visiting BB%02u: ", block->bbNum);
203 unsigned numSucc = block->NumSucc(comp);
204 for (unsigned i = 0; i < numSucc; ++i)
206 printf("BB%02u, ", block->GetSucc(i, comp)->bbNum);
208 EHSuccessorIter end = block->GetEHSuccs(comp).end();
209 for (EHSuccessorIter ehsi = block->GetEHSuccs(comp).begin(); ehsi != end; ++ehsi)
211 printf("[EH]BB%02u, ", (*ehsi)->bbNum);
217 if (iterators.TopRef() != ends.TopRef())
219 // if the block on TOS still has unreached successors, visit them
220 AllSuccessorIter& iter = iterators.TopRef();
221 BasicBlock* succ = *iter;
225 if (BitVecOps::TryAddElemD(&m_visitedTraits, m_visited, succ->bbNum))
228 iterators.Push(succ->GetAllSuccs(comp).begin());
229 ends.Push(succ->GetAllSuccs(comp).end());
234 // all successors have been visited
239 postOrder[postIndex] = block;
240 block->bbPostOrderNum = postIndex;
243 DBG_SSA_JITDUMP("postOrder[%d] = %s\n", postIndex, block->dspToString());
247 // In the absence of EH (because catch/finally have no preds), this should be valid.
248 // assert(postIndex == (count - 1));
254 * Computes the immediate dominator IDom for each block iteratively.
256 * @param postOrder The array of basic blocks arranged in postOrder.
257 * @param count The size of valid elements in the postOrder array.
259 * @see "A simple, fast dominance algorithm." paper.
261 void SsaBuilder::ComputeImmediateDom(BasicBlock** postOrder, int count)
263 JITDUMP("[SsaBuilder::ComputeImmediateDom]\n");
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)
269 blk->bbIDom = nullptr;
272 // Add entry point to visited as its IDom is NULL.
273 BitVecOps::ClearD(&m_visitedTraits, m_visited);
274 BitVecOps::AddElemD(&m_visitedTraits, m_visited, m_pCompiler->fgFirstBB->bbNum);
276 assert(postOrder[count - 1] == m_pCompiler->fgFirstBB);
283 // In reverse post order, except for the entry block (count - 1 is entry BB).
284 for (int i = count - 2; i >= 0; --i)
286 BasicBlock* block = postOrder[i];
288 DBG_SSA_JITDUMP("Visiting in reverse post order: BB%02u.\n", block->bbNum);
290 // Find the first processed predecessor block.
291 BasicBlock* predBlock = nullptr;
292 for (flowList* pred = m_pCompiler->BlockPredsWithEH(block); pred; pred = pred->flNext)
294 if (BitVecOps::IsMember(&m_visitedTraits, m_visited, pred->flBlock->bbNum))
296 predBlock = pred->flBlock;
301 // There could just be a single basic block, so just check if there were any preds.
302 if (predBlock != nullptr)
304 DBG_SSA_JITDUMP("Pred block is BB%02u.\n", predBlock->bbNum);
307 // Intersect DOM, if computed, for all predecessors.
308 BasicBlock* bbIDom = predBlock;
309 for (flowList* pred = m_pCompiler->BlockPredsWithEH(block); pred; pred = pred->flNext)
311 if (predBlock != pred->flBlock)
313 BasicBlock* domAncestor = IntersectDom(pred->flBlock, bbIDom);
314 // The result may be NULL if "block" and "pred->flBlock" are part of a
315 // cycle -- neither is guaranteed ordered wrt the other in reverse postorder,
316 // so we may be computing the IDom of "block" before the IDom of "pred->flBlock" has
317 // been computed. But that's OK -- if they're in a cycle, they share the same immediate
318 // dominator, so the contribution of "pred->flBlock" is not necessary to compute
320 if (domAncestor != nullptr)
322 bbIDom = domAncestor;
327 // Did we change the bbIDom value? If so, we go around the outer loop again.
328 if (block->bbIDom != bbIDom)
332 // IDom has changed, update it.
333 DBG_SSA_JITDUMP("bbIDom of BB%02u becomes BB%02u.\n", block->bbNum, bbIDom ? bbIDom->bbNum : 0);
334 block->bbIDom = bbIDom;
337 // Mark the current block as visited.
338 BitVecOps::AddElemD(&m_visitedTraits, m_visited, block->bbNum);
340 DBG_SSA_JITDUMP("Marking block BB%02u as processed.\n", block->bbNum);
345 #ifdef SSA_FEATURE_DOMARR
347 * Walk the DOM tree and compute pre and post-order arrangement of the tree.
349 * @param curBlock The current block being operated on at some recursive level.
350 * @param domTree The DOM tree as a map (block -> set of child blocks.)
351 * @param preIndex The initial index given to the first block visited in pre order.
352 * @param postIndex The initial index given to the first block visited in post order.
354 * @remarks This would help us answer queries such as "a dom b?" in constant time.
355 * For example, if a dominated b, then Pre[a] < Pre[b] but Post[a] > Post[b]
357 void SsaBuilder::DomTreeWalk(BasicBlock* curBlock, BlkToBlkSetMap* domTree, int* preIndex, int* postIndex)
359 JITDUMP("[SsaBuilder::DomTreeWalk] block %s:\n", curBlock->dspToString());
361 // Store the order number at the block number in the pre order list.
362 m_pDomPreOrder[curBlock->bbNum] = *preIndex;
366 if (domTree->Lookup(curBlock, &pBlkSet))
368 for (BlkSet::KeyIterator ki = pBlkSet->Begin(); !ki.Equal(pBlkSet->End()); ++ki)
370 if (curBlock != ki.Get())
372 DomTreeWalk(ki.Get(), domTree, preIndex, postIndex);
377 // Store the order number at the block number in the post order list.
378 m_pDomPostOrder[curBlock->bbNum] = *postIndex;
384 * Using IDom of each basic block, add a mapping from block->IDom -> block.
385 * @param pCompiler Compiler instance
386 * @param block The basic block that will become the child node of it's iDom.
387 * @param domTree The output domTree which will hold the mapping "block->bbIDom" -> "block"
391 void SsaBuilder::ConstructDomTreeForBlock(Compiler* pCompiler, BasicBlock* block, BlkToBlkSetMap* domTree)
393 BasicBlock* bbIDom = block->bbIDom;
395 // bbIDom for (only) fgFirstBB will be NULL.
396 if (bbIDom == nullptr)
401 // If the bbIDom map key doesn't exist, create one.
403 if (!domTree->Lookup(bbIDom, &pBlkSet))
405 pBlkSet = new (domTree->GetAllocator()) BlkSet(domTree->GetAllocator());
406 domTree->Set(bbIDom, pBlkSet);
409 DBG_SSA_JITDUMP("Inserting BB%02u as dom child of BB%02u.\n", block->bbNum, bbIDom->bbNum);
410 // Insert the block into the block's set.
411 pBlkSet->Set(block, true);
415 * Using IDom of each basic block, compute the whole tree. If a block "b" has IDom "i",
416 * then, block "b" is dominated by "i". The mapping then is i -> { ..., b, ... }, in
417 * other words, "domTree" is a tree represented by nodes mapped to their children.
419 * @param pCompiler Compiler instance
420 * @param domTree The output domTree which will hold the mapping "block->bbIDom" -> "block"
424 void SsaBuilder::ComputeDominators(Compiler* pCompiler, BlkToBlkSetMap* domTree)
426 JITDUMP("*************** In SsaBuilder::ComputeDominators(Compiler*, ...)\n");
428 // Construct the DOM tree from bbIDom
429 for (BasicBlock* block = pCompiler->fgFirstBB; block != nullptr; block = block->bbNext)
431 ConstructDomTreeForBlock(pCompiler, block, domTree);
434 DBEXEC(pCompiler->verboseSsa, DisplayDominators(domTree));
438 * Compute the DOM tree into a map(block -> set of blocks) adjacency representation.
440 * Using IDom of each basic block, compute the whole tree. If a block "b" has IDom "i",
441 * then, block "b" is dominated by "i". The mapping then is i -> { ..., b, ... }
443 * @param postOrder The array of basic blocks arranged in postOrder.
444 * @param count The size of valid elements in the postOrder array.
445 * @param domTree A map of (block -> set of blocks) tree representation that is empty.
448 void SsaBuilder::ComputeDominators(BasicBlock** postOrder, int count, BlkToBlkSetMap* domTree)
450 JITDUMP("*************** In SsaBuilder::ComputeDominators(BasicBlock** postOrder, int count, ...)\n");
452 // Construct the DOM tree from bbIDom
453 for (int i = 0; i < count; ++i)
455 ConstructDomTreeForBlock(m_pCompiler, postOrder[i], domTree);
458 DBEXEC(m_pCompiler->verboseSsa, DisplayDominators(domTree));
460 #ifdef SSA_FEATURE_DOMARR
461 // Allocate space for constant time computation of (a DOM b?) query.
462 unsigned bbArrSize = m_pCompiler->fgBBNumMax + 1; // We will use 1-based bbNums as indices into these arrays, so
464 m_pDomPreOrder = new (&m_allocator) int[bbArrSize];
465 m_pDomPostOrder = new (&m_allocator) int[bbArrSize];
471 // Populate the pre and post order of the tree.
472 DomTreeWalk(m_pCompiler->fgFirstBB, domTree, &preIndex, &postIndex);
479 * Display the DOM tree.
481 * @param domTree A map of (block -> set of blocks) tree representation.
484 void SsaBuilder::DisplayDominators(BlkToBlkSetMap* domTree)
486 printf("After computing dominator tree: \n");
487 for (BlkToBlkSetMap::KeyIterator nodes = domTree->Begin(); !nodes.Equal(domTree->End()); ++nodes)
489 printf("BB%02u := {", nodes.Get()->bbNum);
491 BlkSet* pBlkSet = nodes.GetValue();
492 for (BlkSet::KeyIterator ki = pBlkSet->Begin(); !ki.Equal(pBlkSet->End()); ++ki)
494 if (!ki.Equal(pBlkSet->Begin()))
498 printf("BB%02u", ki.Get()->bbNum);
506 //------------------------------------------------------------------------
507 // ComputeDominanceFrontiers: Compute flow graph dominance frontiers
510 // postOrder - an array containing all flow graph blocks
511 // count - the number of blocks in the postOrder array
512 // mapDF - a caller provided hashtable that will be populated
513 // with blocks and their dominance frontiers (only those
514 // blocks that have non-empty frontiers will be included)
517 // Recall that the dominance frontier of a block B is the set of blocks
518 // B3 such that there exists some B2 s.t. B3 is a successor of B2, and
519 // B dominates B2. Note that this dominance need not be strict -- B2
520 // and B may be the same node.
521 // See "A simple, fast dominance algorithm", by Cooper, Harvey, and Kennedy.
523 void SsaBuilder::ComputeDominanceFrontiers(BasicBlock** postOrder, int count, BlkToBlkVectorMap* mapDF)
525 DBG_SSA_JITDUMP("Computing DF:\n");
527 for (int i = 0; i < count; ++i)
529 BasicBlock* block = postOrder[i];
531 DBG_SSA_JITDUMP("Considering block BB%02u.\n", block->bbNum);
533 // Recall that B3 is in the dom frontier of B1 if there exists a B2
534 // such that B1 dom B2, !(B1 dom B3), and B3 is an immediate successor
535 // of B2. (Note that B1 might be the same block as B2.)
536 // In that definition, we're considering "block" to be B3, and trying
537 // to find B1's. To do so, first we consider the predecessors of "block",
538 // searching for candidate B2's -- "block" is obviously an immediate successor
539 // of its immediate predecessors. If there are zero or one preds, then there
540 // is no pred, or else the single pred dominates "block", so no B2 exists.
542 flowList* blockPreds = m_pCompiler->BlockPredsWithEH(block);
544 // If block has 0/1 predecessor, skip.
545 if ((blockPreds == nullptr) || (blockPreds->flNext == nullptr))
547 DBG_SSA_JITDUMP(" Has %d preds; skipping.\n", blockPreds == nullptr ? 0 : 1);
551 // Otherwise, there are > 1 preds. Each is a candidate B2 in the definition --
552 // *unless* it dominates "block"/B3.
554 for (flowList* pred = blockPreds; pred != nullptr; pred = pred->flNext)
556 DBG_SSA_JITDUMP(" Considering predecessor BB%02u.\n", pred->flBlock->bbNum);
558 // If we've found a B2, then consider the possible B1's. We start with
559 // B2, since a block dominates itself, then traverse upwards in the dominator
560 // tree, stopping when we reach the root, or the immediate dominator of "block"/B3.
561 // (Note that we are guaranteed to encounter this immediate dominator of "block"/B3:
562 // a predecessor must be dominated by B3's immediate dominator.)
563 // Along this way, make "block"/B3 part of the dom frontier of the B1.
564 // When we reach this immediate dominator, the definition no longer applies, since this
565 // potential B1 *does* dominate "block"/B3, so we stop.
566 for (BasicBlock* b1 = pred->flBlock; (b1 != nullptr) && (b1 != block->bbIDom); // !root && !loop
569 DBG_SSA_JITDUMP(" Adding BB%02u to dom frontier of pred dom BB%02u.\n", block->bbNum, b1->bbNum);
571 BlkVector& b1DF = *mapDF->Emplace(b1, &m_allocator);
572 // It's possible to encounter the same DF multiple times, ensure that we don't add duplicates.
573 if (b1DF.empty() || (b1DF.back() != block))
575 b1DF.push_back(block);
582 if (m_pCompiler->verboseSsa)
584 printf("\nComputed DF:\n");
585 for (int i = 0; i < count; ++i)
587 BasicBlock* b = postOrder[i];
588 printf("Block BB%02u := {", b->bbNum);
590 BlkVector* bDF = mapDF->LookupPointer(b);
594 for (BasicBlock* f : *bDF)
596 printf("%sBB%02u", (index++ == 0) ? "" : ",", f->bbNum);
605 //------------------------------------------------------------------------
606 // ComputeIteratedDominanceFrontier: Compute the iterated dominance frontier
607 // for the specified block.
610 // b - the block to computed the frontier for
611 // mapDF - a map containing the dominance frontiers of all blocks
612 // bIDF - a caller provided vector where the IDF is to be stored
615 // The iterated dominance frontier is formed by a closure operation:
616 // the IDF of B is the smallest set that includes B's dominance frontier,
617 // and also includes the dominance frontier of all elements of the set.
619 void SsaBuilder::ComputeIteratedDominanceFrontier(BasicBlock* b, const BlkToBlkVectorMap* mapDF, BlkVector* bIDF)
621 assert(bIDF->empty());
623 BlkVector* bDF = mapDF->LookupPointer(b);
627 // Compute IDF(b) - start by adding DF(b) to IDF(b).
628 bIDF->reserve(bDF->size());
629 BitVecOps::ClearD(&m_visitedTraits, m_visited);
631 for (BasicBlock* f : *bDF)
633 BitVecOps::AddElemD(&m_visitedTraits, m_visited, f->bbNum);
637 // Now for each block f from IDF(b) add DF(f) to IDF(b). This may result in new
638 // blocks being added to IDF(b) and the process repeats until no more new blocks
639 // are added. Note that since we keep adding to bIDF we can't use iterators as
640 // they may get invalidated. This happens to be a convenient way to avoid having
641 // to track newly added blocks in a separate set.
642 for (size_t newIndex = 0; newIndex < bIDF->size(); newIndex++)
644 BasicBlock* f = (*bIDF)[newIndex];
645 BlkVector* fDF = mapDF->LookupPointer(f);
649 for (BasicBlock* ff : *fDF)
651 if (BitVecOps::TryAddElemD(&m_visitedTraits, m_visited, ff->bbNum))
661 if (m_pCompiler->verboseSsa)
663 printf("IDF(BB%02u) := {", b->bbNum);
665 for (BasicBlock* f : *bIDF)
667 printf("%sBB%02u", (index++ == 0) ? "" : ",", f->bbNum);
675 * Returns the phi GT_PHI node if the variable already has a phi node.
677 * @param block The block for which the existence of a phi node needs to be checked.
678 * @param lclNum The lclNum for which the occurrence of a phi node needs to be checked.
680 * @return If there is a phi node for the lclNum, returns the GT_PHI tree, else NULL.
682 static GenTree* GetPhiNode(BasicBlock* block, unsigned lclNum)
684 // Walk the statements for phi nodes.
685 for (GenTree* stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
687 // A prefix of the statements of the block are phi definition nodes. If we complete processing
688 // that prefix, exit.
689 if (!stmt->IsPhiDefnStmt())
694 GenTree* tree = stmt->gtStmt.gtStmtExpr;
696 GenTree* phiLhs = tree->gtOp.gtOp1;
697 assert(phiLhs->OperGet() == GT_LCL_VAR);
698 if (phiLhs->gtLclVarCommon.gtLclNum == lclNum)
700 return tree->gtOp.gtOp2;
707 * Inserts phi functions at DF(b) for variables v that are live after the phi
708 * insertion point i.e., v in live-in(b).
710 * To do so, the function computes liveness, dominance frontier and inserts a phi node,
711 * if we have var v in def(b) and live-in(l) and l is in DF(b).
713 * @param postOrder The array of basic blocks arranged in postOrder.
714 * @param count The size of valid elements in the postOrder array.
716 void SsaBuilder::InsertPhiFunctions(BasicBlock** postOrder, int count)
718 JITDUMP("*************** In SsaBuilder::InsertPhiFunctions()\n");
720 // Compute liveness on the graph.
721 m_pCompiler->fgLocalVarLiveness();
722 EndPhase(PHASE_BUILD_SSA_LIVENESS);
724 // Compute dominance frontier.
725 BlkToBlkVectorMap mapDF(&m_allocator);
726 ComputeDominanceFrontiers(postOrder, count, &mapDF);
727 EndPhase(PHASE_BUILD_SSA_DF);
729 // Use the same IDF vector for all blocks to avoid unnecessary memory allocations
730 BlkVector blockIDF(&m_allocator);
732 JITDUMP("Inserting phi functions:\n");
734 for (int i = 0; i < count; ++i)
736 BasicBlock* block = postOrder[i];
737 DBG_SSA_JITDUMP("Considering dominance frontier of block BB%02u:\n", block->bbNum);
740 ComputeIteratedDominanceFrontier(block, &mapDF, &blockIDF);
742 if (blockIDF.empty())
747 // For each local var number "lclNum" that "block" assigns to...
748 VarSetOps::Iter defVars(m_pCompiler, block->bbVarDef);
749 unsigned varIndex = 0;
750 while (defVars.NextElem(&varIndex))
752 unsigned lclNum = m_pCompiler->lvaTrackedToVarNum[varIndex];
753 DBG_SSA_JITDUMP(" Considering local var V%02u:\n", lclNum);
755 if (m_pCompiler->fgExcludeFromSsa(lclNum))
757 DBG_SSA_JITDUMP(" Skipping because it is excluded.\n");
761 // For each block "bbInDomFront" that is in the dominance frontier of "block"...
762 for (BasicBlock* bbInDomFront : blockIDF)
764 DBG_SSA_JITDUMP(" Considering BB%02u in dom frontier of BB%02u:\n", bbInDomFront->bbNum,
767 // Check if variable "lclNum" is live in block "*iterBlk".
768 if (!VarSetOps::IsMember(m_pCompiler, bbInDomFront->bbLiveIn, varIndex))
773 // Check if we've already inserted a phi node.
774 if (GetPhiNode(bbInDomFront, lclNum) == nullptr)
776 // We have a variable i that is defined in block j and live at l, and l belongs to dom frontier of
777 // j. So insert a phi node at l.
778 JITDUMP("Inserting phi definition for V%02u at start of BB%02u.\n", lclNum, bbInDomFront->bbNum);
780 GenTree* phiLhs = m_pCompiler->gtNewLclvNode(lclNum, m_pCompiler->lvaTable[lclNum].TypeGet());
782 // Create 'phiRhs' as a GT_PHI node for 'lclNum', it will eventually hold a GT_LIST of GT_PHI_ARG
783 // nodes. However we have to construct this list so for now the gtOp1 of 'phiRhs' is a nullptr.
784 // It will get replaced with a GT_LIST of GT_PHI_ARG nodes in
785 // SsaBuilder::AssignPhiNodeRhsVariables() and in SsaBuilder::AddDefToHandlerPhis()
788 m_pCompiler->gtNewOperNode(GT_PHI, m_pCompiler->lvaTable[lclNum].TypeGet(), nullptr);
790 GenTree* phiAsg = m_pCompiler->gtNewAssignNode(phiLhs, phiRhs);
792 GenTree* stmt = m_pCompiler->fgInsertStmtAtBeg(bbInDomFront, phiAsg);
793 m_pCompiler->gtSetStmtInfo(stmt);
794 m_pCompiler->fgSetStmtSeq(stmt);
799 // Now make a similar phi definition if the block defines memory.
800 if (block->bbMemoryDef != 0)
802 // For each block "bbInDomFront" that is in the dominance frontier of "block".
803 for (BasicBlock* bbInDomFront : blockIDF)
805 DBG_SSA_JITDUMP(" Considering BB%02u in dom frontier of BB%02u for Memory phis:\n",
806 bbInDomFront->bbNum, block->bbNum);
808 for (MemoryKind memoryKind : allMemoryKinds())
810 if ((memoryKind == GcHeap) && m_pCompiler->byrefStatesMatchGcHeapStates)
812 // Share the PhiFunc with ByrefExposed.
813 assert(memoryKind > ByrefExposed);
814 bbInDomFront->bbMemorySsaPhiFunc[memoryKind] = bbInDomFront->bbMemorySsaPhiFunc[ByrefExposed];
818 // Check if this memoryKind is defined in this block.
819 if ((block->bbMemoryDef & memoryKindSet(memoryKind)) == 0)
824 // Check if memoryKind is live into block "*iterBlk".
825 if ((bbInDomFront->bbMemoryLiveIn & memoryKindSet(memoryKind)) == 0)
830 // Check if we've already inserted a phi node.
831 if (bbInDomFront->bbMemorySsaPhiFunc[memoryKind] == nullptr)
833 // We have a variable i that is defined in block j and live at l, and l belongs to dom frontier
835 // j. So insert a phi node at l.
836 JITDUMP("Inserting phi definition for %s at start of BB%02u.\n", memoryKindNames[memoryKind],
837 bbInDomFront->bbNum);
838 bbInDomFront->bbMemorySsaPhiFunc[memoryKind] = BasicBlock::EmptyMemoryPhiDef;
844 EndPhase(PHASE_BUILD_SSA_INSERT_PHIS);
848 * Record a def point of a variable.
850 * The def point is just the tree that is a local variable def.
852 * @param tree Tree node where an SSA variable is def'ed.
854 * @remarks The result is in the m_defs map :: [lclNum, ssaNum] -> tree.
856 void SsaBuilder::AddDefPoint(GenTree* tree, BasicBlock* blk)
858 Compiler::IndirectAssignmentAnnotation* pIndirAnnot;
859 // In the case of an "indirect assignment", where the LHS is IND of a byref to the local actually being assigned,
860 // we make the ASG tree the def point.
861 assert(tree->IsLocal() || IsIndirectAssign(tree, &pIndirAnnot));
866 lclNum = tree->gtLclVarCommon.gtLclNum;
867 defSsaNum = m_pCompiler->GetSsaNumForLocalVarDef(tree);
871 bool b = m_pCompiler->GetIndirAssignMap()->Lookup(tree, &pIndirAnnot);
873 lclNum = pIndirAnnot->m_lclNum;
874 defSsaNum = pIndirAnnot->m_defSsaNum;
877 // Record that there's a new SSA def.
878 m_pCompiler->lvaTable[lclNum].lvNumSsaNames++;
880 // Record where the defn happens.
881 LclSsaVarDsc* ssaDef = m_pCompiler->lvaTable[lclNum].GetPerSsaData(defSsaNum);
882 ssaDef->m_defLoc.m_blk = blk;
883 ssaDef->m_defLoc.m_tree = tree;
886 bool SsaBuilder::IsIndirectAssign(GenTree* tree, Compiler::IndirectAssignmentAnnotation** ppIndirAssign)
888 return tree->OperGet() == GT_ASG && m_pCompiler->m_indirAssignMap != nullptr &&
889 m_pCompiler->GetIndirAssignMap()->Lookup(tree, ppIndirAssign);
893 * Rename the local variable tree node.
895 * If the given tree node is a local variable, then for a def give a new count, if use,
896 * then give the count in the top of stack, i.e., current count (used for last def.)
898 * @param tree Tree node where an SSA variable is used or def'ed.
899 * @param pRenameState The incremental rename information stored during renaming process.
901 * @remarks This method has to maintain parity with TreePopStacks corresponding to pushes
904 void SsaBuilder::TreeRenameVariables(GenTree* tree, BasicBlock* block, SsaRenameState* pRenameState, bool isPhiDefn)
906 // This is perhaps temporary -- maybe should be done elsewhere. Label GT_INDs on LHS of assignments, so we
907 // can skip these during (at least) value numbering.
908 if (tree->OperIsAssignment())
910 GenTree* lhs = tree->gtOp.gtOp1->gtEffectiveVal(/*commaOnly*/ true);
911 GenTree* trueLhs = lhs->gtEffectiveVal(/*commaOnly*/ true);
912 if (trueLhs->OperIsIndir())
914 trueLhs->gtFlags |= GTF_IND_ASG_LHS;
916 else if (trueLhs->OperGet() == GT_CLS_VAR)
918 trueLhs->gtFlags |= GTF_CLS_VAR_ASG_LHS;
922 // Figure out if "tree" may make a new GC heap state (if we care for this block).
923 if ((block->bbMemoryHavoc & memoryKindSet(GcHeap)) == 0)
925 if (tree->OperIsAssignment() || tree->OperIsBlkOp())
927 if (m_pCompiler->ehBlockHasExnFlowDsc(block))
929 GenTreeLclVarCommon* lclVarNode;
931 bool isLocal = tree->DefinesLocal(m_pCompiler, &lclVarNode);
932 bool isAddrExposedLocal = isLocal && m_pCompiler->lvaVarAddrExposed(lclVarNode->gtLclNum);
933 bool hasByrefHavoc = ((block->bbMemoryHavoc & memoryKindSet(ByrefExposed)) != 0);
934 if (!isLocal || (isAddrExposedLocal && !hasByrefHavoc))
936 // It *may* define byref memory in a non-havoc way. Make a new SSA # -- associate with this node.
937 unsigned count = pRenameState->CountForMemoryDef();
940 pRenameState->PushMemory(ByrefExposed, block, count);
941 m_pCompiler->GetMemorySsaMap(ByrefExposed)->Set(tree, count);
943 if (JitTls::GetCompiler()->verboseSsa)
946 Compiler::printTreeID(tree);
947 printf(" (in try block) may define memory; ssa # = %d.\n", count);
951 // Now add this SSA # to all phis of the reachable catch blocks.
952 AddMemoryDefToHandlerPhis(ByrefExposed, block, count);
957 // Add a new def for GcHeap as well
958 if (m_pCompiler->byrefStatesMatchGcHeapStates)
960 // GcHeap and ByrefExposed share the same stacks, SsaMap, and phis
961 assert(!hasByrefHavoc);
962 assert(pRenameState->CountForMemoryUse(GcHeap) == count);
963 assert(*m_pCompiler->GetMemorySsaMap(GcHeap)->LookupPointer(tree) == count);
964 assert(block->bbMemorySsaPhiFunc[GcHeap] == block->bbMemorySsaPhiFunc[ByrefExposed]);
970 // Allocate a distinct defnum for the GC Heap
971 count = pRenameState->CountForMemoryDef();
974 pRenameState->PushMemory(GcHeap, block, count);
975 m_pCompiler->GetMemorySsaMap(GcHeap)->Set(tree, count);
976 AddMemoryDefToHandlerPhis(GcHeap, block, count);
984 Compiler::IndirectAssignmentAnnotation* pIndirAssign = nullptr;
985 if (!tree->IsLocal() && !IsIndirectAssign(tree, &pIndirAssign))
990 if (pIndirAssign != nullptr)
992 unsigned lclNum = pIndirAssign->m_lclNum;
993 // Is this a variable we exclude from SSA?
994 if (m_pCompiler->fgExcludeFromSsa(lclNum))
996 pIndirAssign->m_defSsaNum = SsaConfig::RESERVED_SSA_NUM;
1000 if (!pIndirAssign->m_isEntire)
1002 pIndirAssign->m_useSsaNum = pRenameState->CountForUse(lclNum);
1004 unsigned count = pRenameState->CountForDef(lclNum);
1005 pIndirAssign->m_defSsaNum = count;
1006 pRenameState->Push(block, lclNum, count);
1007 AddDefPoint(tree, block);
1011 unsigned lclNum = tree->gtLclVarCommon.gtLclNum;
1012 // Is this a variable we exclude from SSA?
1013 if (m_pCompiler->fgExcludeFromSsa(lclNum))
1015 tree->gtLclVarCommon.SetSsaNum(SsaConfig::RESERVED_SSA_NUM);
1019 if (tree->gtFlags & GTF_VAR_DEF)
1021 if (tree->gtFlags & GTF_VAR_USEASG)
1023 // This the "x" in something like "x op= y"; it is both a use (first), then a def.
1024 // The def will define a new SSA name, and record that in "x". If we need the SSA
1025 // name of the use, we record it in a map reserved for that purpose.
1026 unsigned count = pRenameState->CountForUse(lclNum);
1027 tree->gtLclVarCommon.SetSsaNum(count);
1030 // Give a count and increment.
1031 unsigned count = pRenameState->CountForDef(lclNum);
1032 if (tree->gtFlags & GTF_VAR_USEASG)
1034 m_pCompiler->GetOpAsgnVarDefSsaNums()->Set(tree, count);
1038 tree->gtLclVarCommon.SetSsaNum(count);
1040 pRenameState->Push(block, lclNum, count);
1041 AddDefPoint(tree, block);
1043 // If necessary, add "lclNum/count" to the arg list of a phi def in any
1044 // handlers for try blocks that "block" is within. (But only do this for "real" definitions,
1045 // not phi definitions.)
1048 AddDefToHandlerPhis(block, lclNum, count);
1051 else if (!isPhiDefn) // Phi args already have ssa numbers.
1053 // This case is obviated by the short-term "early-out" above...but it's in the right direction.
1054 // Is it a promoted struct local?
1055 if (m_pCompiler->lvaTable[lclNum].lvPromoted)
1057 assert(tree->TypeGet() == TYP_STRUCT);
1058 LclVarDsc* varDsc = &m_pCompiler->lvaTable[lclNum];
1059 // If has only a single field var, treat this as a use of that field var.
1060 // Otherwise, we don't give SSA names to uses of promoted struct vars.
1061 if (varDsc->lvFieldCnt == 1)
1063 lclNum = varDsc->lvFieldLclStart;
1067 tree->gtLclVarCommon.SetSsaNum(SsaConfig::RESERVED_SSA_NUM);
1071 // Give the count as top of stack.
1072 unsigned count = pRenameState->CountForUse(lclNum);
1073 tree->gtLclVarCommon.SetSsaNum(count);
1078 void SsaBuilder::AddDefToHandlerPhis(BasicBlock* block, unsigned lclNum, unsigned count)
1080 assert(m_pCompiler->lvaTable[lclNum].lvTracked); // Precondition.
1081 unsigned lclIndex = m_pCompiler->lvaTable[lclNum].lvVarIndex;
1083 EHblkDsc* tryBlk = m_pCompiler->ehGetBlockExnFlowDsc(block);
1084 if (tryBlk != nullptr)
1087 "Definition of local V%02u/d:%d in block BB%02u has exn handler; adding as phi arg to handlers.\n", lclNum,
1088 count, block->bbNum);
1091 BasicBlock* handler = tryBlk->ExFlowBlock();
1093 // Is "lclNum" live on entry to the handler?
1094 if (VarSetOps::IsMember(m_pCompiler, handler->bbLiveIn, lclIndex))
1097 bool phiFound = false;
1099 // A prefix of blocks statements will be SSA definitions. Search those for "lclNum".
1100 for (GenTree* stmt = handler->bbTreeList; stmt; stmt = stmt->gtNext)
1102 // If the tree is not an SSA def, break out of the loop: we're done.
1103 if (!stmt->IsPhiDefnStmt())
1108 GenTree* tree = stmt->gtStmt.gtStmtExpr;
1110 assert(tree->IsPhiDefn());
1112 if (tree->gtOp.gtOp1->gtLclVar.gtLclNum == lclNum)
1114 // It's the definition for the right local. Add "count" to the RHS.
1115 GenTree* phi = tree->gtOp.gtOp2;
1116 GenTreeArgList* args = nullptr;
1117 if (phi->gtOp.gtOp1 != nullptr)
1119 args = phi->gtOp.gtOp1->AsArgList();
1122 // Make sure it isn't already present: we should only add each definition once.
1123 for (GenTreeArgList* curArgs = args; curArgs != nullptr; curArgs = curArgs->Rest())
1125 GenTreePhiArg* phiArg = curArgs->Current()->AsPhiArg();
1126 assert(phiArg->gtSsaNum != count);
1129 var_types typ = m_pCompiler->lvaTable[lclNum].TypeGet();
1130 GenTreePhiArg* newPhiArg =
1131 new (m_pCompiler, GT_PHI_ARG) GenTreePhiArg(typ, lclNum, count, block);
1133 phi->gtOp.gtOp1 = new (m_pCompiler, GT_LIST) GenTreeArgList(newPhiArg, args);
1134 m_pCompiler->gtSetStmtInfo(stmt);
1135 m_pCompiler->fgSetStmtSeq(stmt);
1139 DBG_SSA_JITDUMP(" Added phi arg u:%d for V%02u to phi defn in handler block BB%02u.\n", count,
1140 lclNum, handler->bbNum);
1147 unsigned nextTryIndex = tryBlk->ebdEnclosingTryIndex;
1148 if (nextTryIndex == EHblkDsc::NO_ENCLOSING_INDEX)
1153 tryBlk = m_pCompiler->ehGetDsc(nextTryIndex);
1158 void SsaBuilder::AddMemoryDefToHandlerPhis(MemoryKind memoryKind, BasicBlock* block, unsigned count)
1160 if (m_pCompiler->ehBlockHasExnFlowDsc(block))
1162 // Don't do anything for a compiler-inserted BBJ_ALWAYS that is a "leave helper".
1163 if (block->bbJumpKind == BBJ_ALWAYS && (block->bbFlags & BBF_INTERNAL) && (block->bbPrev->isBBCallAlwaysPair()))
1169 DBG_SSA_JITDUMP("Definition of %s/d:%d in block BB%02u has exn handler; adding as phi arg to handlers.\n",
1170 memoryKindNames[memoryKind], count, block->bbNum);
1171 EHblkDsc* tryBlk = m_pCompiler->ehGetBlockExnFlowDsc(block);
1174 BasicBlock* handler = tryBlk->ExFlowBlock();
1176 // Is memoryKind live on entry to the handler?
1177 if ((handler->bbMemoryLiveIn & memoryKindSet(memoryKind)) != 0)
1179 assert(handler->bbMemorySsaPhiFunc != nullptr);
1181 // Add "count" to the phi args of memoryKind.
1182 BasicBlock::MemoryPhiArg*& handlerMemoryPhi = handler->bbMemorySsaPhiFunc[memoryKind];
1185 if (m_pCompiler->byrefStatesMatchGcHeapStates)
1187 // When sharing phis for GcHeap and ByrefExposed, callers should ask to add phis
1188 // for ByrefExposed only.
1189 assert(memoryKind != GcHeap);
1190 if (memoryKind == ByrefExposed)
1192 // The GcHeap and ByrefExposed phi funcs should always be in sync.
1193 assert(handlerMemoryPhi == handler->bbMemorySsaPhiFunc[GcHeap]);
1198 if (handlerMemoryPhi == BasicBlock::EmptyMemoryPhiDef)
1200 handlerMemoryPhi = new (m_pCompiler) BasicBlock::MemoryPhiArg(count);
1205 BasicBlock::MemoryPhiArg* curArg = handler->bbMemorySsaPhiFunc[memoryKind];
1206 while (curArg != nullptr)
1208 assert(curArg->GetSsaNum() != count);
1209 curArg = curArg->m_nextArg;
1212 handlerMemoryPhi = new (m_pCompiler) BasicBlock::MemoryPhiArg(count, handlerMemoryPhi);
1215 DBG_SSA_JITDUMP(" Added phi arg u:%d for %s to phi defn in handler block BB%02u.\n", count,
1216 memoryKindNames[memoryKind], memoryKind, handler->bbNum);
1218 if ((memoryKind == ByrefExposed) && m_pCompiler->byrefStatesMatchGcHeapStates)
1220 // Share the phi between GcHeap and ByrefExposed.
1221 handler->bbMemorySsaPhiFunc[GcHeap] = handlerMemoryPhi;
1224 unsigned tryInd = tryBlk->ebdEnclosingTryIndex;
1225 if (tryInd == EHblkDsc::NO_ENCLOSING_INDEX)
1229 tryBlk = m_pCompiler->ehGetDsc(tryInd);
1235 * Walk the block's tree in the evaluation order and give var definitions and uses their
1238 * @param block Block for which SSA variables have to be renamed.
1239 * @param pRenameState The incremental rename information stored during renaming process.
1242 void SsaBuilder::BlockRenameVariables(BasicBlock* block, SsaRenameState* pRenameState)
1244 // Walk the statements of the block and rename the tree variables.
1246 // First handle the incoming memory states.
1247 for (MemoryKind memoryKind : allMemoryKinds())
1249 if ((memoryKind == GcHeap) && m_pCompiler->byrefStatesMatchGcHeapStates)
1251 // ByrefExposed and GcHeap share any phi this block may have,
1252 assert(block->bbMemorySsaPhiFunc[memoryKind] == block->bbMemorySsaPhiFunc[ByrefExposed]);
1253 // so we will have already allocated a defnum for it if needed.
1254 assert(memoryKind > ByrefExposed);
1255 assert(pRenameState->CountForMemoryUse(memoryKind) == pRenameState->CountForMemoryUse(ByrefExposed));
1259 // Is there an Phi definition for memoryKind at the start of this block?
1260 if (block->bbMemorySsaPhiFunc[memoryKind] != nullptr)
1262 unsigned count = pRenameState->CountForMemoryDef();
1263 pRenameState->PushMemory(memoryKind, block, count);
1265 DBG_SSA_JITDUMP("Ssa # for %s phi on entry to BB%02u is %d.\n", memoryKindNames[memoryKind],
1266 block->bbNum, count);
1270 // Record the "in" Ssa # for memoryKind.
1271 block->bbMemorySsaNumIn[memoryKind] = pRenameState->CountForMemoryUse(memoryKind);
1274 // We need to iterate over phi definitions, to give them SSA names, but we need
1275 // to know which are which, so we don't add phi definitions to handler phi arg lists.
1276 // Statements are phi defns until they aren't.
1277 bool isPhiDefn = true;
1278 GenTree* firstNonPhi = block->FirstNonPhiDef();
1279 for (GenTree* stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
1281 if (stmt == firstNonPhi)
1286 for (GenTree* tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
1288 TreeRenameVariables(tree, block, pRenameState, isPhiDefn);
1292 // Now handle the final memory states.
1293 for (MemoryKind memoryKind : allMemoryKinds())
1295 MemoryKindSet memorySet = memoryKindSet(memoryKind);
1297 // If the block defines memory, allocate an SSA variable for the final memory state in the block.
1298 // (This may be redundant with the last SSA var explicitly created, but there's no harm in that.)
1299 if ((memoryKind == GcHeap) && m_pCompiler->byrefStatesMatchGcHeapStates)
1301 // We've already allocated the SSA num and propagated it to shared phis, if needed,
1302 // when processing ByrefExposed.
1303 assert(memoryKind > ByrefExposed);
1304 assert(((block->bbMemoryDef & memorySet) != 0) ==
1305 ((block->bbMemoryDef & memoryKindSet(ByrefExposed)) != 0));
1306 assert(pRenameState->CountForMemoryUse(memoryKind) == pRenameState->CountForMemoryUse(ByrefExposed));
1310 if ((block->bbMemoryDef & memorySet) != 0)
1312 unsigned count = pRenameState->CountForMemoryDef();
1313 pRenameState->PushMemory(memoryKind, block, count);
1314 AddMemoryDefToHandlerPhis(memoryKind, block, count);
1318 // Record the "out" Ssa" # for memoryKind.
1319 block->bbMemorySsaNumOut[memoryKind] = pRenameState->CountForMemoryUse(memoryKind);
1321 DBG_SSA_JITDUMP("Ssa # for %s on entry to BB%02u is %d; on exit is %d.\n", memoryKindNames[memoryKind],
1322 block->bbNum, block->bbMemorySsaNumIn[memoryKind], block->bbMemorySsaNumOut[memoryKind]);
1327 * Walk through the phi nodes of a given block and assign rhs variables to them.
1329 * Also renumber the rhs variables from top of the stack.
1331 * @param block Block for which phi nodes have to be assigned their rhs arguments.
1332 * @param pRenameState The incremental rename information stored during renaming process.
1335 void SsaBuilder::AssignPhiNodeRhsVariables(BasicBlock* block, SsaRenameState* pRenameState)
1337 for (BasicBlock* succ : block->GetAllSuccs(m_pCompiler))
1339 // Walk the statements for phi nodes.
1340 for (GenTree* stmt = succ->bbTreeList; stmt != nullptr && stmt->IsPhiDefnStmt(); stmt = stmt->gtNext)
1342 GenTree* tree = stmt->gtStmt.gtStmtExpr;
1343 assert(tree->IsPhiDefn());
1345 // Get the phi node from GT_ASG.
1346 GenTree* phiNode = tree->gtOp.gtOp2;
1347 assert(phiNode->gtOp.gtOp1 == nullptr || phiNode->gtOp.gtOp1->OperGet() == GT_LIST);
1349 unsigned lclNum = tree->gtOp.gtOp1->gtLclVar.gtLclNum;
1350 unsigned ssaNum = pRenameState->CountForUse(lclNum);
1351 // Search the arglist for an existing definition for ssaNum.
1352 // (Can we assert that its the head of the list? This should only happen when we add
1353 // during renaming for a definition that occurs within a try, and then that's the last
1354 // value of the var within that basic block.)
1355 GenTreeArgList* argList = (phiNode->gtOp.gtOp1 == nullptr ? nullptr : phiNode->gtOp.gtOp1->AsArgList());
1357 while (argList != nullptr)
1359 if (argList->Current()->AsLclVarCommon()->GetSsaNum() == ssaNum)
1364 argList = argList->Rest();
1368 GenTree* newPhiArg =
1369 new (m_pCompiler, GT_PHI_ARG) GenTreePhiArg(tree->gtOp.gtOp1->TypeGet(), lclNum, ssaNum, block);
1370 argList = (phiNode->gtOp.gtOp1 == nullptr ? nullptr : phiNode->gtOp.gtOp1->AsArgList());
1371 phiNode->gtOp.gtOp1 = new (m_pCompiler, GT_LIST) GenTreeArgList(newPhiArg, argList);
1372 DBG_SSA_JITDUMP(" Added phi arg u:%d for V%02u from BB%02u in BB%02u.\n", ssaNum, lclNum, block->bbNum,
1376 m_pCompiler->gtSetStmtInfo(stmt);
1377 m_pCompiler->fgSetStmtSeq(stmt);
1380 // Now handle memory.
1381 for (MemoryKind memoryKind : allMemoryKinds())
1383 BasicBlock::MemoryPhiArg*& succMemoryPhi = succ->bbMemorySsaPhiFunc[memoryKind];
1384 if (succMemoryPhi != nullptr)
1386 if ((memoryKind == GcHeap) && m_pCompiler->byrefStatesMatchGcHeapStates)
1388 // We've already propagated the "out" number to the phi shared with ByrefExposed,
1389 // but still need to update bbMemorySsaPhiFunc to be in sync between GcHeap and ByrefExposed.
1390 assert(memoryKind > ByrefExposed);
1391 assert(block->bbMemorySsaNumOut[memoryKind] == block->bbMemorySsaNumOut[ByrefExposed]);
1392 assert((succ->bbMemorySsaPhiFunc[ByrefExposed] == succMemoryPhi) ||
1393 (succ->bbMemorySsaPhiFunc[ByrefExposed]->m_nextArg ==
1394 (succMemoryPhi == BasicBlock::EmptyMemoryPhiDef ? nullptr : succMemoryPhi)));
1395 succMemoryPhi = succ->bbMemorySsaPhiFunc[ByrefExposed];
1400 if (succMemoryPhi == BasicBlock::EmptyMemoryPhiDef)
1402 succMemoryPhi = new (m_pCompiler) BasicBlock::MemoryPhiArg(block->bbMemorySsaNumOut[memoryKind]);
1406 BasicBlock::MemoryPhiArg* curArg = succMemoryPhi;
1407 unsigned ssaNum = block->bbMemorySsaNumOut[memoryKind];
1409 // This is a quadratic algorithm. We might need to consider some switch over to a hash table
1410 // representation for the arguments of a phi node, to make this linear.
1411 while (curArg != nullptr)
1413 if (curArg->m_ssaNum == ssaNum)
1418 curArg = curArg->m_nextArg;
1422 succMemoryPhi = new (m_pCompiler) BasicBlock::MemoryPhiArg(ssaNum, succMemoryPhi);
1425 DBG_SSA_JITDUMP(" Added phi arg for %s u:%d from BB%02u in BB%02u.\n", memoryKindNames[memoryKind],
1426 block->bbMemorySsaNumOut[memoryKind], block->bbNum, succ->bbNum);
1430 // If "succ" is the first block of a try block (and "block" is not also in that try block)
1431 // then we must look at the vars that have phi defs in the corresponding handler;
1432 // the current SSA name for such vars must be included as an argument to that phi.
1433 if (m_pCompiler->bbIsTryBeg(succ))
1435 assert(succ->hasTryIndex());
1436 unsigned tryInd = succ->getTryIndex();
1438 while (tryInd != EHblkDsc::NO_ENCLOSING_INDEX)
1440 // Check if the predecessor "block" is within the same try block.
1441 if (block->hasTryIndex())
1443 for (unsigned blockTryInd = block->getTryIndex(); blockTryInd != EHblkDsc::NO_ENCLOSING_INDEX;
1444 blockTryInd = m_pCompiler->ehGetEnclosingTryIndex(blockTryInd))
1446 if (blockTryInd == tryInd)
1448 // It is; don't execute the loop below.
1449 tryInd = EHblkDsc::NO_ENCLOSING_INDEX;
1454 // The loop just above found that the predecessor "block" is within the same
1455 // try block as "succ." So we don't need to process this try, or any
1456 // further outer try blocks here, since they would also contain both "succ"
1458 if (tryInd == EHblkDsc::NO_ENCLOSING_INDEX)
1464 EHblkDsc* succTry = m_pCompiler->ehGetDsc(tryInd);
1465 // This is necessarily true on the first iteration, but not
1466 // necessarily on the second and subsequent.
1467 if (succTry->ebdTryBeg != succ)
1472 // succ is the first block of this try. Look at phi defs in the handler.
1473 // For a filter, we consider the filter to be the "real" handler.
1474 BasicBlock* handlerStart = succTry->ExFlowBlock();
1476 for (GenTree* stmt = handlerStart->bbTreeList; stmt; stmt = stmt->gtNext)
1478 GenTree* tree = stmt->gtStmt.gtStmtExpr;
1480 // Check if the first n of the statements are phi nodes. If not, exit.
1481 if (tree->OperGet() != GT_ASG || tree->gtOp.gtOp2 == nullptr ||
1482 tree->gtOp.gtOp2->OperGet() != GT_PHI)
1487 // Get the phi node from GT_ASG.
1488 GenTree* lclVar = tree->gtOp.gtOp1;
1489 unsigned lclNum = lclVar->gtLclVar.gtLclNum;
1491 // If the variable is live-out of "blk", and is therefore live on entry to the try-block-start
1492 // "succ", then we make sure the current SSA name for the
1493 // var is one of the args of the phi node. If not, go on.
1494 LclVarDsc* lclVarDsc = &m_pCompiler->lvaTable[lclNum];
1495 if (!lclVarDsc->lvTracked ||
1496 !VarSetOps::IsMember(m_pCompiler, block->bbLiveOut, lclVarDsc->lvVarIndex))
1501 GenTree* phiNode = tree->gtOp.gtOp2;
1502 assert(phiNode->gtOp.gtOp1 == nullptr || phiNode->gtOp.gtOp1->OperGet() == GT_LIST);
1503 GenTreeArgList* argList = reinterpret_cast<GenTreeArgList*>(phiNode->gtOp.gtOp1);
1505 // What is the current SSAName from the predecessor for this local?
1506 unsigned ssaNum = pRenameState->CountForUse(lclNum);
1508 // See if this ssaNum is already an arg to the phi.
1509 bool alreadyArg = false;
1510 for (GenTreeArgList* curArgs = argList; curArgs != nullptr; curArgs = curArgs->Rest())
1512 if (curArgs->Current()->gtPhiArg.gtSsaNum == ssaNum)
1520 // Add the new argument.
1521 GenTree* newPhiArg =
1522 new (m_pCompiler, GT_PHI_ARG) GenTreePhiArg(lclVar->TypeGet(), lclNum, ssaNum, block);
1523 phiNode->gtOp.gtOp1 = new (m_pCompiler, GT_LIST) GenTreeArgList(newPhiArg, argList);
1525 DBG_SSA_JITDUMP(" Added phi arg u:%d for V%02u from BB%02u in BB%02u.\n", ssaNum, lclNum,
1526 block->bbNum, handlerStart->bbNum);
1528 m_pCompiler->gtSetStmtInfo(stmt);
1529 m_pCompiler->fgSetStmtSeq(stmt);
1533 // Now handle memory.
1534 for (MemoryKind memoryKind : allMemoryKinds())
1536 BasicBlock::MemoryPhiArg*& handlerMemoryPhi = handlerStart->bbMemorySsaPhiFunc[memoryKind];
1537 if (handlerMemoryPhi != nullptr)
1539 if ((memoryKind == GcHeap) && m_pCompiler->byrefStatesMatchGcHeapStates)
1541 // We've already added the arg to the phi shared with ByrefExposed if needed,
1542 // but still need to update bbMemorySsaPhiFunc to stay in sync.
1543 assert(memoryKind > ByrefExposed);
1544 assert(block->bbMemorySsaNumOut[memoryKind] == block->bbMemorySsaNumOut[ByrefExposed]);
1545 assert(handlerStart->bbMemorySsaPhiFunc[ByrefExposed]->m_ssaNum ==
1546 block->bbMemorySsaNumOut[memoryKind]);
1547 handlerMemoryPhi = handlerStart->bbMemorySsaPhiFunc[ByrefExposed];
1552 if (handlerMemoryPhi == BasicBlock::EmptyMemoryPhiDef)
1555 new (m_pCompiler) BasicBlock::MemoryPhiArg(block->bbMemorySsaNumOut[memoryKind]);
1559 // This path has a potential to introduce redundant phi args, due to multiple
1560 // preds of the same try-begin block having the same live-out memory def, and/or
1561 // due to nested try-begins each having preds with the same live-out memory def.
1562 // Avoid doing quadratic processing on handler phis, and instead live with the
1563 // occasional redundancy.
1564 handlerMemoryPhi = new (m_pCompiler)
1565 BasicBlock::MemoryPhiArg(block->bbMemorySsaNumOut[memoryKind], handlerMemoryPhi);
1567 DBG_SSA_JITDUMP(" Added phi arg for %s u:%d from BB%02u in BB%02u.\n",
1568 memoryKindNames[memoryKind], block->bbMemorySsaNumOut[memoryKind], block->bbNum,
1569 handlerStart->bbNum);
1573 tryInd = succTry->ebdEnclosingTryIndex;
1580 * Walk the block's tree in the evaluation order and reclaim rename stack for var definitions.
1582 * @param block Block for which SSA variables have to be renamed.
1583 * @param pRenameState The incremental rename information stored during renaming process.
1586 void SsaBuilder::BlockPopStacks(BasicBlock* block, SsaRenameState* pRenameState)
1588 // Pop the names given to the non-phi nodes.
1589 pRenameState->PopBlockStacks(block);
1592 for (MemoryKind memoryKind : allMemoryKinds())
1594 if ((memoryKind == GcHeap) && m_pCompiler->byrefStatesMatchGcHeapStates)
1596 // GcHeap and ByrefExposed share a rename stack, so don't try
1597 // to pop it a second time.
1600 pRenameState->PopBlockMemoryStack(memoryKind, block);
1605 * Perform variable renaming.
1607 * Walks the blocks and renames all var defs with ssa numbers and all uses with the
1608 * current count that is in the top of the stack. Assigns phi node rhs variables
1609 * (i.e., the arguments to the phi.) Then, calls the function recursively on child
1610 * nodes in the DOM tree to continue the renaming process.
1612 * @param block Block for which SSA variables have to be renamed.
1613 * @param pRenameState The incremental rename information stored during renaming process.
1615 * @remarks At the end of the method, m_uses and m_defs should be populated linking the
1618 * @see Briggs, Cooper, Harvey and Simpson "Practical Improvements to the Construction
1619 * and Destruction of Static Single Assignment Form."
1622 void SsaBuilder::RenameVariables(BlkToBlkSetMap* domTree, SsaRenameState* pRenameState)
1624 JITDUMP("*************** In SsaBuilder::RenameVariables()\n");
1626 // The first thing we do is treat parameters and must-init variables as if they have a
1627 // virtual definition before entry -- they start out at SSA name 1.
1628 for (unsigned i = 0; i < m_pCompiler->lvaCount; i++)
1630 LclVarDsc* varDsc = &m_pCompiler->lvaTable[i];
1633 varDsc->lvNumSsaNames = SsaConfig::UNINIT_SSA_NUM; // Start off fresh...
1636 if (varDsc->lvIsParam || m_pCompiler->info.compInitMem || varDsc->lvMustInit ||
1637 (varDsc->lvTracked &&
1638 VarSetOps::IsMember(m_pCompiler, m_pCompiler->fgFirstBB->bbLiveIn, varDsc->lvVarIndex)))
1640 unsigned count = pRenameState->CountForDef(i);
1642 // In ValueNum we'd assume un-inited variables get FIRST_SSA_NUM.
1643 assert(count == SsaConfig::FIRST_SSA_NUM);
1645 varDsc->lvNumSsaNames++;
1647 pRenameState->Push(nullptr, i, count);
1651 // In ValueNum we'd assume un-inited memory gets FIRST_SSA_NUM.
1652 // The memory is a parameter. Use FIRST_SSA_NUM as first SSA name.
1653 unsigned initMemoryCount = pRenameState->CountForMemoryDef();
1654 assert(initMemoryCount == SsaConfig::FIRST_SSA_NUM);
1655 for (MemoryKind memoryKind : allMemoryKinds())
1657 if ((memoryKind == GcHeap) && m_pCompiler->byrefStatesMatchGcHeapStates)
1659 // GcHeap shares its stack with ByrefExposed; don't re-push.
1662 pRenameState->PushMemory(memoryKind, m_pCompiler->fgFirstBB, initMemoryCount);
1665 // Initialize the memory ssa numbers for unreachable blocks. ValueNum expects
1666 // memory ssa numbers to have some intitial value.
1667 for (BasicBlock* block = m_pCompiler->fgFirstBB; block; block = block->bbNext)
1669 if (block->bbIDom == nullptr)
1671 for (MemoryKind memoryKind : allMemoryKinds())
1673 block->bbMemorySsaNumIn[memoryKind] = initMemoryCount;
1674 block->bbMemorySsaNumOut[memoryKind] = initMemoryCount;
1682 bool m_processed; // Whether the this block have already been processed: its var renamed, and children
1684 // If so, awaiting only BlockPopStacks.
1685 BlockWork(BasicBlock* blk, bool processed = false) : m_blk(blk), m_processed(processed)
1689 typedef jitstd::vector<BlockWork> BlockWorkStack;
1691 BlockWorkStack* blocksToDo = new (&m_allocator) BlockWorkStack(&m_allocator);
1692 blocksToDo->push_back(BlockWork(m_pCompiler->fgFirstBB)); // Probably have to include other roots of dom tree.
1694 while (blocksToDo->size() != 0)
1696 BlockWork blockWrk = blocksToDo->back();
1697 blocksToDo->pop_back();
1698 BasicBlock* block = blockWrk.m_blk;
1700 DBG_SSA_JITDUMP("[SsaBuilder::RenameVariables](BB%02u, processed = %d)\n", block->bbNum, blockWrk.m_processed);
1702 if (!blockWrk.m_processed)
1704 // Push the block back on the stack with "m_processed" true, to record the fact that when its children have
1705 // been (recursively) processed, we still need to call BlockPopStacks on it.
1706 blocksToDo->push_back(BlockWork(block, true));
1708 // Walk the block give counts to DEFs and give top of stack count for USEs.
1709 BlockRenameVariables(block, pRenameState);
1711 // Assign arguments to the phi node of successors, corresponding to the block's index.
1712 AssignPhiNodeRhsVariables(block, pRenameState);
1714 // Recurse with the block's DOM children.
1716 if (domTree->Lookup(block, &pBlkSet))
1718 for (BlkSet::KeyIterator child = pBlkSet->Begin(); !child.Equal(pBlkSet->End()); ++child)
1720 DBG_SSA_JITDUMP("[SsaBuilder::RenameVariables](pushing dom child BB%02u)\n", child.Get()->bbNum);
1721 blocksToDo->push_back(BlockWork(child.Get()));
1727 // Done, pop all the stack count, if there is one for this block.
1728 BlockPopStacks(block, pRenameState);
1729 DBG_SSA_JITDUMP("[SsaBuilder::RenameVariables] done with BB%02u\n", block->bbNum);
1733 // Remember the number of memory SSA names.
1734 m_pCompiler->lvMemoryNumSsaNames = pRenameState->MemoryCount();
1739 * Print the blocks, the phi nodes get printed as well.
1742 * [0027CC0C] ----------- stmtExpr void (IL 0x019...0x01B)
1743 * N001 ( 1, 1) [0027CB70] ----------- const int 23
1744 * N003 ( 3, 3) [0027CBD8] -A------R-- = int
1745 * N002 ( 1, 1) [0027CBA4] D------N--- lclVar int V01 arg1 d:5
1748 * [0027D530] ----------- stmtExpr void (IL ???... ???)
1749 * N002 ( 0, 0) [0027D4C8] ----------- phi int
1750 * [0027D8CC] ----------- lclVar int V01 arg1 u:5
1751 * [0027D844] ----------- lclVar int V01 arg1 u:4
1752 * N004 ( 2, 2) [0027D4FC] -A------R-- = int
1753 * N003 ( 1, 1) [0027D460] D------N--- lclVar int V01 arg1 d:3
1755 void SsaBuilder::Print(BasicBlock** postOrder, int count)
1757 for (int i = count - 1; i >= 0; --i)
1759 printf("After SSA BB%02u:\n", postOrder[i]->bbNum);
1760 m_pCompiler->gtDispTreeList(postOrder[i]->bbTreeList);
1768 * Sorts the graph topologically.
1769 * - Collects them in postOrder array.
1771 * Identifies each block's immediate dominator.
1772 * - Computes this in bbIDom of each BasicBlock.
1774 * Computes DOM tree relation.
1775 * - Computes domTree as block -> set of blocks.
1776 * - Computes pre/post order traversal of the DOM tree.
1778 * Inserts phi nodes.
1779 * - Computes dominance frontier as block -> set of blocks.
1780 * - Allocates block use/def/livein/liveout and computes it.
1781 * - Inserts phi nodes with only rhs at the beginning of the blocks.
1783 * Renames variables.
1784 * - Walks blocks in evaluation order and gives uses and defs names.
1785 * - Gives empty phi nodes their rhs arguments as they become known while renaming.
1787 * @return true if successful, for now, this must always be true.
1789 * @see "A simple, fast dominance algorithm" by Keith D. Cooper, Timothy J. Harvey, Ken Kennedy.
1790 * @see Briggs, Cooper, Harvey and Simpson "Practical Improvements to the Construction
1791 * and Destruction of Static Single Assignment Form."
1793 void SsaBuilder::Build()
1796 if (m_pCompiler->verbose)
1798 printf("*************** In SsaBuilder::Build()\n");
1802 // Ensure that there's a first block outside a try, so that the dominator tree has a unique root.
1805 // Just to keep block no. & index same add 1.
1806 int blockCount = m_pCompiler->fgBBNumMax + 1;
1808 JITDUMP("[SsaBuilder] Max block count is %d.\n", blockCount);
1810 // Allocate the postOrder array for the graph.
1812 BasicBlock** postOrder;
1814 if (blockCount > DEFAULT_MIN_OPTS_BB_COUNT)
1816 postOrder = new (&m_allocator) BasicBlock*[blockCount];
1820 postOrder = (BasicBlock**)alloca(blockCount * sizeof(BasicBlock*));
1823 m_visitedTraits = BitVecTraits(blockCount, m_pCompiler);
1824 m_visited = BitVecOps::MakeEmpty(&m_visitedTraits);
1826 // Topologically sort the graph.
1827 int count = TopologicalSort(postOrder, blockCount);
1828 JITDUMP("[SsaBuilder] Topologically sorted the graph.\n");
1829 EndPhase(PHASE_BUILD_SSA_TOPOSORT);
1832 ComputeImmediateDom(postOrder, count);
1834 // Compute the dominator tree.
1835 BlkToBlkSetMap* domTree = new (&m_allocator) BlkToBlkSetMap(&m_allocator);
1836 ComputeDominators(postOrder, count, domTree);
1837 EndPhase(PHASE_BUILD_SSA_DOMS);
1839 // Insert phi functions.
1840 InsertPhiFunctions(postOrder, count);
1842 // Rename local variables and collect UD information for each ssa var.
1843 SsaRenameState* pRenameState = new (&m_allocator)
1844 SsaRenameState(&m_allocator, m_pCompiler->lvaCount, m_pCompiler->byrefStatesMatchGcHeapStates);
1845 RenameVariables(domTree, pRenameState);
1846 EndPhase(PHASE_BUILD_SSA_RENAME);
1849 // At this point we are in SSA form. Print the SSA form.
1850 if (m_pCompiler->verboseSsa)
1852 Print(postOrder, count);
1857 void SsaBuilder::SetupBBRoot()
1859 // Allocate a bbroot, if necessary.
1860 // We need a unique block to be the root of the dominator tree.
1861 // This can be violated if the first block is in a try, or if it is the first block of
1862 // a loop (which would necessarily be an infinite loop) -- i.e., it has a predecessor.
1864 // If neither condition holds, no reason to make a new block.
1865 if (!m_pCompiler->fgFirstBB->hasTryIndex() && m_pCompiler->fgFirstBB->bbPreds == nullptr)
1870 BasicBlock* bbRoot = m_pCompiler->bbNewBasicBlock(BBJ_NONE);
1871 bbRoot->bbFlags |= BBF_INTERNAL;
1873 // May need to fix up preds list, so remember the old first block.
1874 BasicBlock* oldFirst = m_pCompiler->fgFirstBB;
1876 // Copy the liveness information from the first basic block.
1877 if (m_pCompiler->fgLocalVarLivenessDone)
1879 VarSetOps::Assign(m_pCompiler, bbRoot->bbLiveIn, oldFirst->bbLiveIn);
1880 VarSetOps::Assign(m_pCompiler, bbRoot->bbLiveOut, oldFirst->bbLiveIn);
1883 // Copy the bbWeight. (This is technically wrong, if the first block is a loop head, but
1884 // it shouldn't matter...)
1885 bbRoot->inheritWeight(oldFirst);
1887 // There's an artifical incoming reference count for the first BB. We're about to make it no longer
1888 // the first BB, so decrement that.
1889 assert(oldFirst->bbRefs > 0);
1892 m_pCompiler->fgInsertBBbefore(m_pCompiler->fgFirstBB, bbRoot);
1894 assert(m_pCompiler->fgFirstBB == bbRoot);
1895 if (m_pCompiler->fgComputePredsDone)
1897 m_pCompiler->fgAddRefPred(oldFirst, bbRoot);
1902 // This method asserts that SSA name constraints specified are satisfied.
1903 void Compiler::JitTestCheckSSA()
1910 static unsigned GetHashCode(SSAName ssaNm)
1912 return ssaNm.m_lvNum << 16 | ssaNm.m_ssaNum;
1915 static bool Equals(SSAName ssaNm1, SSAName ssaNm2)
1917 return ssaNm1.m_lvNum == ssaNm2.m_lvNum && ssaNm1.m_ssaNum == ssaNm2.m_ssaNum;
1921 typedef JitHashTable<ssize_t, JitSmallPrimitiveKeyFuncs<ssize_t>, SSAName> LabelToSSANameMap;
1922 typedef JitHashTable<SSAName, SSAName, ssize_t> SSANameToLabelMap;
1924 // If we have no test data, early out.
1925 if (m_nodeTestData == nullptr)
1930 NodeToTestDataMap* testData = GetNodeTestData();
1932 // First we have to know which nodes in the tree are reachable.
1933 NodeToIntMap* reachable = FindReachableNodesInNodeTestData();
1935 LabelToSSANameMap* labelToSSA = new (getAllocatorDebugOnly()) LabelToSSANameMap(getAllocatorDebugOnly());
1936 SSANameToLabelMap* ssaToLabel = new (getAllocatorDebugOnly()) SSANameToLabelMap(getAllocatorDebugOnly());
1940 printf("\nJit Testing: SSA names.\n");
1942 for (NodeToTestDataMap::KeyIterator ki = testData->Begin(); !ki.Equal(testData->End()); ++ki)
1944 TestLabelAndNum tlAndN;
1945 GenTree* node = ki.Get();
1946 bool b = testData->Lookup(node, &tlAndN);
1948 if (tlAndN.m_tl == TL_SsaName)
1950 if (node->OperGet() != GT_LCL_VAR)
1952 printf("SSAName constraint put on non-lcl-var expression ");
1954 printf(" (of type %s).\n", varTypeName(node->TypeGet()));
1957 GenTreeLclVarCommon* lcl = node->AsLclVarCommon();
1960 if (!reachable->Lookup(lcl, &dummy))
1964 printf(" had a test constraint declared, but has become unreachable at the time the constraint is "
1966 "(This is probably as a result of some optimization -- \n"
1967 "you may need to modify the test case to defeat this opt.)\n");
1975 printf(", SSA name = <%d, %d> -- SSA name class %d.\n", lcl->gtLclNum, lcl->gtSsaNum, tlAndN.m_num);
1978 if (labelToSSA->Lookup(tlAndN.m_num, &ssaNm))
1982 printf(" Already in hash tables.\n");
1984 // The mapping(s) must be one-to-one: if the label has a mapping, then the ssaNm must, as well.
1986 bool b = ssaToLabel->Lookup(ssaNm, &num2);
1987 // And the mappings must be the same.
1988 if (tlAndN.m_num != num2)
1992 printf(", SSA name = <%d, %d> was declared in SSA name class %d,\n", lcl->gtLclNum, lcl->gtSsaNum,
1995 "but this SSA name <%d,%d> has already been associated with a different SSA name class: %d.\n",
1996 ssaNm.m_lvNum, ssaNm.m_ssaNum, num2);
1999 // And the current node must be of the specified SSA family.
2000 if (!(lcl->gtLclNum == ssaNm.m_lvNum && lcl->gtSsaNum == ssaNm.m_ssaNum))
2004 printf(", SSA name = <%d, %d> was declared in SSA name class %d,\n", lcl->gtLclNum, lcl->gtSsaNum,
2006 printf("but that name class was previously bound to a different SSA name: <%d,%d>.\n",
2007 ssaNm.m_lvNum, ssaNm.m_ssaNum);
2013 ssaNm.m_lvNum = lcl->gtLclNum;
2014 ssaNm.m_ssaNum = lcl->gtSsaNum;
2016 // The mapping(s) must be one-to-one: if the label has no mapping, then the ssaNm may not, either.
2017 if (ssaToLabel->Lookup(ssaNm, &num))
2021 printf(", SSA name = <%d, %d> was declared in SSA name class %d,\n", lcl->gtLclNum, lcl->gtSsaNum,
2023 printf("but this SSA name has already been associated with a different name class: %d.\n", num);
2026 // Add to both mappings.
2027 labelToSSA->Set(tlAndN.m_num, ssaNm);
2028 ssaToLabel->Set(ssaNm, tlAndN.m_num);
2031 printf(" added to hash tables.\n");