mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-01 15:17:25 +00:00
Allow overlaps between virtreg and physreg live ranges.
The RegisterCoalescer understands overlapping live ranges where one register is defined as a copy of the other. With this change, register allocators using LiveRegMatrix can do the same, at least for copies between physical and virtual registers. When a physreg is defined by a copy from a virtreg, allow those live ranges to overlap: %CL<def> = COPY %vreg11:sub_8bit; GR32_ABCD:%vreg11 %vreg13<def,tied1> = SAR32rCL %vreg13<tied0>, %CL<imp-use,kill> We can assign %vreg11 to %ECX, overlapping the live range of %CL. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163336 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "RegisterCoalescer.h"
|
||||
#include <algorithm>
|
||||
using namespace llvm;
|
||||
|
||||
@@ -142,6 +143,48 @@ bool LiveInterval::overlapsFrom(const LiveInterval& other,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LiveInterval::overlaps(const LiveInterval &Other,
|
||||
const CoalescerPair &CP,
|
||||
const SlotIndexes &Indexes) const {
|
||||
assert(!empty() && "empty interval");
|
||||
if (Other.empty())
|
||||
return false;
|
||||
|
||||
// Use binary searches to find initial positions.
|
||||
const_iterator I = find(Other.beginIndex());
|
||||
const_iterator IE = end();
|
||||
if (I == IE)
|
||||
return false;
|
||||
const_iterator J = Other.find(I->start);
|
||||
const_iterator JE = Other.end();
|
||||
if (J == JE)
|
||||
return false;
|
||||
|
||||
for (;;) {
|
||||
// J has just been advanced to satisfy:
|
||||
assert(J->end >= I->start);
|
||||
// Check for an overlap.
|
||||
if (J->start < I->end) {
|
||||
// I and J are overlapping. Find the later start.
|
||||
SlotIndex Def = std::max(I->start, J->start);
|
||||
// Allow the overlap if Def is a coalescable copy.
|
||||
if (Def.isBlock() ||
|
||||
!CP.isCoalescable(Indexes.getInstructionFromIndex(Def)))
|
||||
return true;
|
||||
}
|
||||
// Advance the iterator that ends first to check for more overlaps.
|
||||
if (J->end > I->end) {
|
||||
std::swap(I, J);
|
||||
std::swap(IE, JE);
|
||||
}
|
||||
// Advance J until J->end >= I->start.
|
||||
do
|
||||
if (++J == JE)
|
||||
return false;
|
||||
while (J->end < I->start);
|
||||
}
|
||||
}
|
||||
|
||||
/// overlaps - Return true if the live interval overlaps a range specified
|
||||
/// by [Start, End).
|
||||
bool LiveInterval::overlaps(SlotIndex Start, SlotIndex End) const {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#define DEBUG_TYPE "regalloc"
|
||||
#include "LiveRegMatrix.h"
|
||||
#include "RegisterCoalescer.h"
|
||||
#include "VirtRegMap.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
@@ -117,8 +118,9 @@ bool LiveRegMatrix::checkRegUnitInterference(LiveInterval &VirtReg,
|
||||
unsigned PhysReg) {
|
||||
if (VirtReg.empty())
|
||||
return false;
|
||||
CoalescerPair CP(VirtReg.reg, PhysReg, *TRI);
|
||||
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units)
|
||||
if (VirtReg.overlaps(LIS->getRegUnit(*Units)))
|
||||
if (VirtReg.overlaps(LIS->getRegUnit(*Units), CP, *LIS->getSlotIndexes()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,13 @@ namespace llvm {
|
||||
: TRI(tri), DstReg(0), SrcReg(0), DstIdx(0), SrcIdx(0),
|
||||
Partial(false), CrossClass(false), Flipped(false), NewRC(0) {}
|
||||
|
||||
/// Create a CoalescerPair representing a virtreg-to-physreg copy.
|
||||
/// No need to call setRegisters().
|
||||
CoalescerPair(unsigned VirtReg, unsigned PhysReg,
|
||||
const TargetRegisterInfo &tri)
|
||||
: TRI(tri), DstReg(PhysReg), SrcReg(VirtReg), DstIdx(0), SrcIdx(0),
|
||||
Partial(false), CrossClass(false), Flipped(false), NewRC(0) {}
|
||||
|
||||
/// setRegisters - set registers to match the copy instruction MI. Return
|
||||
/// false if MI is not a coalescable copy instruction.
|
||||
bool setRegisters(const MachineInstr*);
|
||||
|
||||
Reference in New Issue
Block a user