summaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegAllocGreedy.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-02-11 00:42:18 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-02-11 00:42:18 +0000
commita6d513f47467b90344a74624d4fb77673942e3ce (patch)
treef74c02f87f5e61f98bb1d2933fa3cb56095b42e5 /lib/CodeGen/RegAllocGreedy.cpp
parentfd3d4cf0ef5237bd517559703bea2310f1841a5d (diff)
downloadllvm-a6d513f47467b90344a74624d4fb77673942e3ce.tar.gz
llvm-a6d513f47467b90344a74624d4fb77673942e3ce.tar.bz2
llvm-a6d513f47467b90344a74624d4fb77673942e3ce.tar.xz
Handle register masks in local live range splitting.
Again the goal is to produce identical assembly with register mask operands enabled. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150287 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegAllocGreedy.cpp')
-rw-r--r--lib/CodeGen/RegAllocGreedy.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp
index 0ac31a5792..874dca6f56 100644
--- a/lib/CodeGen/RegAllocGreedy.cpp
+++ b/lib/CodeGen/RegAllocGreedy.cpp
@@ -1352,6 +1352,26 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order,
dbgs() << '\n';
});
+ // If VirtReg is live across any register mask operands, compute a list of
+ // gaps with register masks.
+ SmallVector<unsigned, 8> RegMaskGaps;
+ if (!UsableRegs.empty()) {
+ // Get regmask slots for the whole block.
+ ArrayRef<SlotIndex> RMS = LIS->getRegMaskSlotsInBlock(BI.MBB->getNumber());
+ // Constrain to VirtReg's live range.
+ unsigned ri = std::lower_bound(RMS.begin(), RMS.end(), Uses.front())
+ - RMS.begin();
+ unsigned re = RMS.size();
+ for (unsigned i = 0; i != NumGaps && ri != re; ++i) {
+ assert(Uses[i] <= RMS[ri]);
+ if (Uses[i+1] <= RMS[ri])
+ continue;
+ RegMaskGaps.push_back(i);
+ do ++ri;
+ while (ri != re && RMS[ri] < Uses[i+1]);
+ }
+ }
+
// Since we allow local split results to be split again, there is a risk of
// creating infinite loops. It is tempting to require that the new live
// ranges have less instructions than the original. That would guarantee
@@ -1386,6 +1406,11 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order,
// order to make use of PhysReg between UseSlots[i] and UseSlots[i+1].
calcGapWeights(PhysReg, GapWeight);
+ // Remove any gaps with regmask clobbers.
+ if (clobberedByRegMask(PhysReg))
+ for (unsigned i = 0, e = RegMaskGaps.size(); i != e; ++i)
+ GapWeight[RegMaskGaps[i]] = HUGE_VALF;
+
// Try to find the best sequence of gaps to close.
// The new spill weight must be larger than any gap interference.