Add Register mask support to RABasic.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 8 Feb 2012 18:54:35 +0000 (18:54 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 8 Feb 2012 18:54:35 +0000 (18:54 +0000)
When a virtual register is live across a call, limit the search space to
call-preserved registers.

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

lib/CodeGen/RegAllocBasic.cpp

index 570a56e2715d91049e4357f79d3e29a299068521..a6dab6f3ce6bfed88d928d29797bd1317c240801 100644 (file)
@@ -72,6 +72,11 @@ class RABasic : public MachineFunctionPass, public RegAllocBase
   std::auto_ptr<Spiller> SpillerInstance;
   std::priority_queue<LiveInterval*, std::vector<LiveInterval*>,
                       CompSpillWeight> Queue;
+
+  // Scratch space.  Allocated here to avoid repeated malloc calls in
+  // selectOrSplit().
+  BitVector UsableRegs;
+
 public:
   RABasic();
 
@@ -234,6 +239,10 @@ bool RABasic::spillInterferences(LiveInterval &VirtReg, unsigned PhysReg,
 // selectOrSplit().
 unsigned RABasic::selectOrSplit(LiveInterval &VirtReg,
                                 SmallVectorImpl<LiveInterval*> &SplitVRegs) {
+  // Check for register mask interference.  When live ranges cross calls, the
+  // set of usable registers is reduced to the callee-saved ones.
+  bool CrossRegMasks = LIS->checkRegMaskInterference(VirtReg, UsableRegs);
+
   // Populate a list of physical register spill candidates.
   SmallVector<unsigned, 8> PhysRegSpillCands;
 
@@ -244,6 +253,11 @@ unsigned RABasic::selectOrSplit(LiveInterval &VirtReg,
        ++I) {
     unsigned PhysReg = *I;
 
+    // If PhysReg is clobbered by a register mask, it isn't useful for
+    // allocation or spilling.
+    if (CrossRegMasks && !UsableRegs.test(PhysReg))
+      continue;
+
     // Check interference and as a side effect, intialize queries for this
     // VirtReg and its aliases.
     unsigned interfReg = checkPhysRegInterference(VirtReg, PhysReg);