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

Alkis Evlogimenos alkis at cs.uiuc.edu
Sun Oct 26 20:39:03 PST 2003


Changes in directory llvm/lib/CodeGen:

LiveIntervals.cpp updated: 1.1.2.3 -> 1.1.2.4

---
Log message:

Reimplement LiveIntervals. Apparently the previous version was not
working properly due to some false assumptions. This version works as
expected and it also supports intervals with holes. One subtle
difference in this implementation is that a live range of [i, j] means
that the variable is live between i and j - 1 (that is it is already
dead in j). In the previous implementation a live range [i, j] meant
that the variable is live between i and j (it dies after the execution
of instruction j).


---
Diffs of the changes:  (+77 -108)

Index: llvm/lib/CodeGen/LiveIntervals.cpp
diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.1.2.3 llvm/lib/CodeGen/LiveIntervals.cpp:1.1.2.4
--- llvm/lib/CodeGen/LiveIntervals.cpp:1.1.2.3	Sat Oct 25 18:31:53 2003
+++ llvm/lib/CodeGen/LiveIntervals.cpp	Sun Oct 26 20:37:58 2003
@@ -1,10 +1,10 @@
 //===-- LiveIntervals.cpp - Live Interval Analysis ------------------------===//
-// 
+//
 //                     The LLVM Compiler Infrastructure
 //
 // This file was developed by the LLVM research group and is distributed under
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+//
 //===----------------------------------------------------------------------===//
 //
 // This file implements the LiveInterval analysis pass which is used
@@ -58,29 +58,22 @@
     _mri = _tm->getRegisterInfo();
     _lv = &getAnalysis<LiveVariables>();
 
-    // create a mapping from BasicBlock* to MachineBasicBlock*
-    typedef std::map<const BasicBlock*, MachineBasicBlock*> BB2MBBMap;
-    BB2MBBMap bb2mbbMap;
+    // number MachineInstrs
+    unsigned miIndex = 0;
     for (MachineFunction::iterator mbb = _mf->begin(), mbbEnd = _mf->end();
          mbb != mbbEnd; ++mbb) {
-        bool inserted = bb2mbbMap.insert(
-            std::make_pair(mbb->getBasicBlock(), &*mbb)).second;
-        assert(inserted && "multiple BasicBlock -> MachineBasicBlock mappings");
-    }
+        const std::pair<MachineBasicBlock*, unsigned>& entry =
+            _lv->getMachineBasicBlockInfo(&*mbb);
+        bool inserted = _i2mbbMap.insert(std::make_pair(entry.second,
+                                                        entry.first)).second;
+        assert(inserted && "multiple index -> MachineBasicBlock");
 
-    // add MachineBasicBlocks in depth first order
-    _mbbOrder.clear();
-    _mbbOrder.reserve(bb2mbbMap.size());
-    const BasicBlock* entry = _mf->getFunction()->begin();
-    for (df_iterator<const BasicBlock*>
-             bb = df_begin(entry), bbEnd = df_end(entry);
-         bb != bbEnd; ++bb) {
-        MachineBasicBlock* mbb = bb2mbbMap.find(*bb)->second;
-        _mbbOrder.push_back(mbb);
-        assert(mbb && "MachineBasicBlock for BasicBlock cannot be null");
+        for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end();
+             mi != miEnd; ++mi) {
+            inserted = _mi2iMap.insert(std::make_pair(*mi, miIndex++)).second;
+            assert(inserted && "multiple MachineInstr -> index mappings");
+        }
     }
-    
-    _i2iMap.clear();
 
     computeIntervals();
 
@@ -91,51 +84,70 @@
     void printRegName(const MRegisterInfo* mri, int reg) {
         DEBUG(
             if (reg < MRegisterInfo::FirstVirtualRegister)
-                std::cerr << mri->getName(reg);
+            std::cerr << mri->getName(reg);
             else
             std::cerr << '%' << reg);
     }
 }
 
-void LiveIntervals::handleRegisterDef(Reg2IntervalMap& r2iMap,
-                                      unsigned i,
+void LiveIntervals::handleRegisterDef(MachineBasicBlock* mbb,
+                                      MachineInstr* instr,
                                       unsigned reg)
 {
-    DEBUG(std::cerr << "\t\t\t\tregister: "; printRegName(_mri, reg));
+    DEBUG(std::cerr << "\t\t\tregister: "; printRegName(_mri, reg));
 
-    if (reg >= MRegisterInfo::FirstVirtualRegister &&
-        r2iMap.find(reg) != r2iMap.end()) {
-        DEBUG(std::cerr << "multiple definitions of virtual register at "
-              "instruction[" << i << "]. previous definition at "
-              "instruction[" << r2iMap.find(reg)->second <<"]\n");
-        // we ignore this because the multiple definitions are
-        // generated by the PHIElimination pass which preservers
-        // LiveVariables
-        return;
-    }
-    // initialize intervals to [index, inf] - be conservative!
-    _intervals.push_back(
-        Interval(reg, i, std::numeric_limits<unsigned>::max()));
-    // update last live interval for this register
-    r2iMap[reg] = _intervals.size() - 1;
+    unsigned start = getInstructionIndex(instr);
 
-    DEBUG(std::cerr << " -> ADD interval " << _intervals.back() << '\n');
-}
+    LiveVariables::VarInfo& vi = _lv->getVarInfo(reg);
 
-void LiveIntervals::handleRegisterKill(Reg2IntervalMap& r2iMap,
-                                       unsigned i,
-                                       unsigned reg)
-{
-    DEBUG(std::cerr << "\t\t\t\tregister: "; printRegName(_mri, reg));
+    Reg2IntervalMap::iterator r2iit = _r2iMap.find(reg);
+    if (r2iit != _r2iMap.end()) {
+        unsigned ii = r2iit->second;
+        Interval& interval = _intervals[ii];
+        unsigned end = getInstructionIndex(mbb->back()) + 1;
+        interval.addRange(start, end);
+        DEBUG(std::cerr << " -> " << interval << '\n');
+    }
+    else {
+        // add new interval
+        _intervals.push_back(Interval(reg));
+        Interval& interval = _intervals.back();
+        // update interval index for this register
+        _r2iMap[reg] = _intervals.size() - 1;
+
+        unsigned index = _lv->getMachineBasicBlockInfo(mbb).second;
+        if (index < vi.AliveBlocks.size() && vi.AliveBlocks[index]) {
+            unsigned end = getInstructionIndex(mbb->back()) + 1;
+            interval.addRange(start, end);
+        }
 
-    Reg2IntervalMap::iterator ri = r2iMap.find(reg);
-    assert(ri != r2iMap.end()
-           && "did not find live interval for killed register");
-    Interval& interval = _intervals[ri->second];
-    // if this is a later kill remark the end here - be conservative!
-    interval.end = i;
+        for (Index2MbbMap::iterator
+                 it = _i2mbbMap.begin(), itEnd = _i2mbbMap.end();
+             it != itEnd; ++it) {
+            unsigned mbbIndex = it->first;
+            MachineBasicBlock* mbb2 = it->second;
+            if (mbbIndex < vi.AliveBlocks.size() &&
+                vi.AliveBlocks[mbbIndex] && mbb != mbb2) {
+                interval.addRange(getInstructionIndex(mbb2->front()),
+                                  getInstructionIndex(mbb2->back()) + 1);
+            }
+        }
 
-    DEBUG(std::cerr << " -> END interval " << interval << '\n');
+        for (int i = 0, e = vi.Kills.size(); i != e; ++i) {
+            MachineBasicBlock* killerBlock = vi.Kills[i].first;
+            MachineInstr* killerInstr = vi.Kills[i].second;
+            interval.addRange(getInstructionIndex(killerBlock->front()),
+                              getInstructionIndex(killerInstr) + 1);
+        }
+        DEBUG(std::cerr << " -> " << interval << '\n');
+    }
+}
+
+unsigned LiveIntervals::getInstructionIndex(MachineInstr* instr)
+{
+    assert(_mi2iMap.find(instr) != _mi2iMap.end() &&
+           "instruction not assigned a number");
+    return _mi2iMap.find(instr)->second;
 }
 
 /// computeIntervals - computes the live intervals for virtual
@@ -146,77 +158,34 @@
 {
     DEBUG(std::cerr << "computing live intervals:\n");
 
-    // register -> last live interval index
-    Reg2IntervalMap r2iMap;
-
-    unsigned index = 0;
-    for (MBBPtrs::iterator it = _mbbOrder.begin(), itEnd = _mbbOrder.end();
+    for (Index2MbbMap::iterator it = _i2mbbMap.begin(), itEnd = _i2mbbMap.end();
          it != itEnd; ++it) {
-        MachineBasicBlock* mbb = *it;
+        MachineBasicBlock* mbb = it->second;
         DEBUG(std::cerr << "machine basic block: "
-                        << mbb->getBasicBlock()->getName() << "\n");
+              << mbb->getBasicBlock()->getName() << "\n");
         for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end();
-             mi != miEnd; ++index, ++mi) {
+             mi != miEnd; ++mi) {
             MachineInstr* instr = *mi;
             const TargetInstrDescriptor& tid =
                 _tm->getInstrInfo().get(instr->getOpcode());
-            _i2iMap.insert(std::make_pair(instr, index));
-            DEBUG(std::cerr << "\t\tinstruction[" << index << "]: "
-                            << *instr << '\n');
-
-            DEBUG(std::cerr << "\t\t\thandling implicit definitions:\n");
-            for (const unsigned* id = tid.ImplicitDefs; *id; ++id) {
-                unsigned reg = *id;
-                handleRegisterDef(r2iMap, index, reg);
-            }
-
-            DEBUG(std::cerr << "\t\t\thandling kills:\n");
-            for (LiveVariables::killed_iterator
-                     ki = _lv->killed_begin(instr),
-                     kiEnd = _lv->killed_end(instr);
-                 ki != kiEnd; ++ki) {
-                unsigned reg = ki->second;
-                handleRegisterKill(r2iMap, index, reg);
-            }
+            DEBUG(std::cerr << "\t\tinstruction["
+                  << _mi2iMap.find(instr)->second << "]: "
+                  << *instr << '\n');
 
-            DEBUG(std::cerr << "\t\t\thandling definitions:\n");
             for (int i = instr->getNumOperands() - 1; i >= 0; --i) {
                 MachineOperand& mop = instr->getOperand(i);
 
-                if (!mop.isRegister())
+                if (!mop.isVirtualRegister())
                     continue;
 
-                // mark start and end points
-                unsigned reg = mop.getAllocatedRegNum();
                 if (mop.opIsDefOnly() || mop.opIsDefAndUse()) {
-                    handleRegisterDef(r2iMap, index, reg);
-                }
-            }
-        }
+                    unsigned reg = mop.getAllocatedRegNum();
 
-        // kill all physical registers in the end of each basic block
-        for (Intervals::iterator it =
-                 _intervals.begin(), itEnd = _intervals.end();
-             it != itEnd; ++it) {
-            unsigned reg = it->reg;
-            if (reg < MRegisterInfo::FirstVirtualRegister) {
-                handleRegisterKill(r2iMap, index, reg);
+                    handleRegisterDef(mbb, instr, reg);
+                }
             }
         }
     }
-
-    // mark the real end of each interval instead of
-    // std::numeric_limits<unsigned>::max()
-    for (Intervals::iterator it = _intervals.begin(), itEnd = _intervals.end();
-         it != itEnd; ++it) {
-        if (it->end == std::numeric_limits<unsigned>::max()) {
-            it->end = index;
-        }
-    }
-
-    // the live intervals should be sorted in increasing start point
-//     assert(std::is_sorted(_intervals.begin(), _intervals.end(),
-//                           StartPointComp()));
 
     DEBUG(std::copy(_intervals.begin(), _intervals.end(),
                     std::ostream_iterator<Interval>(std::cerr, "\n")));





More information about the llvm-commits mailing list