[llvm-commits] [regalloc_linearscan] CVS: llvm/lib/CodeGen/RegAllocLinearScan.cpp

Alkis Evlogimenos alkis at cs.uiuc.edu
Sat Nov 15 12:34:02 PST 2003


Changes in directory llvm/lib/CodeGen:

RegAllocLinearScan.cpp updated: 1.1.2.12 -> 1.1.2.13

---
Log message:

Make register allocation more aggressive. As a result two-addr
instructions end up preventing a copy (a = b op c -> a = b, a = a op c
in the general case; we avoid a = b if this is b's last use).

When spilled defined operands are used do not load them if this is not
a use (no need to insert extra load if we are redefining the value).


---
Diffs of the changes:  (+88 -74)

Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp
diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.12 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.13
--- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.1.2.12	Thu Nov 13 03:49:50 2003
+++ llvm/lib/CodeGen/RegAllocLinearScan.cpp	Sat Nov 15 12:33:33 2003
@@ -222,10 +222,6 @@
                                  inactive_.end()));
             DEBUG(printVirt2PhysMap());
 
-            // process the active intervals (this will potentially
-            // expire intervals and hence free physical registers)
-            processActiveIntervals(curIndex);
-
             // FIXME: holes are completely ignored for now
             // processInactiveIntervals(curIndex);
 
@@ -238,20 +234,6 @@
                 reservePhysReg(physReg);
             }
 
-            // loop over operands and spill all already defined
-            // physical registers
-            DEBUG(std::cerr << "\t\tprocessing already allocated physical "
-                  "registers:\n");
-            for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
-                 i != e; ++i) {
-                MachineOperand& op = (*currentInstr_)->getOperand(i);
-                if (op.isPhysicalRegister() &&
-                    (op.opIsDefOnly() || op.opIsDefAndUse())) {
-                    unsigned physReg = op.getAllocatedRegNum();
-                    reservePhysReg(physReg);
-                }
-            }
-
             // assign physical registers to used operands
             DEBUG(std::cerr << "\t\tprocessing used operands:\n");
             for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
@@ -276,9 +258,57 @@
                 }
             }
 
+            // loop over killed physical registers and clear them
+            DEBUG(std::cerr << "\t\tprocessing killed physical registers:\n");
+            for (LiveVariables::killed_iterator
+                     ki = lv_->killed_begin(*currentInstr_),
+                     ke = lv_->killed_end(*currentInstr_);
+                 ki != ke; ++ki) {
+                unsigned reg = ki->second;
+                if (reg < MRegisterInfo::FirstVirtualRegister) {
+                    clearReservedPhysReg(reg);
+                }
+            }
+
+            // loop over dead physical registers and clear them
+            DEBUG(std::cerr << "\t\tprocessing dead physical registers:\n");
+            for (LiveVariables::killed_iterator
+                     ki = lv_->dead_begin(*currentInstr_),
+                     ke = lv_->dead_end(*currentInstr_);
+                 ki != ke; ++ki) {
+                unsigned reg = ki->second;
+                if (reg < MRegisterInfo::FirstVirtualRegister) {
+                    clearReservedPhysReg(reg);
+                }
+            }
+
+
+            DEBUG(std::cerr << "\t\tclearing temporarily used operands:\n");
+            for (unsigned i = 0, e = tempUseOperands_.size(); i != e; ++i) {
+                clearVirtReg(tempUseOperands_[i]);
+            }
+
+            // this will expire intervals that are dead right after
+            // the execution of this instruction
+            processActiveIntervals(curIndex + 1);
+
             processInterval(curIndex);
 
-            // assign physical registers to used operands
+            // loop over operands and spill all already defined
+            // physical registers
+            DEBUG(std::cerr << "\t\tprocessing already allocated physical "
+                  "registers:\n");
+            for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
+                 i != e; ++i) {
+                MachineOperand& op = (*currentInstr_)->getOperand(i);
+                if (op.isPhysicalRegister() &&
+                    (op.opIsDefOnly() || op.opIsDefAndUse())) {
+                    unsigned physReg = op.getAllocatedRegNum();
+                    reservePhysReg(physReg);
+                }
+            }
+
+            // assign physical registers to not allocated defined operands
             DEBUG(std::cerr << "\t\tprocessing not allocated defined "
                   "operands:\n");
             for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
@@ -297,7 +327,14 @@
                             physReg = getFreePhysReg(virtReg);
                         }
                         assert(physReg && "no available physical register?!");
-                        loadVirt2PhysReg(virtReg, physReg);
+                        // load from stack only if we are going to use the value
+                        if (op.opIsDefAndUse()) {
+                            loadVirt2PhysReg(virtReg, physReg);
+                        }
+                        // otherwise just assign the mapping
+                        else {
+                            allocateVirt2PhysReg(virtReg, physReg);
+                        }
                         tempDefOperands_.push_back(virtReg);
                     }
                     (*currentInstr_)->SetMachineOperandReg(i, v2pMap_[virtReg]);
@@ -321,35 +358,36 @@
                 }
             }
 
-            // loop over killed physical registers and clear them
-            DEBUG(std::cerr << "\t\tprocessing killed physical registers:\n");
-            for (LiveVariables::killed_iterator
-                     ki = lv_->killed_begin(*currentInstr_),
-                     ke = lv_->killed_end(*currentInstr_);
-                 ki != ke; ++ki) {
-                unsigned reg = ki->second;
-                if (reg < MRegisterInfo::FirstVirtualRegister) {
-                    clearReservedPhysReg(reg);
-                }
-            }
-
-            // loop over dead physical registers and clear them
-            DEBUG(std::cerr << "\t\tprocessing dead physical registers:\n");
-            for (LiveVariables::killed_iterator
-                     ki = lv_->dead_begin(*currentInstr_),
-                     ke = lv_->dead_end(*currentInstr_);
-                 ki != ke; ++ki) {
-                unsigned reg = ki->second;
-                if (reg < MRegisterInfo::FirstVirtualRegister) {
-                    clearReservedPhysReg(reg);
-                }
+            // if the instructions is a two address instruction:
+            //
+            //"a = b + c" but a and b must be the same register,
+            //insert "a = b" before it and make the original
+            //instruction "a = a + c")
+
+            if (tm_->getInstrInfo().isTwoAddrInstr(
+                    (*currentInstr_)->getOpcode())) {
+                assert((*currentInstr_)->getOperand(1).isRegister() &&
+                       (*currentInstr_)->getOperand(1).getAllocatedRegNum() &&
+                       (*currentInstr_)->getOperand(1).opIsUse() &&
+                       "Two address instruction invalid");
+
+                unsigned regA =
+                    (*currentInstr_)->getOperand(0).getAllocatedRegNum();
+                unsigned regB =
+                    (*currentInstr_)->getOperand(1).getAllocatedRegNum();
+                const TargetRegisterClass* rc = mri_->getRegClass(regA);
+
+                instrAdded_ += mri_->copyRegToReg(*currentMbb_,
+                                                  currentInstr_,
+                                                  regA,
+                                                  regB,
+                                                  rc);
+                tempUseOperands_.erase(remove(tempUseOperands_.begin(),
+                                              tempUseOperands_.end(),
+                                              regB),
+                                       tempUseOperands_.end());
+                (*currentInstr_)->SetMachineOperandReg(1, regA);
             }
-
-            DEBUG(std::cerr << "\t\tclearing temporarily used operands:\n");
-            for (unsigned i = 0, e = tempUseOperands_.size(); i != e; ++i) {
-                clearVirtReg(tempUseOperands_[i]);
-            }
-
             DEBUG(std::cerr << "\t\tspilling temporarily defined operands:\n");
             for (unsigned i = 0, e = tempDefOperands_.size(); i != e; ++i) {
                 spillVirtReg(tempDefOperands_[i]);
@@ -379,31 +417,7 @@
         currentInterval_->start() == curIndex) {
         DEBUG(std::cerr << "\t\tprocessing current interval:\n");
         unsigned virtReg = currentInterval_->reg;
-        unsigned physReg = (unsigned) -1;
-        if (tm_->getInstrInfo().isTwoAddrInstr((*currentInstr_)->getOpcode())) {
-            assert((*currentInstr_)->getOperand(1).isRegister() &&
-                   (*currentInstr_)->getOperand(1).getAllocatedRegNum() &&
-                   (*currentInstr_)->getOperand(1).opIsUse() &&
-                   "Two address instruction invalid");
-                               
-            physReg = (*currentInstr_)->getOperand(1).getAllocatedRegNum();
-            // remove interval from active
-            for (IntervalPtrs::iterator i = active_.begin(), e = active_.end();
-                 i != e; ++i) {
-                if ((*i)->reg == p2vMap_[physReg]) {
-                    active_.erase(i);
-                    break;
-                }
-            }
-            tempUseOperands_.erase(remove(tempUseOperands_.begin(),
-                                           tempUseOperands_.end(),
-                                           p2vMap_[physReg]),
-                                    tempUseOperands_.end());
-            spillVirtReg(p2vMap_[physReg]);
-        }
-        else {
-            physReg = getFreePhysReg(virtReg);
-        }
+        unsigned physReg = getFreePhysReg(virtReg);
 
         if (!physReg) {
             spillInterval();
@@ -454,7 +468,7 @@
 //             // remove from inactive
 //             i = inactive_.erase(i);
 //         }
-//         // move re-activated intervals in active list 
+//         // move re-activated intervals in active list
 //         else if ((*i)->overlaps(curIndex)) {
 //             DEBUG(std::cerr << "\t\t\tinterval " << **i << " active\n");
 //             markReg(virtReg);





More information about the llvm-commits mailing list