#include "llvm/CodeGen/LiveInterval.h"
#include "LiveRangeUtils.h"
#include "RegisterCoalescer.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <iterator>
#include <utility>
usingnamespacellvm;
namespace {
template <typename ImplT, typename IteratorT, typename CollectionT>
class CalcLiveRangeUtilBase { … };
class CalcLiveRangeUtilVector;
CalcLiveRangeUtilVectorBase;
class CalcLiveRangeUtilVector : public CalcLiveRangeUtilVectorBase { … };
class CalcLiveRangeUtilSet;
CalcLiveRangeUtilSetBase;
class CalcLiveRangeUtilSet : public CalcLiveRangeUtilSetBase { … };
}
LiveRange::iterator LiveRange::find(SlotIndex Pos) { … }
VNInfo *LiveRange::createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc) { … }
VNInfo *LiveRange::createDeadDef(VNInfo *VNI) { … }
bool LiveRange::overlapsFrom(const LiveRange& other,
const_iterator StartPos) const { … }
bool LiveRange::overlaps(const LiveRange &Other, const CoalescerPair &CP,
const SlotIndexes &Indexes) const { … }
bool LiveRange::overlaps(SlotIndex Start, SlotIndex End) const { … }
bool LiveRange::covers(const LiveRange &Other) const { … }
void LiveRange::markValNoForDeletion(VNInfo *ValNo) { … }
void LiveRange::RenumberValues() { … }
void LiveRange::addSegmentToSet(Segment S) { … }
LiveRange::iterator LiveRange::addSegment(Segment S) { … }
void LiveRange::append(const Segment S) { … }
std::pair<VNInfo*,bool> LiveRange::extendInBlock(ArrayRef<SlotIndex> Undefs,
SlotIndex StartIdx, SlotIndex Kill) { … }
VNInfo *LiveRange::extendInBlock(SlotIndex StartIdx, SlotIndex Kill) { … }
void LiveRange::removeSegment(SlotIndex Start, SlotIndex End,
bool RemoveDeadValNo) { … }
LiveRange::iterator LiveRange::removeSegment(iterator I, bool RemoveDeadValNo) { … }
void LiveRange::removeValNoIfDead(VNInfo *ValNo) { … }
void LiveRange::removeValNo(VNInfo *ValNo) { … }
void LiveRange::join(LiveRange &Other,
const int *LHSValNoAssignments,
const int *RHSValNoAssignments,
SmallVectorImpl<VNInfo *> &NewVNInfo) { … }
void LiveRange::MergeSegmentsInAsValue(const LiveRange &RHS,
VNInfo *LHSValNo) { … }
void LiveRange::MergeValueInAsValue(const LiveRange &RHS,
const VNInfo *RHSValNo,
VNInfo *LHSValNo) { … }
VNInfo *LiveRange::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) { … }
void LiveRange::flushSegmentSet() { … }
bool LiveRange::isLiveAtIndexes(ArrayRef<SlotIndex> Slots) const { … }
void LiveInterval::freeSubRange(SubRange *S) { … }
void LiveInterval::removeEmptySubRanges() { … }
void LiveInterval::clearSubRanges() { … }
static void stripValuesNotDefiningMask(unsigned Reg, LiveInterval::SubRange &SR,
LaneBitmask LaneMask,
const SlotIndexes &Indexes,
const TargetRegisterInfo &TRI,
unsigned ComposeSubRegIdx) { … }
void LiveInterval::refineSubRanges(
BumpPtrAllocator &Allocator, LaneBitmask LaneMask,
std::function<void(LiveInterval::SubRange &)> Apply,
const SlotIndexes &Indexes, const TargetRegisterInfo &TRI,
unsigned ComposeSubRegIdx) { … }
unsigned LiveInterval::getSize() const { … }
void LiveInterval::computeSubRangeUndefs(SmallVectorImpl<SlotIndex> &Undefs,
LaneBitmask LaneMask,
const MachineRegisterInfo &MRI,
const SlotIndexes &Indexes) const { … }
raw_ostream& llvm::operator<<(raw_ostream& OS, const LiveRange::Segment &S) { … }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void LiveRange::Segment::dump() const {
dbgs() << *this << '\n';
}
#endif
void LiveRange::print(raw_ostream &OS) const { … }
void LiveInterval::SubRange::print(raw_ostream &OS) const { … }
void LiveInterval::print(raw_ostream &OS) const { … }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void LiveRange::dump() const {
dbgs() << *this << '\n';
}
LLVM_DUMP_METHOD void LiveInterval::SubRange::dump() const {
dbgs() << *this << '\n';
}
LLVM_DUMP_METHOD void LiveInterval::dump() const {
dbgs() << *this << '\n';
}
#endif
#ifndef NDEBUG
bool LiveRange::verify() const {
for (const_iterator I = begin(), E = end(); I != E; ++I) {
if (!I->start.isValid())
return false;
if (!I->end.isValid())
return false;
if (I->start >= I->end)
return false;
if (I->valno == nullptr)
return false;
if (I->valno->id >= valnos.size())
return false;
if (I->valno != valnos[I->valno->id])
return false;
if (std::next(I) != E) {
if (I->end > std::next(I)->start)
return false;
if (I->end == std::next(I)->start) {
if (I->valno == std::next(I)->valno)
return false;
}
}
}
return true;
}
bool LiveInterval::verify(const MachineRegisterInfo *MRI) const {
if (!super::verify())
return false;
LaneBitmask Mask;
LaneBitmask MaxMask = MRI != nullptr ? MRI->getMaxLaneMaskForVReg(reg())
: LaneBitmask::getAll();
for (const SubRange &SR : subranges()) {
if ((Mask & SR.LaneMask).any())
return false;
Mask |= SR.LaneMask;
if ((Mask & ~MaxMask).any())
return false;
if (SR.empty())
return false;
if (!SR.verify())
return false;
if (!covers(SR))
return false;
}
return true;
}
#endif
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void LiveRangeUpdater::print(raw_ostream &OS) const {
if (!isDirty()) {
if (LR)
OS << "Clean updater: " << *LR << '\n';
else
OS << "Null updater.\n";
return;
}
assert(LR && "Can't have null LR in dirty updater.");
OS << " updater with gap = " << (ReadI - WriteI)
<< ", last start = " << LastStart
<< ":\n Area 1:";
for (const auto &S : make_range(LR->begin(), WriteI))
OS << ' ' << S;
OS << "\n Spills:";
for (unsigned I = 0, E = Spills.size(); I != E; ++I)
OS << ' ' << Spills[I];
OS << "\n Area 2:";
for (const auto &S : make_range(ReadI, LR->end()))
OS << ' ' << S;
OS << '\n';
}
LLVM_DUMP_METHOD void LiveRangeUpdater::dump() const {
print(errs());
}
#endif
static inline bool coalescable(const LiveRange::Segment &A,
const LiveRange::Segment &B) { … }
void LiveRangeUpdater::add(LiveRange::Segment Seg) { … }
void LiveRangeUpdater::mergeSpills() { … }
void LiveRangeUpdater::flush() { … }
unsigned ConnectedVNInfoEqClasses::Classify(const LiveRange &LR) { … }
void ConnectedVNInfoEqClasses::Distribute(LiveInterval &LI, LiveInterval *LIV[],
MachineRegisterInfo &MRI) { … }