xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/LiveRangeCalc.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
15ffd83dbSDimitry Andric //===- LiveRangeCalc.cpp - Calculate live ranges -------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Implementation of the LiveRangeCalc class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
138bcb0991SDimitry Andric #include "llvm/CodeGen/LiveRangeCalc.h"
140b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h"
150b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
160b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h"
170b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/LiveInterval.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/SlotIndexes.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
260b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
270b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
280b57cec5SDimitry Andric #include <algorithm>
290b57cec5SDimitry Andric #include <cassert>
300b57cec5SDimitry Andric #include <iterator>
310b57cec5SDimitry Andric #include <tuple>
320b57cec5SDimitry Andric #include <utility>
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric using namespace llvm;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric #define DEBUG_TYPE "regalloc"
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric // Reserve an address that indicates a value that is known to be "undef".
390b57cec5SDimitry Andric static VNInfo UndefVNI(0xbad, SlotIndex());
400b57cec5SDimitry Andric 
resetLiveOutMap()410b57cec5SDimitry Andric void LiveRangeCalc::resetLiveOutMap() {
420b57cec5SDimitry Andric   unsigned NumBlocks = MF->getNumBlockIDs();
430b57cec5SDimitry Andric   Seen.clear();
440b57cec5SDimitry Andric   Seen.resize(NumBlocks);
450b57cec5SDimitry Andric   EntryInfos.clear();
460b57cec5SDimitry Andric   Map.resize(NumBlocks);
470b57cec5SDimitry Andric }
480b57cec5SDimitry Andric 
reset(const MachineFunction * mf,SlotIndexes * SI,MachineDominatorTree * MDT,VNInfo::Allocator * VNIA)490b57cec5SDimitry Andric void LiveRangeCalc::reset(const MachineFunction *mf,
500b57cec5SDimitry Andric                           SlotIndexes *SI,
510b57cec5SDimitry Andric                           MachineDominatorTree *MDT,
520b57cec5SDimitry Andric                           VNInfo::Allocator *VNIA) {
530b57cec5SDimitry Andric   MF = mf;
540b57cec5SDimitry Andric   MRI = &MF->getRegInfo();
550b57cec5SDimitry Andric   Indexes = SI;
560b57cec5SDimitry Andric   DomTree = MDT;
570b57cec5SDimitry Andric   Alloc = VNIA;
580b57cec5SDimitry Andric   resetLiveOutMap();
590b57cec5SDimitry Andric   LiveIn.clear();
600b57cec5SDimitry Andric }
610b57cec5SDimitry Andric 
updateFromLiveIns()620b57cec5SDimitry Andric void LiveRangeCalc::updateFromLiveIns() {
630b57cec5SDimitry Andric   LiveRangeUpdater Updater;
640b57cec5SDimitry Andric   for (const LiveInBlock &I : LiveIn) {
650b57cec5SDimitry Andric     if (!I.DomNode)
660b57cec5SDimitry Andric       continue;
670b57cec5SDimitry Andric     MachineBasicBlock *MBB = I.DomNode->getBlock();
680b57cec5SDimitry Andric     assert(I.Value && "No live-in value found");
690b57cec5SDimitry Andric     SlotIndex Start, End;
700b57cec5SDimitry Andric     std::tie(Start, End) = Indexes->getMBBRange(MBB);
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric     if (I.Kill.isValid())
730b57cec5SDimitry Andric       // Value is killed inside this block.
740b57cec5SDimitry Andric       End = I.Kill;
750b57cec5SDimitry Andric     else {
760b57cec5SDimitry Andric       // The value is live-through, update LiveOut as well.
770b57cec5SDimitry Andric       // Defer the Domtree lookup until it is needed.
780b57cec5SDimitry Andric       assert(Seen.test(MBB->getNumber()));
790b57cec5SDimitry Andric       Map[MBB] = LiveOutPair(I.Value, nullptr);
800b57cec5SDimitry Andric     }
810b57cec5SDimitry Andric     Updater.setDest(&I.LR);
820b57cec5SDimitry Andric     Updater.add(Start, End, I.Value);
830b57cec5SDimitry Andric   }
840b57cec5SDimitry Andric   LiveIn.clear();
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric 
extend(LiveRange & LR,SlotIndex Use,unsigned PhysReg,ArrayRef<SlotIndex> Undefs)870b57cec5SDimitry Andric void LiveRangeCalc::extend(LiveRange &LR, SlotIndex Use, unsigned PhysReg,
880b57cec5SDimitry Andric                            ArrayRef<SlotIndex> Undefs) {
890b57cec5SDimitry Andric   assert(Use.isValid() && "Invalid SlotIndex");
900b57cec5SDimitry Andric   assert(Indexes && "Missing SlotIndexes");
910b57cec5SDimitry Andric   assert(DomTree && "Missing dominator tree");
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   MachineBasicBlock *UseMBB = Indexes->getMBBFromIndex(Use.getPrevSlot());
940b57cec5SDimitry Andric   assert(UseMBB && "No MBB at Use");
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   // Is there a def in the same MBB we can extend?
970b57cec5SDimitry Andric   auto EP = LR.extendInBlock(Undefs, Indexes->getMBBStartIdx(UseMBB), Use);
980b57cec5SDimitry Andric   if (EP.first != nullptr || EP.second)
990b57cec5SDimitry Andric     return;
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric   // Find the single reaching def, or determine if Use is jointly dominated by
1020b57cec5SDimitry Andric   // multiple values, and we may need to create even more phi-defs to preserve
1030b57cec5SDimitry Andric   // VNInfo SSA form.  Perform a search for all predecessor blocks where we
1040b57cec5SDimitry Andric   // know the dominating VNInfo.
1050b57cec5SDimitry Andric   if (findReachingDefs(LR, *UseMBB, Use, PhysReg, Undefs))
1060b57cec5SDimitry Andric     return;
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric   // When there were multiple different values, we may need new PHIs.
1090b57cec5SDimitry Andric   calculateValues();
1100b57cec5SDimitry Andric }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric // This function is called by a client after using the low-level API to add
1130b57cec5SDimitry Andric // live-out and live-in blocks.  The unique value optimization is not
1140b57cec5SDimitry Andric // available, SplitEditor::transferValues handles that case directly anyway.
calculateValues()1150b57cec5SDimitry Andric void LiveRangeCalc::calculateValues() {
1160b57cec5SDimitry Andric   assert(Indexes && "Missing SlotIndexes");
1170b57cec5SDimitry Andric   assert(DomTree && "Missing dominator tree");
1180b57cec5SDimitry Andric   updateSSA();
1190b57cec5SDimitry Andric   updateFromLiveIns();
1200b57cec5SDimitry Andric }
1210b57cec5SDimitry Andric 
isDefOnEntry(LiveRange & LR,ArrayRef<SlotIndex> Undefs,MachineBasicBlock & MBB,BitVector & DefOnEntry,BitVector & UndefOnEntry)1220b57cec5SDimitry Andric bool LiveRangeCalc::isDefOnEntry(LiveRange &LR, ArrayRef<SlotIndex> Undefs,
1230b57cec5SDimitry Andric                                  MachineBasicBlock &MBB, BitVector &DefOnEntry,
1240b57cec5SDimitry Andric                                  BitVector &UndefOnEntry) {
1250b57cec5SDimitry Andric   unsigned BN = MBB.getNumber();
1260b57cec5SDimitry Andric   if (DefOnEntry[BN])
1270b57cec5SDimitry Andric     return true;
1280b57cec5SDimitry Andric   if (UndefOnEntry[BN])
1290b57cec5SDimitry Andric     return false;
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   auto MarkDefined = [BN, &DefOnEntry](MachineBasicBlock &B) -> bool {
1320b57cec5SDimitry Andric     for (MachineBasicBlock *S : B.successors())
1330b57cec5SDimitry Andric       DefOnEntry[S->getNumber()] = true;
1340b57cec5SDimitry Andric     DefOnEntry[BN] = true;
1350b57cec5SDimitry Andric     return true;
1360b57cec5SDimitry Andric   };
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric   SetVector<unsigned> WorkList;
1390b57cec5SDimitry Andric   // Checking if the entry of MBB is reached by some def: add all predecessors
1400b57cec5SDimitry Andric   // that are potentially defined-on-exit to the work list.
1410b57cec5SDimitry Andric   for (MachineBasicBlock *P : MBB.predecessors())
1420b57cec5SDimitry Andric     WorkList.insert(P->getNumber());
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric   for (unsigned i = 0; i != WorkList.size(); ++i) {
1450b57cec5SDimitry Andric     // Determine if the exit from the block is reached by some def.
1460b57cec5SDimitry Andric     unsigned N = WorkList[i];
1470b57cec5SDimitry Andric     MachineBasicBlock &B = *MF->getBlockNumbered(N);
1480b57cec5SDimitry Andric     if (Seen[N]) {
1490b57cec5SDimitry Andric       const LiveOutPair &LOB = Map[&B];
1500b57cec5SDimitry Andric       if (LOB.first != nullptr && LOB.first != &UndefVNI)
1510b57cec5SDimitry Andric         return MarkDefined(B);
1520b57cec5SDimitry Andric     }
1530b57cec5SDimitry Andric     SlotIndex Begin, End;
1540b57cec5SDimitry Andric     std::tie(Begin, End) = Indexes->getMBBRange(&B);
1550b57cec5SDimitry Andric     // Treat End as not belonging to B.
1560b57cec5SDimitry Andric     // If LR has a segment S that starts at the next block, i.e. [End, ...),
1570b57cec5SDimitry Andric     // std::upper_bound will return the segment following S. Instead,
1580b57cec5SDimitry Andric     // S should be treated as the first segment that does not overlap B.
159fe6060f1SDimitry Andric     LiveRange::iterator UB = upper_bound(LR, End.getPrevSlot());
1600b57cec5SDimitry Andric     if (UB != LR.begin()) {
1610b57cec5SDimitry Andric       LiveRange::Segment &Seg = *std::prev(UB);
1620b57cec5SDimitry Andric       if (Seg.end > Begin) {
1630b57cec5SDimitry Andric         // There is a segment that overlaps B. If the range is not explicitly
1640b57cec5SDimitry Andric         // undefined between the end of the segment and the end of the block,
1650b57cec5SDimitry Andric         // treat the block as defined on exit. If it is, go to the next block
1660b57cec5SDimitry Andric         // on the work list.
1670b57cec5SDimitry Andric         if (LR.isUndefIn(Undefs, Seg.end, End))
1680b57cec5SDimitry Andric           continue;
1690b57cec5SDimitry Andric         return MarkDefined(B);
1700b57cec5SDimitry Andric       }
1710b57cec5SDimitry Andric     }
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric     // No segment overlaps with this block. If this block is not defined on
1740b57cec5SDimitry Andric     // entry, or it undefines the range, do not process its predecessors.
1750b57cec5SDimitry Andric     if (UndefOnEntry[N] || LR.isUndefIn(Undefs, Begin, End)) {
1760b57cec5SDimitry Andric       UndefOnEntry[N] = true;
1770b57cec5SDimitry Andric       continue;
1780b57cec5SDimitry Andric     }
1790b57cec5SDimitry Andric     if (DefOnEntry[N])
1800b57cec5SDimitry Andric       return MarkDefined(B);
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric     // Still don't know: add all predecessors to the work list.
1830b57cec5SDimitry Andric     for (MachineBasicBlock *P : B.predecessors())
1840b57cec5SDimitry Andric       WorkList.insert(P->getNumber());
1850b57cec5SDimitry Andric   }
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric   UndefOnEntry[BN] = true;
1880b57cec5SDimitry Andric   return false;
1890b57cec5SDimitry Andric }
1900b57cec5SDimitry Andric 
findReachingDefs(LiveRange & LR,MachineBasicBlock & UseMBB,SlotIndex Use,unsigned PhysReg,ArrayRef<SlotIndex> Undefs)1910b57cec5SDimitry Andric bool LiveRangeCalc::findReachingDefs(LiveRange &LR, MachineBasicBlock &UseMBB,
1920b57cec5SDimitry Andric                                      SlotIndex Use, unsigned PhysReg,
1930b57cec5SDimitry Andric                                      ArrayRef<SlotIndex> Undefs) {
1940b57cec5SDimitry Andric   unsigned UseMBBNum = UseMBB.getNumber();
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric   // Block numbers where LR should be live-in.
1970b57cec5SDimitry Andric   SmallVector<unsigned, 16> WorkList(1, UseMBBNum);
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric   // Remember if we have seen more than one value.
2000b57cec5SDimitry Andric   bool UniqueVNI = true;
2010b57cec5SDimitry Andric   VNInfo *TheVNI = nullptr;
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   bool FoundUndef = false;
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric   // Using Seen as a visited set, perform a BFS for all reaching defs.
2060b57cec5SDimitry Andric   for (unsigned i = 0; i != WorkList.size(); ++i) {
2070b57cec5SDimitry Andric     MachineBasicBlock *MBB = MF->getBlockNumbered(WorkList[i]);
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric #ifndef NDEBUG
2100b57cec5SDimitry Andric     if (MBB->pred_empty()) {
2110b57cec5SDimitry Andric       MBB->getParent()->verify();
2120b57cec5SDimitry Andric       errs() << "Use of " << printReg(PhysReg, MRI->getTargetRegisterInfo())
2130b57cec5SDimitry Andric              << " does not have a corresponding definition on every path:\n";
2140b57cec5SDimitry Andric       const MachineInstr *MI = Indexes->getInstructionFromIndex(Use);
2150b57cec5SDimitry Andric       if (MI != nullptr)
2160b57cec5SDimitry Andric         errs() << Use << " " << *MI;
2170b57cec5SDimitry Andric       report_fatal_error("Use not jointly dominated by defs.");
2180b57cec5SDimitry Andric     }
2190b57cec5SDimitry Andric 
220*5f757f3fSDimitry Andric     if (Register::isPhysicalRegister(PhysReg)) {
2210b57cec5SDimitry Andric       const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
222*5f757f3fSDimitry Andric       bool IsLiveIn = MBB->isLiveIn(PhysReg);
223*5f757f3fSDimitry Andric       for (MCRegAliasIterator Alias(PhysReg, TRI, false); !IsLiveIn && Alias.isValid(); ++Alias)
224*5f757f3fSDimitry Andric         IsLiveIn = MBB->isLiveIn(*Alias);
225*5f757f3fSDimitry Andric       if (!IsLiveIn) {
226*5f757f3fSDimitry Andric         MBB->getParent()->verify();
2270b57cec5SDimitry Andric         errs() << "The register " << printReg(PhysReg, TRI)
2280b57cec5SDimitry Andric                << " needs to be live in to " << printMBBReference(*MBB)
2290b57cec5SDimitry Andric                << ", but is missing from the live-in list.\n";
2300b57cec5SDimitry Andric         report_fatal_error("Invalid global physical register");
2310b57cec5SDimitry Andric       }
232*5f757f3fSDimitry Andric     }
2330b57cec5SDimitry Andric #endif
2340b57cec5SDimitry Andric     FoundUndef |= MBB->pred_empty();
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric     for (MachineBasicBlock *Pred : MBB->predecessors()) {
2370b57cec5SDimitry Andric        // Is this a known live-out block?
2380b57cec5SDimitry Andric        if (Seen.test(Pred->getNumber())) {
2390b57cec5SDimitry Andric          if (VNInfo *VNI = Map[Pred].first) {
2400b57cec5SDimitry Andric            if (TheVNI && TheVNI != VNI)
2410b57cec5SDimitry Andric              UniqueVNI = false;
2420b57cec5SDimitry Andric            TheVNI = VNI;
2430b57cec5SDimitry Andric          }
2440b57cec5SDimitry Andric          continue;
2450b57cec5SDimitry Andric        }
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric        SlotIndex Start, End;
2480b57cec5SDimitry Andric        std::tie(Start, End) = Indexes->getMBBRange(Pred);
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric        // First time we see Pred.  Try to determine the live-out value, but set
2510b57cec5SDimitry Andric        // it as null if Pred is live-through with an unknown value.
2520b57cec5SDimitry Andric        auto EP = LR.extendInBlock(Undefs, Start, End);
2530b57cec5SDimitry Andric        VNInfo *VNI = EP.first;
2540b57cec5SDimitry Andric        FoundUndef |= EP.second;
2550b57cec5SDimitry Andric        setLiveOutValue(Pred, EP.second ? &UndefVNI : VNI);
2560b57cec5SDimitry Andric        if (VNI) {
2570b57cec5SDimitry Andric          if (TheVNI && TheVNI != VNI)
2580b57cec5SDimitry Andric            UniqueVNI = false;
2590b57cec5SDimitry Andric          TheVNI = VNI;
2600b57cec5SDimitry Andric        }
2610b57cec5SDimitry Andric        if (VNI || EP.second)
2620b57cec5SDimitry Andric          continue;
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric        // No, we need a live-in value for Pred as well
2650b57cec5SDimitry Andric        if (Pred != &UseMBB)
2660b57cec5SDimitry Andric          WorkList.push_back(Pred->getNumber());
2670b57cec5SDimitry Andric        else
2680b57cec5SDimitry Andric           // Loopback to UseMBB, so value is really live through.
2690b57cec5SDimitry Andric          Use = SlotIndex();
2700b57cec5SDimitry Andric     }
2710b57cec5SDimitry Andric   }
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   LiveIn.clear();
2740b57cec5SDimitry Andric   FoundUndef |= (TheVNI == nullptr || TheVNI == &UndefVNI);
2750b57cec5SDimitry Andric   if (!Undefs.empty() && FoundUndef)
2760b57cec5SDimitry Andric     UniqueVNI = false;
2770b57cec5SDimitry Andric 
2780b57cec5SDimitry Andric   // Both updateSSA() and LiveRangeUpdater benefit from ordered blocks, but
2790b57cec5SDimitry Andric   // neither require it. Skip the sorting overhead for small updates.
2800b57cec5SDimitry Andric   if (WorkList.size() > 4)
2810b57cec5SDimitry Andric     array_pod_sort(WorkList.begin(), WorkList.end());
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric   // If a unique reaching def was found, blit in the live ranges immediately.
2840b57cec5SDimitry Andric   if (UniqueVNI) {
2850b57cec5SDimitry Andric     assert(TheVNI != nullptr && TheVNI != &UndefVNI);
2860b57cec5SDimitry Andric     LiveRangeUpdater Updater(&LR);
2870b57cec5SDimitry Andric     for (unsigned BN : WorkList) {
2880b57cec5SDimitry Andric       SlotIndex Start, End;
2890b57cec5SDimitry Andric       std::tie(Start, End) = Indexes->getMBBRange(BN);
2900b57cec5SDimitry Andric       // Trim the live range in UseMBB.
2910b57cec5SDimitry Andric       if (BN == UseMBBNum && Use.isValid())
2920b57cec5SDimitry Andric         End = Use;
2930b57cec5SDimitry Andric       else
2940b57cec5SDimitry Andric         Map[MF->getBlockNumbered(BN)] = LiveOutPair(TheVNI, nullptr);
2950b57cec5SDimitry Andric       Updater.add(Start, End, TheVNI);
2960b57cec5SDimitry Andric     }
2970b57cec5SDimitry Andric     return true;
2980b57cec5SDimitry Andric   }
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   // Prepare the defined/undefined bit vectors.
3010b57cec5SDimitry Andric   EntryInfoMap::iterator Entry;
3020b57cec5SDimitry Andric   bool DidInsert;
3030b57cec5SDimitry Andric   std::tie(Entry, DidInsert) = EntryInfos.insert(
3040b57cec5SDimitry Andric       std::make_pair(&LR, std::make_pair(BitVector(), BitVector())));
3050b57cec5SDimitry Andric   if (DidInsert) {
3060b57cec5SDimitry Andric     // Initialize newly inserted entries.
3070b57cec5SDimitry Andric     unsigned N = MF->getNumBlockIDs();
3080b57cec5SDimitry Andric     Entry->second.first.resize(N);
3090b57cec5SDimitry Andric     Entry->second.second.resize(N);
3100b57cec5SDimitry Andric   }
3110b57cec5SDimitry Andric   BitVector &DefOnEntry = Entry->second.first;
3120b57cec5SDimitry Andric   BitVector &UndefOnEntry = Entry->second.second;
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   // Multiple values were found, so transfer the work list to the LiveIn array
3150b57cec5SDimitry Andric   // where UpdateSSA will use it as a work list.
3160b57cec5SDimitry Andric   LiveIn.reserve(WorkList.size());
3170b57cec5SDimitry Andric   for (unsigned BN : WorkList) {
3180b57cec5SDimitry Andric     MachineBasicBlock *MBB = MF->getBlockNumbered(BN);
3190b57cec5SDimitry Andric     if (!Undefs.empty() &&
3200b57cec5SDimitry Andric         !isDefOnEntry(LR, Undefs, *MBB, DefOnEntry, UndefOnEntry))
3210b57cec5SDimitry Andric       continue;
3220b57cec5SDimitry Andric     addLiveInBlock(LR, DomTree->getNode(MBB));
3230b57cec5SDimitry Andric     if (MBB == &UseMBB)
3240b57cec5SDimitry Andric       LiveIn.back().Kill = Use;
3250b57cec5SDimitry Andric   }
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric   return false;
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric // This is essentially the same iterative algorithm that SSAUpdater uses,
3310b57cec5SDimitry Andric // except we already have a dominator tree, so we don't have to recompute it.
updateSSA()3320b57cec5SDimitry Andric void LiveRangeCalc::updateSSA() {
3330b57cec5SDimitry Andric   assert(Indexes && "Missing SlotIndexes");
3340b57cec5SDimitry Andric   assert(DomTree && "Missing dominator tree");
3350b57cec5SDimitry Andric 
3360b57cec5SDimitry Andric   // Interate until convergence.
3370b57cec5SDimitry Andric   bool Changed;
3380b57cec5SDimitry Andric   do {
3390b57cec5SDimitry Andric     Changed = false;
3400b57cec5SDimitry Andric     // Propagate live-out values down the dominator tree, inserting phi-defs
3410b57cec5SDimitry Andric     // when necessary.
3420b57cec5SDimitry Andric     for (LiveInBlock &I : LiveIn) {
3430b57cec5SDimitry Andric       MachineDomTreeNode *Node = I.DomNode;
3440b57cec5SDimitry Andric       // Skip block if the live-in value has already been determined.
3450b57cec5SDimitry Andric       if (!Node)
3460b57cec5SDimitry Andric         continue;
3470b57cec5SDimitry Andric       MachineBasicBlock *MBB = Node->getBlock();
3480b57cec5SDimitry Andric       MachineDomTreeNode *IDom = Node->getIDom();
3490b57cec5SDimitry Andric       LiveOutPair IDomValue;
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric       // We need a live-in value to a block with no immediate dominator?
3520b57cec5SDimitry Andric       // This is probably an unreachable block that has survived somehow.
3530b57cec5SDimitry Andric       bool needPHI = !IDom || !Seen.test(IDom->getBlock()->getNumber());
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric       // IDom dominates all of our predecessors, but it may not be their
3560b57cec5SDimitry Andric       // immediate dominator. Check if any of them have live-out values that are
3570b57cec5SDimitry Andric       // properly dominated by IDom. If so, we need a phi-def here.
3580b57cec5SDimitry Andric       if (!needPHI) {
3590b57cec5SDimitry Andric         IDomValue = Map[IDom->getBlock()];
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric         // Cache the DomTree node that defined the value.
3620b57cec5SDimitry Andric         if (IDomValue.first && IDomValue.first != &UndefVNI &&
3630b57cec5SDimitry Andric             !IDomValue.second) {
3640b57cec5SDimitry Andric           Map[IDom->getBlock()].second = IDomValue.second =
3650b57cec5SDimitry Andric             DomTree->getNode(Indexes->getMBBFromIndex(IDomValue.first->def));
3660b57cec5SDimitry Andric         }
3670b57cec5SDimitry Andric 
3680b57cec5SDimitry Andric         for (MachineBasicBlock *Pred : MBB->predecessors()) {
3690b57cec5SDimitry Andric           LiveOutPair &Value = Map[Pred];
3700b57cec5SDimitry Andric           if (!Value.first || Value.first == IDomValue.first)
3710b57cec5SDimitry Andric             continue;
3720b57cec5SDimitry Andric           if (Value.first == &UndefVNI) {
3730b57cec5SDimitry Andric             needPHI = true;
3740b57cec5SDimitry Andric             break;
3750b57cec5SDimitry Andric           }
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric           // Cache the DomTree node that defined the value.
3780b57cec5SDimitry Andric           if (!Value.second)
3790b57cec5SDimitry Andric             Value.second =
3800b57cec5SDimitry Andric               DomTree->getNode(Indexes->getMBBFromIndex(Value.first->def));
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric           // This predecessor is carrying something other than IDomValue.
3830b57cec5SDimitry Andric           // It could be because IDomValue hasn't propagated yet, or it could be
3840b57cec5SDimitry Andric           // because MBB is in the dominance frontier of that value.
3850b57cec5SDimitry Andric           if (DomTree->dominates(IDom, Value.second)) {
3860b57cec5SDimitry Andric             needPHI = true;
3870b57cec5SDimitry Andric             break;
3880b57cec5SDimitry Andric           }
3890b57cec5SDimitry Andric         }
3900b57cec5SDimitry Andric       }
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric       // The value may be live-through even if Kill is set, as can happen when
3930b57cec5SDimitry Andric       // we are called from extendRange. In that case LiveOutSeen is true, and
3940b57cec5SDimitry Andric       // LiveOut indicates a foreign or missing value.
3950b57cec5SDimitry Andric       LiveOutPair &LOP = Map[MBB];
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric       // Create a phi-def if required.
3980b57cec5SDimitry Andric       if (needPHI) {
3990b57cec5SDimitry Andric         Changed = true;
4000b57cec5SDimitry Andric         assert(Alloc && "Need VNInfo allocator to create PHI-defs");
4010b57cec5SDimitry Andric         SlotIndex Start, End;
4020b57cec5SDimitry Andric         std::tie(Start, End) = Indexes->getMBBRange(MBB);
4030b57cec5SDimitry Andric         LiveRange &LR = I.LR;
4040b57cec5SDimitry Andric         VNInfo *VNI = LR.getNextValue(Start, *Alloc);
4050b57cec5SDimitry Andric         I.Value = VNI;
4060b57cec5SDimitry Andric         // This block is done, we know the final value.
4070b57cec5SDimitry Andric         I.DomNode = nullptr;
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric         // Add liveness since updateFromLiveIns now skips this node.
4100b57cec5SDimitry Andric         if (I.Kill.isValid()) {
4110b57cec5SDimitry Andric           if (VNI)
4120b57cec5SDimitry Andric             LR.addSegment(LiveInterval::Segment(Start, I.Kill, VNI));
4130b57cec5SDimitry Andric         } else {
4140b57cec5SDimitry Andric           if (VNI)
4150b57cec5SDimitry Andric             LR.addSegment(LiveInterval::Segment(Start, End, VNI));
4160b57cec5SDimitry Andric           LOP = LiveOutPair(VNI, Node);
4170b57cec5SDimitry Andric         }
4180b57cec5SDimitry Andric       } else if (IDomValue.first && IDomValue.first != &UndefVNI) {
4190b57cec5SDimitry Andric         // No phi-def here. Remember incoming value.
4200b57cec5SDimitry Andric         I.Value = IDomValue.first;
4210b57cec5SDimitry Andric 
4220b57cec5SDimitry Andric         // If the IDomValue is killed in the block, don't propagate through.
4230b57cec5SDimitry Andric         if (I.Kill.isValid())
4240b57cec5SDimitry Andric           continue;
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric         // Propagate IDomValue if it isn't killed:
4270b57cec5SDimitry Andric         // MBB is live-out and doesn't define its own value.
4280b57cec5SDimitry Andric         if (LOP.first == IDomValue.first)
4290b57cec5SDimitry Andric           continue;
4300b57cec5SDimitry Andric         Changed = true;
4310b57cec5SDimitry Andric         LOP = IDomValue;
4320b57cec5SDimitry Andric       }
4330b57cec5SDimitry Andric     }
4340b57cec5SDimitry Andric   } while (Changed);
4350b57cec5SDimitry Andric }
4360b57cec5SDimitry Andric 
isJointlyDominated(const MachineBasicBlock * MBB,ArrayRef<SlotIndex> Defs,const SlotIndexes & Indexes)4370b57cec5SDimitry Andric bool LiveRangeCalc::isJointlyDominated(const MachineBasicBlock *MBB,
4380b57cec5SDimitry Andric                                        ArrayRef<SlotIndex> Defs,
4390b57cec5SDimitry Andric                                        const SlotIndexes &Indexes) {
4400b57cec5SDimitry Andric   const MachineFunction &MF = *MBB->getParent();
4410b57cec5SDimitry Andric   BitVector DefBlocks(MF.getNumBlockIDs());
4420b57cec5SDimitry Andric   for (SlotIndex I : Defs)
4430b57cec5SDimitry Andric     DefBlocks.set(Indexes.getMBBFromIndex(I)->getNumber());
4440b57cec5SDimitry Andric 
4450b57cec5SDimitry Andric   SetVector<unsigned> PredQueue;
4460b57cec5SDimitry Andric   PredQueue.insert(MBB->getNumber());
4470b57cec5SDimitry Andric   for (unsigned i = 0; i != PredQueue.size(); ++i) {
4480b57cec5SDimitry Andric     unsigned BN = PredQueue[i];
4490b57cec5SDimitry Andric     if (DefBlocks[BN])
4500b57cec5SDimitry Andric       return true;
4510b57cec5SDimitry Andric     const MachineBasicBlock *B = MF.getBlockNumbered(BN);
4520b57cec5SDimitry Andric     for (const MachineBasicBlock *P : B->predecessors())
4530b57cec5SDimitry Andric       PredQueue.insert(P->getNumber());
4540b57cec5SDimitry Andric   }
4550b57cec5SDimitry Andric   return false;
4560b57cec5SDimitry Andric }
457