Skip to content

Commit

Permalink
Merged master:7ba3293691be into amd-gfx:f2bcfb477c22
Browse files Browse the repository at this point in the history
Local branch amd-gfx f2bcfb4 Merged master:c298824f9caf into amd-gfx:c54224fe9b38
Remote branch master 7ba3293 [StackColoring] Conservatively merge catch point of V for catch(V)
  • Loading branch information
Sw authored and Sw committed Nov 4, 2020
2 parents f2bcfb4 + 7ba3293 commit 362b062
Show file tree
Hide file tree
Showing 23 changed files with 993 additions and 154 deletions.
4 changes: 2 additions & 2 deletions clang-tools-extra/clangd/ConfigFragment.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ template <typename T> struct Located {
: Range(Range), Value(std::move(Value)) {}

llvm::SMRange Range;
T &operator->() { return Value; }
const T &operator->() const { return Value; }
T *operator->() { return &Value; }
const T *operator->() const { return &Value; }
T &operator*() { return Value; }
const T &operator*() const { return Value; }

Expand Down
6 changes: 3 additions & 3 deletions llvm/include/llvm/CodeGen/LiveRangeEdit.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ class LiveRangeEdit : private MachineRegisterInfo::Delegate {

/// Called when a virtual register is no longer used. Return false to defer
/// its deletion from LiveIntervals.
virtual bool LRE_CanEraseVirtReg(unsigned) { return true; }
virtual bool LRE_CanEraseVirtReg(Register) { return true; }

/// Called before shrinking the live range of a virtual register.
virtual void LRE_WillShrinkVirtReg(unsigned) {}
virtual void LRE_WillShrinkVirtReg(Register) {}

/// Called after cloning a virtual register.
/// This is used for new registers representing connected components of Old.
virtual void LRE_DidCloneVirtReg(unsigned New, unsigned Old) {}
virtual void LRE_DidCloneVirtReg(Register New, Register Old) {}
};

private:
Expand Down
15 changes: 15 additions & 0 deletions llvm/include/llvm/CodeGen/TargetInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1737,6 +1737,21 @@ class TargetInstrInfo : public MCInstrInfo {
return 5;
}

/// Return the maximal number of alias checks on memory operands. For
/// instructions with more than one memory operands, the alias check on a
/// single MachineInstr pair has quadratic overhead and results in
/// unacceptable performance in the worst case. The limit here is to clamp
/// that maximal checks performed. Usually, that's the product of memory
/// operand numbers from that pair of MachineInstr to be checked. For
/// instance, with two MachineInstrs with 4 and 5 memory operands
/// correspondingly, a total of 20 checks are required. With this limit set to
/// 16, their alias check is skipped. We choose to limit the product instead
/// of the individual instruction as targets may have special MachineInstrs
/// with a considerably high number of memory operands, such as `ldm` in ARM.
/// Setting this limit per MachineInstr would result in either too high
/// overhead or too rigid restriction.
virtual unsigned getMemOperandAACheckLimit() const { return 16; }

/// Return an array that contains the ids of the target indices (used for the
/// TargetIndex machine operand) and their names.
///
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/InlineSpiller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class HoistSpillHelper : private LiveRangeEdit::Delegate {
unsigned Original);
bool rmFromMergeableSpills(MachineInstr &Spill, int StackSlot);
void hoistAllSpills();
void LRE_DidCloneVirtReg(unsigned, unsigned) override;
void LRE_DidCloneVirtReg(Register, Register) override;
};

class InlineSpiller : public Spiller {
Expand Down Expand Up @@ -1551,7 +1551,7 @@ void HoistSpillHelper::hoistAllSpills() {

/// For VirtReg clone, the \p New register should have the same physreg or
/// stackslot as the \p old register.
void HoistSpillHelper::LRE_DidCloneVirtReg(unsigned New, unsigned Old) {
void HoistSpillHelper::LRE_DidCloneVirtReg(Register New, Register Old) {
if (VRM.hasPhys(Old))
VRM.assignVirt2Phys(New, VRM.getPhys(Old));
else if (VRM.getStackSlot(Old) != VirtRegMap::NO_STACK_SLOT)
Expand Down
145 changes: 80 additions & 65 deletions llvm/lib/CodeGen/MachineInstr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1276,81 +1276,96 @@ bool MachineInstr::mayAlias(AAResults *AA, const MachineInstr &Other,
if (TII->areMemAccessesTriviallyDisjoint(*this, Other))
return false;

// FIXME: Need to handle multiple memory operands to support all targets.
if (!hasOneMemOperand() || !Other.hasOneMemOperand())
// Memory operations without memory operands may access anything. Be
// conservative and assume `MayAlias`.
if (memoperands_empty() || Other.memoperands_empty())
return true;

MachineMemOperand *MMOa = *memoperands_begin();
MachineMemOperand *MMOb = *Other.memoperands_begin();

// The following interface to AA is fashioned after DAGCombiner::isAlias
// and operates with MachineMemOperand offset with some important
// assumptions:
// - LLVM fundamentally assumes flat address spaces.
// - MachineOperand offset can *only* result from legalization and
// cannot affect queries other than the trivial case of overlap
// checking.
// - These offsets never wrap and never step outside
// of allocated objects.
// - There should never be any negative offsets here.
//
// FIXME: Modify API to hide this math from "user"
// Even before we go to AA we can reason locally about some
// memory objects. It can save compile time, and possibly catch some
// corner cases not currently covered.

int64_t OffsetA = MMOa->getOffset();
int64_t OffsetB = MMOb->getOffset();
int64_t MinOffset = std::min(OffsetA, OffsetB);

uint64_t WidthA = MMOa->getSize();
uint64_t WidthB = MMOb->getSize();
bool KnownWidthA = WidthA != MemoryLocation::UnknownSize;
bool KnownWidthB = WidthB != MemoryLocation::UnknownSize;

const Value *ValA = MMOa->getValue();
const Value *ValB = MMOb->getValue();
bool SameVal = (ValA && ValB && (ValA == ValB));
if (!SameVal) {
const PseudoSourceValue *PSVa = MMOa->getPseudoValue();
const PseudoSourceValue *PSVb = MMOb->getPseudoValue();
if (PSVa && ValB && !PSVa->mayAlias(&MFI))
return false;
if (PSVb && ValA && !PSVb->mayAlias(&MFI))
return false;
if (PSVa && PSVb && (PSVa == PSVb))
SameVal = true;
}
// Skip if there are too many memory operands.
auto NumChecks = getNumMemOperands() * Other.getNumMemOperands();
if (NumChecks > TII->getMemOperandAACheckLimit())
return true;

auto HasAlias = [MFI, AA, UseTBAA](const MachineMemOperand *MMOa,
const MachineMemOperand *MMOb) {
// The following interface to AA is fashioned after DAGCombiner::isAlias
// and operates with MachineMemOperand offset with some important
// assumptions:
// - LLVM fundamentally assumes flat address spaces.
// - MachineOperand offset can *only* result from legalization and
// cannot affect queries other than the trivial case of overlap
// checking.
// - These offsets never wrap and never step outside
// of allocated objects.
// - There should never be any negative offsets here.
//
// FIXME: Modify API to hide this math from "user"
// Even before we go to AA we can reason locally about some
// memory objects. It can save compile time, and possibly catch some
// corner cases not currently covered.

int64_t OffsetA = MMOa->getOffset();
int64_t OffsetB = MMOb->getOffset();
int64_t MinOffset = std::min(OffsetA, OffsetB);

uint64_t WidthA = MMOa->getSize();
uint64_t WidthB = MMOb->getSize();
bool KnownWidthA = WidthA != MemoryLocation::UnknownSize;
bool KnownWidthB = WidthB != MemoryLocation::UnknownSize;

const Value *ValA = MMOa->getValue();
const Value *ValB = MMOb->getValue();
bool SameVal = (ValA && ValB && (ValA == ValB));
if (!SameVal) {
const PseudoSourceValue *PSVa = MMOa->getPseudoValue();
const PseudoSourceValue *PSVb = MMOb->getPseudoValue();
if (PSVa && ValB && !PSVa->mayAlias(&MFI))
return false;
if (PSVb && ValA && !PSVb->mayAlias(&MFI))
return false;
if (PSVa && PSVb && (PSVa == PSVb))
SameVal = true;
}

if (SameVal) {
if (!KnownWidthA || !KnownWidthB)
return true;
int64_t MaxOffset = std::max(OffsetA, OffsetB);
int64_t LowWidth = (MinOffset == OffsetA) ? WidthA : WidthB;
return (MinOffset + LowWidth > MaxOffset);
}

if (SameVal) {
if (!KnownWidthA || !KnownWidthB)
if (!AA)
return true;
int64_t MaxOffset = std::max(OffsetA, OffsetB);
int64_t LowWidth = (MinOffset == OffsetA) ? WidthA : WidthB;
return (MinOffset + LowWidth > MaxOffset);
}

if (!AA)
return true;
if (!ValA || !ValB)
return true;

if (!ValA || !ValB)
return true;
assert((OffsetA >= 0) && "Negative MachineMemOperand offset");
assert((OffsetB >= 0) && "Negative MachineMemOperand offset");

assert((OffsetA >= 0) && "Negative MachineMemOperand offset");
assert((OffsetB >= 0) && "Negative MachineMemOperand offset");
int64_t OverlapA = KnownWidthA ? WidthA + OffsetA - MinOffset
: MemoryLocation::UnknownSize;
int64_t OverlapB = KnownWidthB ? WidthB + OffsetB - MinOffset
: MemoryLocation::UnknownSize;

int64_t OverlapA = KnownWidthA ? WidthA + OffsetA - MinOffset
: MemoryLocation::UnknownSize;
int64_t OverlapB = KnownWidthB ? WidthB + OffsetB - MinOffset
: MemoryLocation::UnknownSize;
AliasResult AAResult =
AA->alias(MemoryLocation(ValA, OverlapA,
UseTBAA ? MMOa->getAAInfo() : AAMDNodes()),
MemoryLocation(ValB, OverlapB,
UseTBAA ? MMOb->getAAInfo() : AAMDNodes()));

AliasResult AAResult = AA->alias(
MemoryLocation(ValA, OverlapA,
UseTBAA ? MMOa->getAAInfo() : AAMDNodes()),
MemoryLocation(ValB, OverlapB,
UseTBAA ? MMOb->getAAInfo() : AAMDNodes()));
return (AAResult != NoAlias);
};

return (AAResult != NoAlias);
// Check each pair of memory operands from both instructions, which can't
// alias only if all pairs won't alias.
for (auto *MMOa : memoperands())
for (auto *MMOb : Other.memoperands())
if (HasAlias(MMOa, MMOb))
return true;

return false;
}

/// hasOrderedMemoryRef - Return true if this instruction may have an ordered
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/RegAllocBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void RegAllocBase::seedLiveRegs() {
NamedRegionTimer T("seed", "Seed Live Regs", TimerGroupName,
TimerGroupDescription, TimePassesIsEnabled);
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
unsigned Reg = Register::index2VirtReg(i);
Register Reg = Register::index2VirtReg(i);
if (MRI->reg_nodbg_empty(Reg))
continue;
enqueue(&LIS->getInterval(Reg));
Expand Down Expand Up @@ -143,7 +143,7 @@ void RegAllocBase::allocatePhysRegs() {
if (AvailablePhysReg)
Matrix->assign(*VirtReg, AvailablePhysReg);

for (unsigned Reg : SplitVRegs) {
for (Register Reg : SplitVRegs) {
assert(LIS->hasInterval(Reg));

LiveInterval *SplitVirtReg = &LIS->getInterval(Reg);
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/CodeGen/RegAllocBasic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ class RABasic : public MachineFunctionPass,
// selectOrSplit().
BitVector UsableRegs;

bool LRE_CanEraseVirtReg(unsigned) override;
void LRE_WillShrinkVirtReg(unsigned) override;
bool LRE_CanEraseVirtReg(Register) override;
void LRE_WillShrinkVirtReg(Register) override;

public:
RABasic();
Expand Down Expand Up @@ -146,7 +146,7 @@ INITIALIZE_PASS_DEPENDENCY(LiveRegMatrix)
INITIALIZE_PASS_END(RABasic, "regallocbasic", "Basic Register Allocator", false,
false)

bool RABasic::LRE_CanEraseVirtReg(unsigned VirtReg) {
bool RABasic::LRE_CanEraseVirtReg(Register VirtReg) {
LiveInterval &LI = LIS->getInterval(VirtReg);
if (VRM->hasPhys(VirtReg)) {
Matrix->unassign(LI);
Expand All @@ -161,7 +161,7 @@ bool RABasic::LRE_CanEraseVirtReg(unsigned VirtReg) {
return false;
}

void RABasic::LRE_WillShrinkVirtReg(unsigned VirtReg) {
void RABasic::LRE_WillShrinkVirtReg(Register VirtReg) {
if (!VRM->hasPhys(VirtReg))
return;

Expand Down
Loading

0 comments on commit 362b062

Please sign in to comment.