Add a spiller option to llc. A simple spiller will come soon. When we get CFG in...
authorAlkis Evlogimenos <alkis@evlogimenos.com>
Mon, 1 Mar 2004 23:18:15 +0000 (23:18 +0000)
committerAlkis Evlogimenos <alkis@evlogimenos.com>
Mon, 1 Mar 2004 23:18:15 +0000 (23:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12062 91177308-0d34-0410-b5e6-96231b3b80d8

docs/CommandGuide/llc.html
lib/CodeGen/Passes.cpp
lib/CodeGen/RegAllocLinearScan.cpp
lib/CodeGen/VirtRegMap.cpp
lib/CodeGen/VirtRegMap.h

index 36710427642e745074a46fb772ac67cbf8207268..4583b11fc60b339b4852feb6d2a78e0e12b84c2c 100644 (file)
@@ -150,6 +150,19 @@ OPTIONS
 
                <di> local
                <dd>Local register allocator</dd>
+
+               <di> linearscan
+               <dd>Linear scan global register allocator (experimental)</dd>
+
+       <li>-spiller=&lt;sp&gt;
+       <br>
+        Specify the spiller to use for register allocators that support it.
+        Currently this option is used by the linear scan register
+        allocator. The default is <i>local</i>.
+        Valid spillers are:
+       <dl compact>
+               <di> local
+               <dd>Local spiller</dd>
        </dl>
        <p>
 
index bdcac4c6d12f9cb9fe9f63bc9fa8d1ce1639fae7..2fb6cb465c25764921b8ef89aadf7626ffa8f8e1 100644 (file)
@@ -26,7 +26,7 @@ namespace {
            cl::Prefix,
            cl::values(clEnumVal(simple,      "  simple register allocator"),
                       clEnumVal(local,       "  local register allocator"),
-                      clEnumVal(linearscan,  "  linear-scan global register allocator"),
+                      clEnumVal(linearscan,  "  linear scan register allocator (experimental)"),
                       0),
            cl::init(local));
 }
index d6c53cd0a72e4827a21967620684fe7972370e22..e92abe10bd31360b430d9ad6eba449a3d47bc160 100644 (file)
@@ -41,6 +41,7 @@ namespace {
 
         std::auto_ptr<PhysRegTracker> prt_;
         std::auto_ptr<VirtRegMap> vrm_;
+        std::auto_ptr<Spiller> spiller_;
 
         typedef std::vector<float> SpillWeights;
         SpillWeights spillWeights_;
@@ -147,12 +148,13 @@ bool RA::runOnMachineFunction(MachineFunction &fn) {
     li_ = &getAnalysis<LiveIntervals>();
     if (!prt_.get()) prt_.reset(new PhysRegTracker(*mri_));
     vrm_.reset(new VirtRegMap(*mf_));
+    if (!spiller_.get()) spiller_.reset(createSpiller());
 
     initIntervalSets(li_->getIntervals());
 
     linearScan();
 
-    eliminateVirtRegs(*mf_, *vrm_);
+    spiller_->runOnMachineFunction(*mf_, *vrm_);
 
     return true;
 }
index 1238a2cefbb43938beaf8dbfb3e8cb9c58df0b42..1187fc26f19862e7591084a45f67795b70aeebb9 100644 (file)
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetInstrInfo.h"
-#include "Support/Statistic.h"
+#include "Support/CommandLine.h"
 #include "Support/Debug.h"
 #include "Support/DenseMap.h"
+#include "Support/Statistic.h"
 #include "Support/STLExtras.h"
 #include <iostream>
 
@@ -35,6 +36,15 @@ namespace {
     Statistic<> numStores("spiller", "Number of stores added");
     Statistic<> numLoads ("spiller", "Number of loads added");
 
+    enum SpillerName { local };
+
+    cl::opt<SpillerName>
+    SpillerOpt("spiller",
+               cl::desc("Spiller to use: (default: local)"),
+               cl::Prefix,
+               cl::values(clEnumVal(local, "  local spiller"),
+                          0),
+               cl::init(local));
 }
 
 int VirtRegMap::assignVirt2StackSlot(unsigned virtReg)
@@ -88,41 +98,44 @@ std::ostream& llvm::operator<<(std::ostream& os, const VirtRegMap& vrm)
     return std::cerr << '\n';
 }
 
+Spiller::~Spiller()
+{
+
+}
+
 namespace {
 
-    class Spiller {
+    class LocalSpiller : public Spiller {
         typedef std::vector<unsigned> Phys2VirtMap;
         typedef std::vector<bool> PhysFlag;
         typedef DenseMap<MachineInstr*, VirtReg2IndexFunctor> Virt2MI;
 
-        MachineFunction& mf_;
-        const TargetMachine& tm_;
-        const TargetInstrInfo& tii_;
-        const MRegisterInfo& mri_;
-        const VirtRegMap& vrm_;
+        MachineFunction* mf_;
+        const TargetMachine* tm_;
+        const TargetInstrInfo* tii_;
+        const MRegisterInfo* mri_;
+        const VirtRegMap* vrm_;
         Phys2VirtMap p2vMap_;
         PhysFlag dirty_;
         Virt2MI lastDef_;
 
     public:
-        Spiller(MachineFunction& mf, const VirtRegMap& vrm)
-            : mf_(mf),
-              tm_(mf_.getTarget()),
-              tii_(tm_.getInstrInfo()),
-              mri_(*tm_.getRegisterInfo()),
-              vrm_(vrm),
-              p2vMap_(mri_.getNumRegs(), 0),
-              dirty_(mri_.getNumRegs(), false),
-              lastDef_() {
+        bool runOnMachineFunction(MachineFunction& mf, const VirtRegMap& vrm) {
+            mf_ = &mf;
+            tm_ = &mf_->getTarget();
+            tii_ = &tm_->getInstrInfo();
+            mri_ = tm_->getRegisterInfo();
+            vrm_ = &vrm;
+            p2vMap_.assign(mri_->getNumRegs(), 0);
+            dirty_.assign(mri_->getNumRegs(), false);
+
             DEBUG(std::cerr << "********** REWRITE MACHINE CODE **********\n");
             DEBUG(std::cerr << "********** Function: "
-                  << mf_.getFunction()->getName() << '\n');
-        }
+                  << mf_->getFunction()->getName() << '\n');
 
-        void eliminateVirtRegs() {
-            for (MachineFunction::iterator mbbi = mf_.begin(),
-                     mbbe = mf_.end(); mbbi != mbbe; ++mbbi) {
-                lastDef_.grow(mf_.getSSARegMap()->getLastVirtReg());
+            for (MachineFunction::iterator mbbi = mf_->begin(),
+                     mbbe = mf_->end(); mbbi != mbbe; ++mbbi) {
+                lastDef_.grow(mf_->getSSARegMap()->getLastVirtReg());
                 DEBUG(std::cerr << mbbi->getBasicBlock()->getName() << ":\n");
                 eliminateVirtRegsInMbb(*mbbi);
                 // clear map, dirty flag and last ref
@@ -130,6 +143,7 @@ namespace {
                 dirty_.assign(dirty_.size(), false);
                 lastDef_.clear();
             }
+            return true;
         }
 
     private:
@@ -137,21 +151,21 @@ namespace {
                                MachineBasicBlock::iterator mii,
                                unsigned physReg) {
             unsigned virtReg = p2vMap_[physReg];
-            if (dirty_[physReg] && vrm_.hasStackSlot(virtReg)) {
+            if (dirty_[physReg] && vrm_->hasStackSlot(virtReg)) {
                 assert(lastDef_[virtReg] && "virtual register is mapped "
                        "to a register and but was not defined!");
                 MachineBasicBlock::iterator lastDef = lastDef_[virtReg];
                 MachineBasicBlock::iterator nextLastRef = next(lastDef);
-                mri_.storeRegToStackSlot(*lastDef->getParent(),
+                mri_->storeRegToStackSlot(*lastDef->getParent(),
                                          nextLastRef,
                                          physReg,
-                                         vrm_.getStackSlot(virtReg),
-                                         mri_.getRegClass(physReg));
+                                         vrm_->getStackSlot(virtReg),
+                                         mri_->getRegClass(physReg));
                 ++numStores;
                 DEBUG(std::cerr << "added: ";
-                      prior(nextLastRef)->print(std::cerr, tm_);
+                      prior(nextLastRef)->print(std::cerr, *tm_);
                       std::cerr << "after: ";
-                      lastDef->print(std::cerr, tm_));
+                      lastDef->print(std::cerr, *tm_));
                 lastDef_[virtReg] = 0;
             }
             p2vMap_[physReg] = 0;
@@ -162,7 +176,7 @@ namespace {
                            MachineBasicBlock::iterator mii,
                            unsigned physReg) {
             vacateJustPhysReg(mbb, mii, physReg);
-            for (const unsigned* as = mri_.getAliasSet(physReg); *as; ++as)
+            for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as)
                 vacateJustPhysReg(mbb, mii, *as);
         }
 
@@ -175,13 +189,13 @@ namespace {
                 vacatePhysReg(mbb, mii, physReg);
                 p2vMap_[physReg] = virtReg;
                 // load if necessary
-                if (vrm_.hasStackSlot(virtReg)) {
-                    mri_.loadRegFromStackSlot(mbb, mii, physReg,
-                                              vrm_.getStackSlot(virtReg),
-                                              mri_.getRegClass(physReg));
+                if (vrm_->hasStackSlot(virtReg)) {
+                    mri_->loadRegFromStackSlot(mbb, mii, physReg,
+                                              vrm_->getStackSlot(virtReg),
+                                              mri_->getRegClass(physReg));
                     ++numLoads;
                     DEBUG(std::cerr << "added: ";
-                          prior(mii)->print(std::cerr,tm_));
+                          prior(mii)->print(std::cerr, *tm_));
                     lastDef_[virtReg] = mii;
                 }
             }
@@ -208,8 +222,8 @@ namespace {
                 // we clear all physical registers that may contain
                 // the value of the spilled virtual register
                 VirtRegMap::MI2VirtMap::const_iterator i, e;
-                for (tie(i, e) = vrm_.getFoldedVirts(mii); i != e; ++i) {
-                    unsigned physReg = vrm_.getPhys(i->second);
+                for (tie(i, e) = vrm_->getFoldedVirts(mii); i != e; ++i) {
+                    unsigned physReg = vrm_->getPhys(i->second);
                     if (physReg) vacateJustPhysReg(mbb, mii, physReg);
                 }
 
@@ -219,7 +233,7 @@ namespace {
                     if (op.isRegister() && op.getReg() && op.isUse() &&
                         MRegisterInfo::isVirtualRegister(op.getReg())) {
                         unsigned virtReg = op.getReg();
-                        unsigned physReg = vrm_.getPhys(virtReg);
+                        unsigned physReg = vrm_->getPhys(virtReg);
                         handleUse(mbb, mii, virtReg, physReg);
                         mii->SetMachineOperandReg(i, physReg);
                         // mark as dirty if this is def&use
@@ -231,7 +245,7 @@ namespace {
                 }
 
                 // spill implicit defs
-                const TargetInstrDescriptor& tid =tii_.get(mii->getOpcode());
+                const TargetInstrDescriptor& tid = tii_->get(mii->getOpcode());
                 for (const unsigned* id = tid.ImplicitDefs; *id; ++id)
                     vacatePhysReg(mbb, mii, *id);
 
@@ -243,13 +257,13 @@ namespace {
                         if (MRegisterInfo::isPhysicalRegister(op.getReg()))
                             vacatePhysReg(mbb, mii, op.getReg());
                         else {
-                            unsigned physReg = vrm_.getPhys(op.getReg());
+                            unsigned physReg = vrm_->getPhys(op.getReg());
                             handleDef(mbb, mii, op.getReg(), physReg);
                             mii->SetMachineOperandReg(i, physReg);
                         }
                 }
 
-                DEBUG(std::cerr << '\t'; mii->print(std::cerr, tm_));
+                DEBUG(std::cerr << '\t'; mii->print(std::cerr, *tm_));
             }
 
             for (unsigned i = 1, e = p2vMap_.size(); i != e; ++i)
@@ -259,8 +273,13 @@ namespace {
     };
 }
 
-
-void llvm::eliminateVirtRegs(MachineFunction& mf, const VirtRegMap& vrm)
+llvm::Spiller* llvm::createSpiller()
 {
-    Spiller(mf, vrm).eliminateVirtRegs();
+    switch (SpillerOpt) {
+    default:
+        std::cerr << "no spiller selected";
+        abort();
+    case local:
+        return new LocalSpiller();
+    }
 }
index 90cc44d31c4261e0182e413ac77e1ed2453b8dcf..3c2f8eec4ad7ebf7f42ffa47bbf07e5b538341d5 100644 (file)
@@ -108,7 +108,14 @@ namespace llvm {
 
     std::ostream& operator<<(std::ostream& os, const VirtRegMap& li);
 
-    void eliminateVirtRegs(MachineFunction& mf, const VirtRegMap& vrm);
+    struct Spiller {
+        virtual ~Spiller();
+
+        virtual bool runOnMachineFunction(MachineFunction& mf, const VirtRegMap& vrm) = 0;
+
+    };
+
+    Spiller* createSpiller();
 
 } // End llvm namespace