[llvm-branch-commits] [llvm-branch] r89256 - in /llvm/branches/Apple/Leela: include/llvm/CodeGen/LiveIntervalAnalysis.h include/llvm/CodeGen/MachineFunction.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/MachineVerifier.cpp

Jakob Stoklund Olesen stoklund at 2pi.dk
Wed Nov 18 14:17:46 PST 2009


Author: stoklund
Date: Wed Nov 18 16:17:45 2009
New Revision: 89256

URL: http://llvm.org/viewvc/llvm-project?rev=89256&view=rev
Log:
Merge 89240 89241

Modified:
    llvm/branches/Apple/Leela/include/llvm/CodeGen/LiveIntervalAnalysis.h
    llvm/branches/Apple/Leela/include/llvm/CodeGen/MachineFunction.h
    llvm/branches/Apple/Leela/lib/CodeGen/LiveIntervalAnalysis.cpp
    llvm/branches/Apple/Leela/lib/CodeGen/MachineVerifier.cpp

Modified: llvm/branches/Apple/Leela/include/llvm/CodeGen/LiveIntervalAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=89256&r1=89255&r2=89256&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/include/llvm/CodeGen/LiveIntervalAnalysis.h (original)
+++ llvm/branches/Apple/Leela/include/llvm/CodeGen/LiveIntervalAnalysis.h Wed Nov 18 16:17:45 2009
@@ -91,9 +91,6 @@
 
     DenseMap<MachineBasicBlock*, LiveIndex> terminatorGaps;
 
-    /// phiJoinCopies - Copy instructions which are PHI joins.
-    SmallVector<MachineInstr*, 16> phiJoinCopies;
-
     /// allocatableRegs_ - A bit vector of allocatable registers.
     BitVector allocatableRegs_;
 
@@ -432,12 +429,6 @@
     /// computeIntervals - Compute live intervals.
     void computeIntervals();
 
-    bool isProfitableToCoalesce(LiveInterval &DstInt, LiveInterval &SrcInt,
-                                SmallVector<MachineInstr*,16> &IdentCopies,
-                                SmallVector<MachineInstr*,16> &OtherCopies);
-
-    void performEarlyCoalescing();
-
     /// handleRegisterDef - update intervals for a register def
     /// (calls handlePhysicalRegisterDef and
     /// handleVirtualRegisterDef)

Modified: llvm/branches/Apple/Leela/include/llvm/CodeGen/MachineFunction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/include/llvm/CodeGen/MachineFunction.h?rev=89256&r1=89255&r2=89256&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/include/llvm/CodeGen/MachineFunction.h (original)
+++ llvm/branches/Apple/Leela/include/llvm/CodeGen/MachineFunction.h Wed Nov 18 16:17:45 2009
@@ -27,6 +27,7 @@
 
 namespace llvm {
 
+class Pass;
 class Value;
 class Function;
 class MachineRegisterInfo;
@@ -231,7 +232,7 @@
 
   /// verify - Run the current MachineFunction through the machine code
   /// verifier, useful for debugger use.
-  void verify() const;
+  void verify(Pass *p=NULL, bool allowDoubleDefs=false) const;
 
   // Provide accessors for the MachineBasicBlock list...
   typedef BasicBlockListType::iterator iterator;

Modified: llvm/branches/Apple/Leela/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=89256&r1=89255&r2=89256&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/branches/Apple/Leela/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Nov 18 16:17:45 2009
@@ -52,15 +52,9 @@
 static cl::opt<bool> EnableFastSpilling("fast-spill",
                                         cl::init(false), cl::Hidden);
 
-static cl::opt<bool> EarlyCoalescing("early-coalescing", cl::init(false));
-
-static cl::opt<int> CoalescingLimit("early-coalescing-limit",
-                                    cl::init(-1), cl::Hidden);
-
 STATISTIC(numIntervals , "Number of original intervals");
 STATISTIC(numFolds     , "Number of loads/stores folded into instructions");
 STATISTIC(numSplits    , "Number of intervals split");
-STATISTIC(numCoalescing, "Number of early coalescing performed");
 
 char LiveIntervals::ID = 0;
 static RegisterPass<LiveIntervals> X("liveintervals", "Live Interval Analysis");
@@ -94,8 +88,6 @@
   mi2iMap_.clear();
   i2miMap_.clear();
   r2iMap_.clear();
-  terminatorGaps.clear();
-  phiJoinCopies.clear();
 
   // Release VNInfo memroy regions after all VNInfo objects are dtor'd.
   VNInfoAllocator.Reset();
@@ -290,7 +282,6 @@
   mi2iMap_.clear();
   i2miMap_.clear();
   terminatorGaps.clear();
-  phiJoinCopies.clear();
   
   FunctionSize = 0;
   
@@ -545,7 +536,6 @@
   processImplicitDefs();
   computeNumbering();
   computeIntervals();
-  performEarlyCoalescing();
 
   numIntervals += getNumIntervals();
 
@@ -836,7 +826,6 @@
         // Remove the old range that we now know has an incorrect number.
         VNInfo *VNI = interval.getValNumInfo(0);
         MachineInstr *Killer = vi.Kills[0];
-        phiJoinCopies.push_back(Killer);
         LiveIndex Start = getMBBStartIdx(Killer->getParent());
         LiveIndex End =
           getNextSlot(getUseIndex(getInstructionIndex(Killer)));
@@ -1086,132 +1075,6 @@
   DEBUG(errs() << " +" << LR << '\n');
 }
 
-bool
-LiveIntervals::isProfitableToCoalesce(LiveInterval &DstInt, LiveInterval &SrcInt,
-                                   SmallVector<MachineInstr*,16> &IdentCopies,
-                                   SmallVector<MachineInstr*,16> &OtherCopies) {
-  bool HaveConflict = false;
-  unsigned NumIdent = 0;
-  for (MachineRegisterInfo::def_iterator ri = mri_->def_begin(SrcInt.reg),
-         re = mri_->def_end(); ri != re; ++ri) {
-    MachineInstr *MI = &*ri;
-    unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
-    if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
-      return false;
-    if (SrcReg != DstInt.reg) {
-      OtherCopies.push_back(MI);
-      HaveConflict |= DstInt.liveAt(getInstructionIndex(MI));
-    } else {
-      IdentCopies.push_back(MI);
-      ++NumIdent;
-    }
-  }
-
-  if (!HaveConflict)
-    return false; // Let coalescer handle it
-  return IdentCopies.size() > OtherCopies.size();
-}
-
-void LiveIntervals::performEarlyCoalescing() {
-  if (!EarlyCoalescing)
-    return;
-
-  /// Perform early coalescing: eliminate copies which feed into phi joins
-  /// and whose sources are defined by the phi joins.
-  for (unsigned i = 0, e = phiJoinCopies.size(); i != e; ++i) {
-    MachineInstr *Join = phiJoinCopies[i];
-    if (CoalescingLimit != -1 && (int)numCoalescing == CoalescingLimit)
-      break;
-
-    unsigned PHISrc, PHIDst, SrcSubReg, DstSubReg;
-    bool isMove= tii_->isMoveInstr(*Join, PHISrc, PHIDst, SrcSubReg, DstSubReg);
-#ifndef NDEBUG
-    assert(isMove && "PHI join instruction must be a move!");
-#else
-    isMove = isMove;
-#endif
-
-    LiveInterval &DstInt = getInterval(PHIDst);
-    LiveInterval &SrcInt = getInterval(PHISrc);
-    SmallVector<MachineInstr*, 16> IdentCopies;
-    SmallVector<MachineInstr*, 16> OtherCopies;
-    if (!isProfitableToCoalesce(DstInt, SrcInt, IdentCopies, OtherCopies))
-      continue;
-
-    DEBUG(errs() << "PHI Join: " << *Join);
-    assert(DstInt.containsOneValue() && "PHI join should have just one val#!");
-    VNInfo *VNI = DstInt.getValNumInfo(0);
-
-    // Change the non-identity copies to directly target the phi destination.
-    for (unsigned i = 0, e = OtherCopies.size(); i != e; ++i) {
-      MachineInstr *PHICopy = OtherCopies[i];
-      DEBUG(errs() << "Moving: " << *PHICopy);
-
-      LiveIndex MIIndex = getInstructionIndex(PHICopy);
-      LiveIndex DefIndex = getDefIndex(MIIndex);
-      LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex);
-      LiveIndex StartIndex = SLR->start;
-      LiveIndex EndIndex = SLR->end;
-
-      // Delete val# defined by the now identity copy and add the range from
-      // beginning of the mbb to the end of the range.
-      SrcInt.removeValNo(SLR->valno);
-      DEBUG(errs() << "  added range [" << StartIndex << ','
-            << EndIndex << "] to reg" << DstInt.reg << '\n');
-      if (DstInt.liveAt(StartIndex))
-        DstInt.removeRange(StartIndex, EndIndex);
-      VNInfo *NewVNI = DstInt.getNextValue(DefIndex, PHICopy, true,
-                                           VNInfoAllocator);
-      NewVNI->setHasPHIKill(true);
-      DstInt.addRange(LiveRange(StartIndex, EndIndex, NewVNI));
-      for (unsigned j = 0, ee = PHICopy->getNumOperands(); j != ee; ++j) {
-        MachineOperand &MO = PHICopy->getOperand(j);
-        if (!MO.isReg() || MO.getReg() != PHISrc)
-          continue;
-        MO.setReg(PHIDst);
-      }
-    }
-
-    // Now let's eliminate all the would-be identity copies.
-    for (unsigned i = 0, e = IdentCopies.size(); i != e; ++i) {
-      MachineInstr *PHICopy = IdentCopies[i];
-      DEBUG(errs() << "Coalescing: " << *PHICopy);
-
-      LiveIndex MIIndex = getInstructionIndex(PHICopy);
-      LiveIndex DefIndex = getDefIndex(MIIndex);
-      LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex);
-      LiveIndex StartIndex = SLR->start;
-      LiveIndex EndIndex = SLR->end;
-
-      // Delete val# defined by the now identity copy and add the range from
-      // beginning of the mbb to the end of the range.
-      SrcInt.removeValNo(SLR->valno);
-      RemoveMachineInstrFromMaps(PHICopy);
-      PHICopy->eraseFromParent();
-      DEBUG(errs() << "  added range [" << StartIndex << ','
-            << EndIndex << "] to reg" << DstInt.reg << '\n');
-      DstInt.addRange(LiveRange(StartIndex, EndIndex, VNI));
-    }
-
-    // Remove the phi join and update the phi block liveness.
-    LiveIndex MIIndex = getInstructionIndex(Join);
-    LiveIndex UseIndex = getUseIndex(MIIndex);
-    LiveIndex DefIndex = getDefIndex(MIIndex);
-    LiveRange *SLR = SrcInt.getLiveRangeContaining(UseIndex);
-    LiveRange *DLR = DstInt.getLiveRangeContaining(DefIndex);
-    DLR->valno->setCopy(0);
-    DLR->valno->setIsDefAccurate(false);
-    DstInt.addRange(LiveRange(SLR->start, SLR->end, DLR->valno));
-    SrcInt.removeRange(SLR->start, SLR->end);
-    assert(SrcInt.empty());
-    removeInterval(PHISrc);
-    RemoveMachineInstrFromMaps(Join);
-    Join->eraseFromParent();
-
-    ++numCoalescing;
-  }
-}
-
 /// computeIntervals - computes the live intervals for virtual
 /// registers. for some ordering of the machine instructions [1,N] a
 /// live interval is an interval [i, j) where 1 <= i <= j < N for

Modified: llvm/branches/Apple/Leela/lib/CodeGen/MachineVerifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/CodeGen/MachineVerifier.cpp?rev=89256&r1=89255&r2=89256&view=diff

==============================================================================
--- llvm/branches/Apple/Leela/lib/CodeGen/MachineVerifier.cpp (original)
+++ llvm/branches/Apple/Leela/lib/CodeGen/MachineVerifier.cpp Wed Nov 18 16:17:45 2009
@@ -42,23 +42,18 @@
 using namespace llvm;
 
 namespace {
-  struct MachineVerifier : public MachineFunctionPass {
-    static char ID; // Pass ID, replacement for typeid
+  struct MachineVerifier {
 
-    MachineVerifier(bool allowDoubleDefs = false) :
-      MachineFunctionPass(&ID),
+    MachineVerifier(Pass *pass, bool allowDoubleDefs) :
+      PASS(pass),
       allowVirtDoubleDefs(allowDoubleDefs),
       allowPhysDoubleDefs(allowDoubleDefs),
       OutFileName(getenv("LLVM_VERIFY_MACHINEINSTRS"))
-        {}
-
-    void getAnalysisUsage(AnalysisUsage &AU) const {
-      AU.setPreservesAll();
-      MachineFunctionPass::getAnalysisUsage(AU);
-    }
+      {}
 
     bool runOnMachineFunction(MachineFunction &MF);
 
+    Pass *const PASS;
     const bool allowVirtDoubleDefs;
     const bool allowPhysDoubleDefs;
 
@@ -112,6 +107,10 @@
       // regsKilled and regsLiveOut.
       RegSet vregsPassed;
 
+      // Vregs that must pass through MBB because they are needed by a successor
+      // block. This set is disjoint from regsLiveOut.
+      RegSet vregsRequired;
+
       BBInfo() : reachable(false) {}
 
       // Add register to vregsPassed if it belongs there. Return true if
@@ -133,6 +132,34 @@
         return changed;
       }
 
+      // Add register to vregsRequired if it belongs there. Return true if
+      // anything changed.
+      bool addRequired(unsigned Reg) {
+        if (!TargetRegisterInfo::isVirtualRegister(Reg))
+          return false;
+        if (regsLiveOut.count(Reg))
+          return false;
+        return vregsRequired.insert(Reg).second;
+      }
+
+      // Same for a full set.
+      bool addRequired(const RegSet &RS) {
+        bool changed = false;
+        for (RegSet::const_iterator I = RS.begin(), E = RS.end(); I != E; ++I)
+          if (addRequired(*I))
+            changed = true;
+        return changed;
+      }
+
+      // Same for a full map.
+      bool addRequired(const RegMap &RM) {
+        bool changed = false;
+        for (RegMap::const_iterator I = RM.begin(), E = RM.end(); I != E; ++I)
+          if (addRequired(I->first))
+            changed = true;
+        return changed;
+      }
+
       // Live-out registers are either in regsLiveOut or vregsPassed.
       bool isLiveOut(unsigned Reg) const {
         return regsLiveOut.count(Reg) || vregsPassed.count(Reg);
@@ -146,6 +173,9 @@
       return Reg < regsReserved.size() && regsReserved.test(Reg);
     }
 
+    // Analysis information if available
+    LiveVariables *LiveVars;
+
     void visitMachineFunctionBefore();
     void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB);
     void visitMachineInstrBefore(const MachineInstr *MI);
@@ -163,20 +193,44 @@
     void calcMaxRegsPassed();
     void calcMinRegsPassed();
     void checkPHIOps(const MachineBasicBlock *MBB);
+
+    void calcRegsRequired();
+    void verifyLiveVariables();
+  };
+
+  struct MachineVerifierPass : public MachineFunctionPass {
+    static char ID; // Pass ID, replacement for typeid
+    bool AllowDoubleDefs;
+
+    explicit MachineVerifierPass(bool allowDoubleDefs = false)
+      : MachineFunctionPass(&ID),
+        AllowDoubleDefs(allowDoubleDefs) {}
+
+    void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.setPreservesAll();
+      MachineFunctionPass::getAnalysisUsage(AU);
+    }
+
+    bool runOnMachineFunction(MachineFunction &MF) {
+      MF.verify(this, AllowDoubleDefs);
+      return false;
+    }
   };
+
 }
 
-char MachineVerifier::ID = 0;
-static RegisterPass<MachineVerifier>
+char MachineVerifierPass::ID = 0;
+static RegisterPass<MachineVerifierPass>
 MachineVer("machineverifier", "Verify generated machine code");
 static const PassInfo *const MachineVerifyID = &MachineVer;
 
 FunctionPass *llvm::createMachineVerifierPass(bool allowPhysDoubleDefs) {
-  return new MachineVerifier(allowPhysDoubleDefs);
+  return new MachineVerifierPass(allowPhysDoubleDefs);
 }
 
-void MachineFunction::verify() const {
-  MachineVerifier().runOnMachineFunction(const_cast<MachineFunction&>(*this));
+void MachineFunction::verify(Pass *p, bool allowDoubleDefs) const {
+  MachineVerifier(p, allowDoubleDefs)
+    .runOnMachineFunction(const_cast<MachineFunction&>(*this));
 }
 
 bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
@@ -202,6 +256,12 @@
   TRI = TM->getRegisterInfo();
   MRI = &MF.getRegInfo();
 
+  if (PASS) {
+    LiveVars = PASS->getAnalysisIfAvailable<LiveVariables>();
+  } else {
+    LiveVars = NULL;
+  }
+
   visitMachineFunctionBefore();
   for (MachineFunction::const_iterator MFI = MF.begin(), MFE = MF.end();
        MFI!=MFE; ++MFI) {
@@ -518,8 +578,9 @@
     } else if (MO->isUse()) {
       regsLiveInButUnused.erase(Reg);
 
+      bool isKill = false;
       if (MO->isKill()) {
-        addRegWithSubRegs(regsKilled, Reg);
+        isKill = true;
         // Tied operands on two-address instuctions MUST NOT have a <kill> flag.
         if (MI->isRegTiedToDefOperand(MONum))
             report("Illegal kill flag on two-address instruction operand",
@@ -529,8 +590,20 @@
         unsigned defIdx;
         if (MI->isRegTiedToDefOperand(MONum, &defIdx) &&
             MI->getOperand(defIdx).getReg() == Reg)
-          addRegWithSubRegs(regsKilled, Reg);
+          isKill = true;
+      }
+      if (isKill) {
+        addRegWithSubRegs(regsKilled, Reg);
+
+        // Check that LiveVars knows this kill
+        if (LiveVars && TargetRegisterInfo::isVirtualRegister(Reg)) {
+          LiveVariables::VarInfo &VI = LiveVars->getVarInfo(Reg);
+          if (std::find(VI.Kills.begin(),
+                        VI.Kills.end(), MI) == VI.Kills.end())
+            report("Kill missing from LiveVariables", MO, MONum);
+        }
       }
+
       // Use of a dead register.
       if (!regsLive.count(Reg)) {
         if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
@@ -734,6 +807,41 @@
   }
 }
 
+// Calculate the set of virtual registers that must be passed through each basic
+// block in order to satisfy the requirements of successor blocks. This is very
+// similar to calcMaxRegsPassed, only backwards.
+void MachineVerifier::calcRegsRequired() {
+  // First push live-in regs to predecessors' vregsRequired.
+  DenseSet<const MachineBasicBlock*> todo;
+  for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end();
+       MFI != MFE; ++MFI) {
+    const MachineBasicBlock &MBB(*MFI);
+    BBInfo &MInfo = MBBInfoMap[&MBB];
+    for (MachineBasicBlock::const_pred_iterator PrI = MBB.pred_begin(),
+           PrE = MBB.pred_end(); PrI != PrE; ++PrI) {
+      BBInfo &PInfo = MBBInfoMap[*PrI];
+      if (PInfo.addRequired(MInfo.vregsLiveIn))
+        todo.insert(*PrI);
+    }
+  }
+
+  // Iteratively push vregsRequired to predecessors. This will converge to the
+  // same final state regardless of DenseSet iteration order.
+  while (!todo.empty()) {
+    const MachineBasicBlock *MBB = *todo.begin();
+    todo.erase(MBB);
+    BBInfo &MInfo = MBBInfoMap[MBB];
+    for (MachineBasicBlock::const_pred_iterator PrI = MBB->pred_begin(),
+           PrE = MBB->pred_end(); PrI != PrE; ++PrI) {
+      if (*PrI == MBB)
+        continue;
+      BBInfo &SInfo = MBBInfoMap[*PrI];
+      if (SInfo.addRequired(MInfo.vregsRequired))
+        todo.insert(*PrI);
+    }
+  }
+}
+
 // Check PHI instructions at the beginning of MBB. It is assumed that
 // calcMinRegsPassed has been run so BBInfo::isLiveOut is valid.
 void MachineVerifier::checkPHIOps(const MachineBasicBlock *MBB) {
@@ -849,4 +957,39 @@
       }
     }
   }
+
+  // Now check LiveVariables info if available
+  if (LiveVars) {
+    calcRegsRequired();
+    verifyLiveVariables();
+  }
 }
+
+void MachineVerifier::verifyLiveVariables() {
+  assert(LiveVars && "Don't call verifyLiveVariables without LiveVars");
+  for (unsigned Reg = TargetRegisterInfo::FirstVirtualRegister,
+         RegE = MRI->getLastVirtReg()-1; Reg != RegE; ++Reg) {
+    LiveVariables::VarInfo &VI = LiveVars->getVarInfo(Reg);
+    for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end();
+         MFI != MFE; ++MFI) {
+      BBInfo &MInfo = MBBInfoMap[MFI];
+
+      // Our vregsRequired should be identical to LiveVariables' AliveBlocks
+      if (MInfo.vregsRequired.count(Reg)) {
+        if (!VI.AliveBlocks.test(MFI->getNumber())) {
+          report("LiveVariables: Block missing from AliveBlocks", MFI);
+          *OS << "Virtual register %reg" << Reg
+              << " must be live through the block.\n";
+        }
+      } else {
+        if (VI.AliveBlocks.test(MFI->getNumber())) {
+          report("LiveVariables: Block should not be in AliveBlocks", MFI);
+          *OS << "Virtual register %reg" << Reg
+              << " is not needed live through the block.\n";
+        }
+      }
+    }
+  }
+}
+
+





More information about the llvm-branch-commits mailing list