aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-04-04 21:00:03 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-04-04 21:00:03 +0000
commit4662a9f270fe2c916c35545718720ed181384c30 (patch)
tree331cf4d4d3f80cbba0e2473652746b2b27d10ee7 /lib/CodeGen
parent0c1953d8cf02edfae896b0a983d345ad61b13b9f (diff)
Allow coalescing with reserved physregs in certain cases:
When a virtual register has a single value that is defined as a copy of a reserved register, permit that copy to be joined. These virtual register are usually copies of the stack pointer: %vreg75<def> = COPY %ESP; GR32:%vreg75 MOV32mr %vreg75, 1, %noreg, 0, %noreg, %vreg74<kill> MOV32mi %vreg75, 1, %noreg, 8, %noreg, 0 MOV32mi %vreg75<kill>, 1, %noreg, 4, %noreg, 0 CALLpcrel32 ... Coalescing these virtual registers early decreases register pressure. Previously, they were coalesced by RALinScan::attemptTrivialCoalescing after register allocation was completed. The lower register pressure causes the mcinst-lowering-cmp0.ll test case to fail because it depends on linear scan spilling a particular register. I am deleting 2008-08-05-SpillerBug.ll because it is counting the number of instructions emitted, and its revision history shows the 'correct' count being edited many times. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128845 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp2
-rw-r--r--lib/CodeGen/RegAllocLinearScan.cpp2
-rw-r--r--lib/CodeGen/SimpleRegisterCoalescing.cpp16
3 files changed, 14 insertions, 6 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 68bd0a60c9..07f83ea7ce 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -572,7 +572,7 @@ void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB,
if (TargetRegisterInfo::isVirtualRegister(MO.getReg()))
handleVirtualRegisterDef(MBB, MI, MIIdx, MO, MOIdx,
getOrCreateInterval(MO.getReg()));
- else if (allocatableRegs_[MO.getReg()]) {
+ else {
MachineInstr *CopyMI = NULL;
if (MI->isCopyLike())
CopyMI = MI;
diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp
index 966570f3f3..ef78949c54 100644
--- a/lib/CodeGen/RegAllocLinearScan.cpp
+++ b/lib/CodeGen/RegAllocLinearScan.cpp
@@ -572,7 +572,7 @@ void RALinScan::initIntervalSets()
for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i) {
if (TargetRegisterInfo::isPhysicalRegister(i->second->reg)) {
- if (!i->second->empty()) {
+ if (!i->second->empty() && allocatableRegs_.test(i->second->reg)) {
mri_->setPhysRegUsed(i->second->reg);
fixed_.push_back(std::make_pair(i->second, i->second->begin()));
}
diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp
index 93aa0a3120..c621726a03 100644
--- a/lib/CodeGen/SimpleRegisterCoalescing.cpp
+++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp
@@ -919,13 +919,23 @@ SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li,
/// are not spillable! If the destination interval uses are far away, think
/// twice about coalescing them!
bool SimpleRegisterCoalescing::shouldJoinPhys(CoalescerPair &CP) {
+ bool Allocatable = li_->isAllocatable(CP.getDstReg());
+ LiveInterval &JoinVInt = li_->getInterval(CP.getSrcReg());
+
+ /// Always join simple intervals that are defined by a single copy from a
+ /// reserved register. This doesn't increase register pressure, so it is
+ /// always beneficial.
+ if (!Allocatable && CP.isFlipped() && JoinVInt.containsOneValue())
+ return true;
+
if (DisablePhysicalJoin) {
DEBUG(dbgs() << "\tPhysreg joins disabled.\n");
return false;
}
- // Only coalesce to allocatable physreg.
- if (!li_->isAllocatable(CP.getDstReg())) {
+ // Only coalesce to allocatable physreg, we don't want to risk modifying
+ // reserved registers.
+ if (!Allocatable) {
DEBUG(dbgs() << "\tRegister is an unallocatable physreg.\n");
return false; // Not coalescable.
}
@@ -944,8 +954,6 @@ bool SimpleRegisterCoalescing::shouldJoinPhys(CoalescerPair &CP) {
// FIXME: Why are we skipping this test for partial copies?
// CodeGen/X86/phys_subreg_coalesce-3.ll needs it.
if (!CP.isPartial()) {
- LiveInterval &JoinVInt = li_->getInterval(CP.getSrcReg());
-
const TargetRegisterClass *RC = mri_->getRegClass(CP.getSrcReg());
unsigned Threshold = allocatableRCRegs_[RC].count() * 2;
unsigned Length = li_->getApproximateInstructionCount(JoinVInt);