Tweak cross-class coalescing to be more aggressive when the target class is small.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 17 May 2011 16:38:37 +0000 (16:38 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Tue, 17 May 2011 16:38:37 +0000 (16:38 +0000)
The greedy register allocator has live range splitting and register class
inflation, so it can actually fully undo this join, including restoring the
original register classes.

We still don't want to do this for long live ranges, mostly because of the high
register pressure of there are many constrained live ranges overlapping.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131466 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SimpleRegisterCoalescing.cpp

index cebf4c9f4a5a00cde61746da5ad182eb06e23d52..1a2151fecf29e2d35f78be9b960388e7d29ee53a 100644 (file)
@@ -987,8 +987,14 @@ SimpleRegisterCoalescing::isWinToJoinCrossClass(unsigned SrcReg,
   LiveInterval &DstInt = li_->getInterval(DstReg);
   unsigned SrcSize = li_->getApproximateInstructionCount(SrcInt);
   unsigned DstSize = li_->getApproximateInstructionCount(DstInt);
-  if (SrcSize <= NewRCCount && DstSize <= NewRCCount)
+
+  // Coalesce aggressively if the intervals are small compared to the number of
+  // registers in the new class. The number 4 is fairly arbitrary, chosen to be
+  // less aggressive than the 8 used for the whole function size.
+  const unsigned ThresSize = 4 * NewRCCount;
+  if (SrcSize <= ThresSize && DstSize <= ThresSize)
     return true;
+
   // Estimate *register use density*. If it doubles or more, abort.
   unsigned SrcUses = std::distance(mri_->use_nodbg_begin(SrcReg),
                                    mri_->use_nodbg_end());
@@ -996,12 +1002,12 @@ SimpleRegisterCoalescing::isWinToJoinCrossClass(unsigned SrcReg,
                                    mri_->use_nodbg_end());
   unsigned NewUses = SrcUses + DstUses;
   unsigned NewSize = SrcSize + DstSize;
-  if (SrcRC != NewRC && SrcSize > NewRCCount) {
+  if (SrcRC != NewRC && SrcSize > ThresSize) {
     unsigned SrcRCCount = allocatableRCRegs_[SrcRC].count();
     if (NewUses*SrcSize*SrcRCCount > 2*SrcUses*NewSize*NewRCCount)
       return false;
   }
-  if (DstRC != NewRC && DstSize > NewRCCount) {
+  if (DstRC != NewRC && DstSize > ThresSize) {
     unsigned DstRCCount = allocatableRCRegs_[DstRC].count();
     if (NewUses*DstSize*DstRCCount > 2*DstUses*NewSize*NewRCCount)
       return false;