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