Skip to content
Open
6 changes: 3 additions & 3 deletions llvm/include/llvm/CodeGen/LiveInterval.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,9 @@ namespace llvm {
}

/// Constructs a new LiveRange object.
LiveRange(bool UseSegmentSet = false)
: segmentSet(UseSegmentSet ? std::make_unique<SegmentSet>()
: nullptr) {}
explicit LiveRange(bool UseSegmentSet = false)
: segmentSet(UseSegmentSet ? std::make_unique<SegmentSet>() : nullptr) {
}

/// Constructs a new LiveRange object by copying segments and valnos from
/// another LiveRange.
Expand Down
44 changes: 19 additions & 25 deletions llvm/include/llvm/CodeGen/LiveStacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,49 +40,43 @@ class LiveStacks {
///
VNInfo::Allocator VNInfoAllocator;

/// S2IMap - Stack slot indices to live interval mapping.
using SS2IntervalMap = std::unordered_map<int, LiveInterval>;
SS2IntervalMap S2IMap;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching the map strategy should be a separate patch from the cosmetic changes

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, #165477


/// S2RCMap - Stack slot indices to register class mapping.
std::map<int, const TargetRegisterClass *> S2RCMap;
int StartIdx = -1;
SmallVector<LiveInterval *> S2LI;
SmallVector<const TargetRegisterClass *> S2RC;

public:
using iterator = SS2IntervalMap::iterator;
using const_iterator = SS2IntervalMap::const_iterator;
using iterator = SmallVector<LiveInterval *>::iterator;
using const_iterator = SmallVector<LiveInterval *>::const_iterator;

const_iterator begin() const { return S2IMap.begin(); }
const_iterator end() const { return S2IMap.end(); }
iterator begin() { return S2IMap.begin(); }
iterator end() { return S2IMap.end(); }
const_iterator begin() const { return S2LI.begin(); }
const_iterator end() const { return S2LI.end(); }
iterator begin() { return S2LI.begin(); }
iterator end() { return S2LI.end(); }

unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); }
unsigned getStartIdx() const { return StartIdx; }
unsigned getNumIntervals() const { return (unsigned)S2LI.size(); }

LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC);

LiveInterval &getInterval(int Slot) {
assert(Slot >= 0 && "Spill slot indice must be >= 0");
SS2IntervalMap::iterator I = S2IMap.find(Slot);
assert(I != S2IMap.end() && "Interval does not exist for stack slot");
return I->second;
return *S2LI[Slot - StartIdx];
}

const LiveInterval &getInterval(int Slot) const {
assert(Slot >= 0 && "Spill slot indice must be >= 0");
SS2IntervalMap::const_iterator I = S2IMap.find(Slot);
assert(I != S2IMap.end() && "Interval does not exist for stack slot");
return I->second;
return *S2LI[Slot - StartIdx];
}

bool hasInterval(int Slot) const { return S2IMap.count(Slot); }
bool hasInterval(int Slot) const {
if (Slot < StartIdx || StartIdx == -1)
return false;
return !getInterval(Slot).empty();
}

const TargetRegisterClass *getIntervalRegClass(int Slot) const {
assert(Slot >= 0 && "Spill slot indice must be >= 0");
std::map<int, const TargetRegisterClass *>::const_iterator I =
S2RCMap.find(Slot);
assert(I != S2RCMap.end() &&
"Register class info does not exist for stack slot");
return I->second;
return S2RC[Slot - StartIdx];
}

VNInfo::Allocator &getVNInfoAllocator() { return VNInfoAllocator; }
Expand Down
43 changes: 0 additions & 43 deletions llvm/include/llvm/DebugInfo/PDB/Native/FormatUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,49 +62,6 @@ LLVM_ABI std::string formatChunkKind(codeview::DebugSubsectionKind Kind,
LLVM_ABI std::string formatSymbolKind(codeview::SymbolKind K);
LLVM_ABI std::string formatTypeLeafKind(codeview::TypeLeafKind K);

/// Returns the number of digits in the given integer.
inline int NumDigits(uint64_t N) {
if (N < 10ULL)
return 1;
if (N < 100ULL)
return 2;
if (N < 1000ULL)
return 3;
if (N < 10000ULL)
return 4;
if (N < 100000ULL)
return 5;
if (N < 1000000ULL)
return 6;
if (N < 10000000ULL)
return 7;
if (N < 100000000ULL)
return 8;
if (N < 1000000000ULL)
return 9;
if (N < 10000000000ULL)
return 10;
if (N < 100000000000ULL)
return 11;
if (N < 1000000000000ULL)
return 12;
if (N < 10000000000000ULL)
return 13;
if (N < 100000000000000ULL)
return 14;
if (N < 1000000000000000ULL)
return 15;
if (N < 10000000000000000ULL)
return 16;
if (N < 100000000000000000ULL)
return 17;
if (N < 1000000000000000000ULL)
return 18;
if (N < 10000000000000000000ULL)
return 19;
return 20;
}

namespace detail {
template <typename T>
struct EndianAdapter final
Expand Down
9 changes: 5 additions & 4 deletions llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,17 +183,18 @@ Error iterateSymbolGroups(InputFile &Input, const PrintScope &HeaderScope,
if (Filters.DumpModi) {
uint32_t Modi = *Filters.DumpModi;
SymbolGroup SG(&Input, Modi);
return iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(Modi)),
return iterateOneModule(Input,
withLabelWidth(HeaderScope, NumDigitsBase10(Modi)),
SG, Modi, Callback);
}

uint32_t I = 0;

for (const auto &SG : Input.symbol_groups()) {
if (shouldDumpSymbolGroup(I, SG, Filters))
if (auto Err =
iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(I)),
SG, I, Callback))
if (auto Err = iterateOneModule(
Input, withLabelWidth(HeaderScope, NumDigitsBase10(I)), SG, I,
Callback))
return Err;

++I;
Expand Down
35 changes: 35 additions & 0 deletions llvm/include/llvm/Support/MathExtras.h
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,41 @@ using stack_float_t = volatile float;
using stack_float_t = float;
#endif

/// Returns the number of digits in the given integer.
inline int NumDigitsBase10(uint64_t X) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should move this out of line. Also in general Support/ADT patches should be split out into a separate PR

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the split off. #165479

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will update this MR once this one is merged since it uses it.

static constexpr struct ConstexprData {
uint8_t AtLeast[65] = {};
uint64_t Boundaries[20] = {};
static constexpr int NumDigitsConstexpr(uint64_t N) {
int res = 1;
while (N >= 10) {
res++;
N /= 10;
}
return res;
}
constexpr ConstexprData() {
uint64_t Val = ~0ull;
for (uint64_t i = 0; i <= 64; i++) {
uint64_t Digits = NumDigitsConstexpr(Val) - 1;
AtLeast[i] = Digits;
Val >>= 1;
}
// Special case because X=0 should return 1 and not 0
Boundaries[0] = 0;
Val = 10;
for (uint64_t i = 1; i < 20; i++) {
Boundaries[i] = Val;
Val *= 10;
}
}
} Data;

uint64_t Base2 = X ? countl_zero(X) : 64;
uint64_t Digits = Data.AtLeast[Base2];
return Digits + (X >= Data.Boundaries[Digits]);
}

} // namespace llvm

#endif
41 changes: 22 additions & 19 deletions llvm/lib/CodeGen/LiveStacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ void LiveStacksWrapperLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
}

void LiveStacks::releaseMemory() {
for (int Idx = 0; Idx < (int)S2LI.size(); ++Idx)
S2LI[Idx]->~LiveInterval();
// Release VNInfo memory regions, VNInfo objects don't need to be dtor'd.
VNInfoAllocator.Reset();
S2IMap.clear();
S2RCMap.clear();
S2LI.clear();
S2RC.clear();
}

void LiveStacks::init(MachineFunction &MF) {
Expand All @@ -52,20 +54,22 @@ void LiveStacks::init(MachineFunction &MF) {
LiveInterval &
LiveStacks::getOrCreateInterval(int Slot, const TargetRegisterClass *RC) {
assert(Slot >= 0 && "Spill slot indice must be >= 0");
SS2IntervalMap::iterator I = S2IMap.find(Slot);
if (I == S2IMap.end()) {
I = S2IMap
.emplace(
std::piecewise_construct, std::forward_as_tuple(Slot),
std::forward_as_tuple(Register::index2StackSlot(Slot), 0.0F))
.first;
S2RCMap.insert(std::make_pair(Slot, RC));
if (StartIdx == -1)
StartIdx = Slot;

int Idx = Slot - StartIdx;
assert(Idx >= 0 && "Slot not in order ?");
if (Idx < (int)S2LI.size()) {
S2RC[Idx] = TRI->getCommonSubClass(S2RC[Idx], RC);
} else {
// Use the largest common subclass register class.
const TargetRegisterClass *&OldRC = S2RCMap[Slot];
OldRC = TRI->getCommonSubClass(OldRC, RC);
S2RC.resize(Idx + 1);
S2LI.resize(Idx + 1);
S2LI[Idx] = this->VNInfoAllocator.Allocate<LiveInterval>();
new (S2LI[Idx]) LiveInterval(Register::index2StackSlot(Slot), 0.0F);
S2RC[Idx] = RC;
}
return I->second;
assert(S2RC.size() == S2LI.size());
return *S2LI[Idx];
}

AnalysisKey LiveStacksAnalysis::Key;
Expand Down Expand Up @@ -96,13 +100,12 @@ void LiveStacksWrapperLegacy::print(raw_ostream &OS, const Module *) const {
}

/// print - Implement the dump method.
void LiveStacks::print(raw_ostream &OS, const Module*) const {
void LiveStacks::print(raw_ostream &OS, const Module *) const {

OS << "********** INTERVALS **********\n";
for (const_iterator I = begin(), E = end(); I != E; ++I) {
I->second.print(OS);
int Slot = I->first;
const TargetRegisterClass *RC = getIntervalRegClass(Slot);
for (int Idx = 0; Idx < (int)S2LI.size(); ++Idx) {
S2LI[Idx]->print(OS);
const TargetRegisterClass *RC = S2RC[Idx];
if (RC)
OS << " [" << TRI->getRegClassName(RC) << "]\n";
else
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/CodeGen/MachineFrameInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
Expand Down Expand Up @@ -221,6 +222,12 @@ void MachineFrameInfo::print(const MachineFunction &MF, raw_ostream &OS) const{
if (SO.StackID != 0)
OS << "id=" << static_cast<unsigned>(SO.StackID) << ' ';

if (SO.Alloca && !SO.Alloca->getName().empty())
OS << "alloca=" << SO.Alloca->getName() << ' ';

if (SO.isSpillSlot)
OS << "spill ";

if (SO.Size == ~0ULL) {
OS << "dead\n";
continue;
Expand Down
Loading