Make load->store deletion a bit smarter. This allows us to compile this:
[oota-llvm.git] / lib / CodeGen / RegAllocLinearScan.cpp
index bc9febff59a94a663564c09834de19608e997ac8..6f850eb1b355abff0be400e490c0c0ec848b0e4e 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     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 is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 #include "llvm/Function.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/RegAllocRegistry.h"
 #include "llvm/CodeGen/RegisterCoalescer.h"
-#include "llvm/CodeGen/SSARegMap.h"
 #include "llvm/Target/MRegisterInfo.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetInstrInfo.h"
@@ -63,9 +64,10 @@ namespace {
     const TargetMachine* tm_;
     const MRegisterInfo* mri_;
     const TargetInstrInfo* tii_;
-    SSARegMap *regmap_;
+    MachineRegisterInfo *reginfo_;
     BitVector allocatableRegs_;
     LiveIntervals* li_;
+    const MachineLoopInfo *loopInfo;
 
     /// handled_ - Intervals are added to the handled_ set in the order of their
     /// start value.  This is uses for backtracking.
@@ -101,6 +103,9 @@ namespace {
       // Make sure PassManager knows which analyses to make available
       // to coalescing and which analyses coalescing invalidates.
       AU.addRequiredTransitive<RegisterCoalescer>();
+      AU.addRequired<MachineLoopInfo>();
+      AU.addPreserved<MachineLoopInfo>();
+      AU.addPreservedID(MachineDominatorsID);
       MachineFunctionPass::getAnalysisUsage(AU);
     }
 
@@ -227,7 +232,7 @@ unsigned RALinScan::attemptTrivialCoalescing(LiveInterval &cur, unsigned Reg) {
   if (Reg == SrcReg)
     return Reg;
 
-  const TargetRegisterClass *RC = regmap_->getRegClass(cur.reg);
+  const TargetRegisterClass *RC = reginfo_->getRegClass(cur.reg);
   if (!RC->contains(SrcReg))
     return Reg;
 
@@ -248,9 +253,10 @@ bool RALinScan::runOnMachineFunction(MachineFunction &fn) {
   tm_ = &fn.getTarget();
   mri_ = tm_->getRegisterInfo();
   tii_ = tm_->getInstrInfo();
-  regmap_ = mf_->getSSARegMap();
+  reginfo_ = &mf_->getRegInfo();
   allocatableRegs_ = mri_->getAllocatableSet(fn);
   li_ = &getAnalysis<LiveIntervals>();
+  loopInfo = &getAnalysis<MachineLoopInfo>();
 
   // We don't run the coalescer here because we have no reason to
   // interact with it.  If the coalescer requires interaction, it
@@ -292,7 +298,7 @@ void RALinScan::initIntervalSets()
 
   for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i) {
     if (MRegisterInfo::isPhysicalRegister(i->second.reg)) {
-      mf_->setPhysRegUsed(i->second.reg);
+      reginfo_->setPhysRegUsed(i->second.reg);
       fixed_.push_back(std::make_pair(&i->second, i->second.begin()));
     } else
       unhandled_.push(&i->second);
@@ -347,18 +353,22 @@ void RALinScan::linearScan()
         DOUT << "\tinterval " << *i->first << " expired\n");
   inactive_.clear();
 
-  // Add live-ins to every BB except for entry.
+  // Add live-ins to every BB except for entry. Also perform trivial coalescing.
   MachineFunction::iterator EntryMBB = mf_->begin();
   SmallVector<MachineBasicBlock*, 8> LiveInMBBs;
   for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i) {
     LiveInterval &cur = i->second;
     unsigned Reg = 0;
-    if (MRegisterInfo::isPhysicalRegister(cur.reg))
+    bool isPhys = MRegisterInfo::isPhysicalRegister(cur.reg);
+    if (isPhys)
       Reg = i->second.reg;
     else if (vrm_->isAssignedReg(cur.reg))
       Reg = attemptTrivialCoalescing(cur, vrm_->getPhys(cur.reg));
     if (!Reg)
       continue;
+    // Ignore splited live intervals.
+    if (!isPhys && vrm_->getPreSplitReg(cur.reg))
+      continue;
     for (LiveInterval::Ranges::const_iterator I = cur.begin(), E = cur.end();
          I != E; ++I) {
       const LiveRange &LR = *I;
@@ -500,7 +510,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
 
   std::vector<std::pair<unsigned, float> > SpillWeightsToAdd;
   unsigned StartPosition = cur->beginNumber();
-  const TargetRegisterClass *RC = regmap_->getRegClass(cur->reg);
+  const TargetRegisterClass *RC = reginfo_->getRegClass(cur->reg);
   const TargetRegisterClass *RCLeader = RelatedRegClasses.getLeaderValue(RC);
 
   // If this live interval is defined by a move instruction and its source is
@@ -532,7 +542,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
     unsigned Reg = i->first->reg;
     assert(MRegisterInfo::isVirtualRegister(Reg) &&
            "Can only allocate virtual registers!");
-    const TargetRegisterClass *RegRC = regmap_->getRegClass(Reg);
+    const TargetRegisterClass *RegRC = reginfo_->getRegClass(Reg);
     // If this is not in a related reg class to the register we're allocating, 
     // don't check it.
     if (RelatedRegClasses.getLeaderValue(RegRC) == RCLeader &&
@@ -686,7 +696,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
   if (cur->weight != HUGE_VALF && cur->weight <= minWeight) {
     DOUT << "\t\t\tspilling(c): " << *cur << '\n';
     std::vector<LiveInterval*> added =
-      li_->addIntervalsForSpills(*cur, *vrm_);
+      li_->addIntervalsForSpills(*cur, loopInfo, *vrm_);
     if (added.empty())
       return;  // Early exit if all spills were folded.
 
@@ -738,7 +748,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
       DOUT << "\t\t\tspilling(a): " << *i->first << '\n';
       earliestStart = std::min(earliestStart, i->first->beginNumber());
       std::vector<LiveInterval*> newIs =
-        li_->addIntervalsForSpills(*i->first, *vrm_);
+        li_->addIntervalsForSpills(*i->first, loopInfo, *vrm_);
       std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
       spilled.insert(reg);
     }
@@ -751,7 +761,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur)
       DOUT << "\t\t\tspilling(i): " << *i->first << '\n';
       earliestStart = std::min(earliestStart, i->first->beginNumber());
       std::vector<LiveInterval*> newIs =
-        li_->addIntervalsForSpills(*i->first, *vrm_);
+        li_->addIntervalsForSpills(*i->first, loopInfo, *vrm_);
       std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
       spilled.insert(reg);
     }
@@ -830,7 +840,7 @@ unsigned RALinScan::getFreePhysReg(LiveInterval *cur) {
   std::vector<unsigned> inactiveCounts(mri_->getNumRegs(), 0);
   unsigned MaxInactiveCount = 0;
   
-  const TargetRegisterClass *RC = regmap_->getRegClass(cur->reg);
+  const TargetRegisterClass *RC = reginfo_->getRegClass(cur->reg);
   const TargetRegisterClass *RCLeader = RelatedRegClasses.getLeaderValue(RC);
  
   for (IntervalPtrs::iterator i = inactive_.begin(), e = inactive_.end();
@@ -841,7 +851,7 @@ unsigned RALinScan::getFreePhysReg(LiveInterval *cur) {
 
     // If this is not in a related reg class to the register we're allocating, 
     // don't check it.
-    const TargetRegisterClass *RegRC = regmap_->getRegClass(reg);
+    const TargetRegisterClass *RegRC = reginfo_->getRegClass(reg);
     if (RelatedRegClasses.getLeaderValue(RegRC) == RCLeader) {
       reg = vrm_->getPhys(reg);
       ++inactiveCounts[reg];