aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/LiveIntervalAnalysis.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2009-12-04 00:16:04 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2009-12-04 00:16:04 +0000
commit6b74e505be1016223e090a6c806f7caa3165a146 (patch)
treedcc016454a3e8332b8d9f3e22e331a4ab0073158 /lib/CodeGen/LiveIntervalAnalysis.cpp
parent2e65c29ac64e7b36603d1a1de3d01cdfd2e61e23 (diff)
downloadexternal_llvm-6b74e505be1016223e090a6c806f7caa3165a146.zip
external_llvm-6b74e505be1016223e090a6c806f7caa3165a146.tar.gz
external_llvm-6b74e505be1016223e090a6c806f7caa3165a146.tar.bz2
Also attempt trivial coalescing for live intervals that end in a copy.
The coalescer is supposed to clean these up, but when setting up parameters for a function call, there may be copies to physregs. If the defining instruction has been LICM'ed far away, the coalescer won't touch it. The register allocation hint does not always work - when the register allocator is backtracking, it clears the hints. This patch takes care of a few more cases that r90163 missed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90502 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LiveIntervalAnalysis.cpp')
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp54
1 files changed, 47 insertions, 7 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 35337ef..0945634 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -157,19 +157,15 @@ bool LiveIntervals::conflictsWithPhysRegDef(const LiveInterval &li,
I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) {
for (SlotIndex index = I->start.getBaseIndex(),
end = I->end.getPrevSlot().getBaseIndex().getNextIndex();
- index != end;
- index = index.getNextIndex()) {
+ index != end;
+ index = index.getNextIndex()) {
MachineInstr *MI = getInstructionFromIndex(index);
if (!MI)
continue; // skip deleted instructions
- unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
- if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
- if (SrcReg == li.reg || DstReg == li.reg)
- continue;
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
MachineOperand& mop = MI->getOperand(i);
- if (!mop.isReg())
+ if (!mop.isReg() || mop.isUse())
continue;
unsigned PhysReg = mop.getReg();
if (PhysReg == 0 || PhysReg == li.reg)
@@ -188,6 +184,50 @@ bool LiveIntervals::conflictsWithPhysRegDef(const LiveInterval &li,
return false;
}
+/// conflictsWithPhysRegUse - Returns true if the specified register is used or
+/// defined during the duration of the specified interval. Copies to and from
+/// li.reg are allowed.
+bool LiveIntervals::conflictsWithPhysRegUse(const LiveInterval &li,
+ VirtRegMap &vrm, unsigned reg) {
+ for (LiveInterval::Ranges::const_iterator
+ I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) {
+ for (SlotIndex index = I->start.getBaseIndex(),
+ end = I->end.getPrevSlot().getBaseIndex().getNextIndex();
+ index != end;
+ index = index.getNextIndex()) {
+ MachineInstr *MI = getInstructionFromIndex(index);
+ if (!MI)
+ continue; // skip deleted instructions
+
+ // Terminators are considered conflicts since reg may be used at the
+ // destination.
+ if (MI->getDesc().isTerminator())
+ return true;
+
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand& mop = MI->getOperand(i);
+ if (!mop.isReg() || mop.isUndef())
+ continue;
+ unsigned PhysReg = mop.getReg();
+ if (PhysReg == 0 || PhysReg == li.reg)
+ continue;
+ if (TargetRegisterInfo::isVirtualRegister(PhysReg)) {
+ if (!vrm.hasPhys(PhysReg))
+ continue;
+ PhysReg = vrm.getPhys(PhysReg);
+ }
+ if (PhysReg && tri_->regsOverlap(PhysReg, reg)) {
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+ if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) ||
+ (SrcReg != li.reg && DstReg != li.reg))
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
/// conflictsWithPhysRegRef - Similar to conflictsWithPhysRegRef except
/// it can check use as well.
bool LiveIntervals::conflictsWithPhysRegRef(LiveInterval &li,