[llvm-commits] [llvm] r67574 - in /llvm/trunk: lib/CodeGen/RegAllocLinearScan.cpp test/CodeGen/X86/2009-03-23-LinearScanBug.ll

Evan Cheng evan.cheng at apple.com
Mon Mar 23 15:57:19 PDT 2009


Author: evancheng
Date: Mon Mar 23 17:57:19 2009
New Revision: 67574

URL: http://llvm.org/viewvc/llvm-project?rev=67574&view=rev
Log:
Fix a bug in spill weight computation. If the alias is a super-register, and the super-register is in the register class we are trying to allocate. Then add the weight to all sub-registers of the super-register even if they are not aliases.                                                                                                  
e.g. allocating for GR32, bh is not used, updating bl spill weight.                                                                                                        
     bl should get the same spill weight otherwise it will be choosen                                                                                              
     as a spill candidate since spilling bh doesn't make ebx available.
This fix PR2866.

Added:
    llvm/trunk/test/CodeGen/X86/2009-03-23-LinearScanBug.ll
Modified:
    llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp

Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp?rev=67574&r1=67573&r2=67574&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Mon Mar 23 17:57:19 2009
@@ -155,6 +155,10 @@
     /// is available, or spill.
     void assignRegOrStackSlotAtInterval(LiveInterval* cur);
 
+    void updateSpillWeights(std::vector<float> &Weights,
+                            unsigned reg, float weight,
+                            const TargetRegisterClass *RC);
+
     /// findIntervalsToSpill - Determine the intervals to spill for the
     /// specified interval. It's passed the physical registers whose spill
     /// weight is the lowest among all the registers whose live intervals
@@ -515,12 +519,35 @@
 
 /// updateSpillWeights - updates the spill weights of the specifed physical
 /// register and its weight.
-static void updateSpillWeights(std::vector<float> &Weights,
-                               unsigned reg, float weight,
-                               const TargetRegisterInfo *TRI) {
+void RALinScan::updateSpillWeights(std::vector<float> &Weights,
+                                   unsigned reg, float weight,
+                                   const TargetRegisterClass *RC) {
+  SmallSet<unsigned, 4> Processed;
+  SmallSet<unsigned, 4> SuperAdded;
+  SmallVector<unsigned, 4> Supers;
   Weights[reg] += weight;
-  for (const unsigned* as = TRI->getAliasSet(reg); *as; ++as)
+  Processed.insert(reg);
+  for (const unsigned* as = tri_->getAliasSet(reg); *as; ++as) {
     Weights[*as] += weight;
+    Processed.insert(*as);
+    if (tri_->isSubRegister(*as, reg) &&
+        SuperAdded.insert(*as) &&
+        RC->contains(*as)) {
+      Supers.push_back(*as);
+    }
+  }
+
+  // If the alias is a super-register, and the super-register is in the
+  // register class we are trying to allocate. Then add the weight to all
+  // sub-registers of the super-register even if they are not aliases.
+  // e.g. allocating for GR32, bh is not used, updating bl spill weight.
+  //      bl should get the same spill weight otherwise it will be choosen
+  //      as a spill candidate since spilling bh doesn't make ebx available.
+  for (unsigned i = 0, e = Supers.size(); i != e; ++i) {
+      for (const unsigned *sr = tri_->getSubRegisters(Supers[i]); *sr; ++sr)
+        if (!Processed.count(*sr))
+          Weights[*sr] += weight;
+  }
 }
 
 static
@@ -817,7 +844,7 @@
   std::vector<float> SpillWeights(tri_->getNumRegs(), 0.0f);
   for (std::vector<std::pair<unsigned, float> >::iterator
        I = SpillWeightsToAdd.begin(), E = SpillWeightsToAdd.end(); I != E; ++I)
-    updateSpillWeights(SpillWeights, I->first, I->second, tri_);
+    updateSpillWeights(SpillWeights, I->first, I->second, RC);
   
   // for each interval in active, update spill weights.
   for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
@@ -826,14 +853,14 @@
     assert(TargetRegisterInfo::isVirtualRegister(reg) &&
            "Can only allocate virtual registers!");
     reg = vrm_->getPhys(reg);
-    updateSpillWeights(SpillWeights, reg, i->first->weight, tri_);
+    updateSpillWeights(SpillWeights, reg, i->first->weight, RC);
   }
  
   DOUT << "\tassigning stack slot at interval "<< *cur << ":\n";
 
   // Find a register to spill.
   float minWeight = HUGE_VALF;
-  unsigned minReg = 0; /*cur->preference*/;  // Try the preferred register first.
+  unsigned minReg = 0; /*cur->preference*/;  // Try the pref register first.
 
   bool Found = false;
   std::vector<std::pair<unsigned,float> > RegsWeights;

Added: llvm/trunk/test/CodeGen/X86/2009-03-23-LinearScanBug.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-03-23-LinearScanBug.ll?rev=67574&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/2009-03-23-LinearScanBug.ll (added)
+++ llvm/trunk/test/CodeGen/X86/2009-03-23-LinearScanBug.ll Mon Mar 23 17:57:19 2009
@@ -0,0 +1,23 @@
+; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin -fast
+
+define fastcc void @optimize_bit_field() nounwind {
+bb4:
+        %a = load i32* null             ; <i32> [#uses=1]
+        %s = load i32* getelementptr (i32* null, i32 1)         ; <i32> [#uses=1]
+        %z = load i32* getelementptr (i32* null, i32 2)         ; <i32> [#uses=1]
+        %r = bitcast i32 0 to i32          ; <i32> [#uses=1]
+        %q = trunc i32 %z to i8            ; <i8> [#uses=1]
+        %b = icmp eq i8 0, %q              ; <i1> [#uses=1]
+        br i1 %b, label %bb73, label %bb72
+
+bb72:      ; preds = %bb4
+        %f = tail call fastcc i32 @gen_lowpart(i32 %r, i32 %a) nounwind              ; <i32> [#uses=1]
+        br label %bb73
+
+bb73:         ; preds = %bb72, %bb4
+        %y = phi i32 [ %f, %bb72 ], [ %s, %bb4 ]          ; <i32> [#uses=1]
+        store i32 %y, i32* getelementptr (i32* null, i32 3)
+        unreachable
+}
+
+declare fastcc i32 @gen_lowpart(i32, i32) nounwind





More information about the llvm-commits mailing list