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

Alkis Evlogimenos alkis at cs.uiuc.edu
Thu Dec 18 07:16:01 PST 2003


Changes in directory llvm/lib/CodeGen:

RegAllocLinearScan.cpp updated: 1.12 -> 1.13
LiveIntervals.cpp updated: 1.10 -> 1.11

---
Log message:

Modify linear scan register allocator to use the two-address
instruction pass. This also fixes all remaining bugs for this new
allocator to pass all tests under test/Programs.


---
Diffs of the changes:  (+39 -76)

Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp
diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.12 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.13
--- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.12	Thu Dec 18 07:12:18 2003
+++ llvm/lib/CodeGen/RegAllocLinearScan.cpp	Thu Dec 18 07:15:02 2003
@@ -84,6 +84,11 @@
         /// runOnMachineFunction - register allocate the whole function
         bool runOnMachineFunction(MachineFunction&);
 
+        /// verifyIntervals - verify that we have no inconsistencies
+        /// in the register assignments we have in active and inactive
+        /// lists
+        bool verifyIntervals();
+
         /// processActiveIntervals - expire old intervals and move
         /// non-overlapping ones to the incative list
         void processActiveIntervals(Intervals::const_iterator cur);
@@ -245,6 +250,8 @@
 
         DEBUG(printIntervals("\tactive", active_.begin(), active_.end()));
         DEBUG(printIntervals("\tinactive", inactive_.begin(), inactive_.end()));
+        assert(verifyIntervals());
+
         processActiveIntervals(i);
         // processInactiveIntervals(i);
 
@@ -321,7 +328,7 @@
             for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
                  i != e; ++i) {
                 MachineOperand& op = (*currentInstr_)->getOperand(i);
-                if (op.isVirtualRegister() && op.isUse()) {
+                if (op.isVirtualRegister() && op.isUse() && !op.isDef()) {
                     unsigned virtReg = op.getAllocatedRegNum();
                     unsigned physReg = v2pMap_[virtReg];
                     if (!physReg) {
@@ -361,81 +368,6 @@
                 }
             }
 
-
-            // if the instruction is a two address instruction and the
-            // source operands are not identical we need to insert
-            // extra instructions.
-
-            unsigned opcode = (*currentInstr_)->getOpcode();
-            if (tm_->getInstrInfo().isTwoAddrInstr(opcode) &&
-                (*currentInstr_)->getOperand(0).getAllocatedRegNum() !=
-                (*currentInstr_)->getOperand(1).getAllocatedRegNum()) {
-                assert((*currentInstr_)->getOperand(1).isRegister() &&
-                       (*currentInstr_)->getOperand(1).getAllocatedRegNum() &&
-                       (*currentInstr_)->getOperand(1).isUse() &&
-                       "Two address instruction invalid");
-
-                unsigned regA =
-                    (*currentInstr_)->getOperand(0).getAllocatedRegNum();
-                unsigned regB =
-                    (*currentInstr_)->getOperand(1).getAllocatedRegNum();
-                unsigned regC =
-                    ((*currentInstr_)->getNumOperands() > 2 &&
-                     (*currentInstr_)->getOperand(2).isRegister()) ?
-                    (*currentInstr_)->getOperand(2).getAllocatedRegNum() :
-                    0;
-
-                const TargetRegisterClass* rc = mri_->getRegClass(regA);
-
-                // special case: "a = b op a". If b is a temporary
-                // reserved register rewrite as: "b = b op a; a = b"
-                // otherwise use a temporary reserved register t and
-                // rewrite as: "t = b; t = t op a; a = t"
-                if (regC && regA == regC) {
-                    // b is a temp reserved register
-                    if (find(reserved_.begin(), reserved_.end(),
-                             regB) != reserved_.end()) {
-                        (*currentInstr_)->SetMachineOperandReg(0, regB);
-                        ++currentInstr_;
-                        instrAdded_ += mri_->copyRegToReg(*currentMbb_,
-                                                          currentInstr_,
-                                                          regA,
-                                                          regB,
-                                                          rc);
-                        --currentInstr_;
-                    }
-                    // b is just a normal register
-                    else {
-                        unsigned tempReg = getFreeTempPhysReg(rc);
-                        assert (tempReg &&
-                                "no free temp reserved physical register?");
-                        instrAdded_ += mri_->copyRegToReg(*currentMbb_,
-                                                          currentInstr_,
-                                                          tempReg,
-                                                          regB,
-                                                          rc);
-                        (*currentInstr_)->SetMachineOperandReg(0, tempReg);
-                        (*currentInstr_)->SetMachineOperandReg(1, tempReg);
-                        ++currentInstr_;
-                        instrAdded_ += mri_->copyRegToReg(*currentMbb_,
-                                                          currentInstr_,
-                                                          regA,
-                                                          tempReg,
-                                                          rc);
-                        --currentInstr_;
-                    }
-                }
-                // "a = b op c" gets rewritten to "a = b; a = a op c"
-                else {
-                    instrAdded_ += mri_->copyRegToReg(*currentMbb_,
-                                                      currentInstr_,
-                                                      regA,
-                                                      regB,
-                                                      rc);
-                    (*currentInstr_)->SetMachineOperandReg(1, regA);
-                }
-            }
-
             DEBUG(std::cerr << "\t\tspilling temporarily defined operands "
                   "of this instruction:\n");
             ++currentInstr_; // we want to insert after this instruction
@@ -452,6 +384,35 @@
         }
     }
 
+    return true;
+}
+
+bool RA::verifyIntervals()
+{
+    std::set<unsigned> assignedRegisters;
+    for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) {
+        if ((*i)->reg >= MRegisterInfo::FirstVirtualRegister) {
+            unsigned reg = v2pMap_.find((*i)->reg)->second;
+
+            bool inserted = assignedRegisters.insert(reg).second;
+            assert(inserted && "registers in active list conflict");
+        }
+    }
+
+    for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) {
+        unsigned reg = (*i)->reg;
+        if (reg >= MRegisterInfo::FirstVirtualRegister) {
+            reg = v2pMap_.find((*i)->reg)->second;
+        }
+
+        for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as) {
+            assert(assignedRegisters.find(*as) == assignedRegisters.end() &&
+                   "registers in active list alias each other");
+        }
+    }
+
+    // TODO: add checks between active and inactive and make sure we
+    // do not overlap anywhere
     return true;
 }
 


Index: llvm/lib/CodeGen/LiveIntervals.cpp
diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.10 llvm/lib/CodeGen/LiveIntervals.cpp:1.11
--- llvm/lib/CodeGen/LiveIntervals.cpp:1.10	Thu Dec 18 02:53:43 2003
+++ llvm/lib/CodeGen/LiveIntervals.cpp	Thu Dec 18 07:15:02 2003
@@ -24,6 +24,7 @@
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/SSARegMap.h"
+#include "llvm/CodeGen/TwoAddressInstructionPass.h"
 #include "llvm/Target/MRegisterInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetMachine.h"
@@ -49,6 +50,7 @@
     AU.addRequired<LiveVariables>();
     AU.addPreservedID(PHIEliminationID);
     AU.addRequiredID(PHIEliminationID);
+    AU.addRequired<TwoAddressInstructionPass>();
     MachineFunctionPass::getAnalysisUsage(AU);
 }
 





More information about the llvm-commits mailing list