[llvm-commits] [vector_llvm] CVS: llvm/lib/CodeGen/AsmPrinter.cpp ELFWriter.cpp IntrinsicLowering.cpp LiveInterval.cpp LiveIntervalAnalysis.cpp Passes.cpp PrologEpilogInserter.cpp RegAllocIterativeScan.cpp RegAllocLocal.cpp TwoAddressInstructionPass.cpp

Robert Bocchino bocchino at cs.uiuc.edu
Wed Nov 16 10:32:26 PST 2005



Changes in directory llvm/lib/CodeGen:

AsmPrinter.cpp updated: 1.20 -> 1.20.2.1
ELFWriter.cpp updated: 1.15 -> 1.15.2.1
IntrinsicLowering.cpp updated: 1.34 -> 1.34.2.1
LiveInterval.cpp updated: 1.22 -> 1.22.2.1
LiveIntervalAnalysis.cpp updated: 1.149 -> 1.149.2.1
Passes.cpp updated: 1.15 -> 1.15.4.1
PrologEpilogInserter.cpp updated: 1.49 -> 1.49.2.1
RegAllocIterativeScan.cpp (r1.22) removed
RegAllocLocal.cpp updated: 1.74 -> 1.74.2.1
TwoAddressInstructionPass.cpp updated: 1.30 -> 1.30.4.1
---
Log message:

Merged mainline into Vector LLVM branch


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

 AsmPrinter.cpp                |   37 ++++++++-----
 ELFWriter.cpp                 |    1 
 IntrinsicLowering.cpp         |    9 ++-
 LiveInterval.cpp              |   86 +++++++++++++++++++++++++------
 LiveIntervalAnalysis.cpp      |  115 +++++++++++++++++++++++++++++++-----------
 Passes.cpp                    |    5 -
 PrologEpilogInserter.cpp      |   13 +++-
 RegAllocLocal.cpp             |   18 ++++--
 TwoAddressInstructionPass.cpp |    4 -
 9 files changed, 212 insertions(+), 76 deletions(-)


Index: llvm/lib/CodeGen/AsmPrinter.cpp
diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.20 llvm/lib/CodeGen/AsmPrinter.cpp:1.20.2.1
--- llvm/lib/CodeGen/AsmPrinter.cpp:1.20	Wed Aug 17 14:24:40 2005
+++ llvm/lib/CodeGen/AsmPrinter.cpp	Wed Nov 16 12:32:14 2005
@@ -13,7 +13,7 @@
 
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/Constants.h"
-#include "llvm/Instruction.h"
+#include "llvm/Module.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Target/TargetMachine.h"
@@ -31,11 +31,14 @@
 
 void AsmPrinter::setupMachineFunction(MachineFunction &MF) {
   // What's my mangled name?
-  CurrentFnName = Mang->getValueName((Value*)MF.getFunction());
+  CurrentFnName = Mang->getValueName(MF.getFunction());
 }
 
 // emitAlignment - Emit an alignment directive to the specified power of two.
-void AsmPrinter::emitAlignment(unsigned NumBits) const {
+void AsmPrinter::emitAlignment(unsigned NumBits, const GlobalValue *GV) const {
+  if (GV && GV->getAlignment())
+    NumBits = Log2_32(GV->getAlignment());
+  if (NumBits == 0) return;   // No need to emit alignment.
   if (AlignmentIsInBytes) NumBits = 1 << NumBits;
   O << AlignDirective << NumBits << "\n";
 }
@@ -68,15 +71,15 @@
       O << (uint64_t)CI->getValue();
   else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV))
     O << CI->getValue();
-  else if (isa<GlobalValue>((Value*)CV)) {
+  else if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
     // This is a constant address for a global variable or function. Use the
     // name of the variable or function as the address value, possibly
     // decorating it with GlobalVarAddrPrefix/Suffix or
     // FunctionAddrPrefix/Suffix (these all default to "" )
-    if (isa<Function>((Value*)CV))
-      O << FunctionAddrPrefix << Mang->getValueName(CV) << FunctionAddrSuffix;
+    if (isa<Function>(GV))
+      O << FunctionAddrPrefix << Mang->getValueName(GV) << FunctionAddrSuffix;
     else
-      O << GlobalVarAddrPrefix << Mang->getValueName(CV) << GlobalVarAddrSuffix;
+      O << GlobalVarAddrPrefix << Mang->getValueName(GV) << GlobalVarAddrSuffix;
   } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
     const TargetData &TD = TM.getTargetData();
     switch(CE->getOpcode()) {
@@ -115,9 +118,7 @@
               || (((TD.getTypeSize(Ty) >= TD.getTypeSize(OpTy))
                    && OpTy->isLosslesslyConvertibleTo(Ty))))
              && "FIXME: Don't yet support this kind of constant cast expr");
-      O << "(";
       emitConstantValueOnly(Op);
-      O << ")";
       break;
     }
     case Instruction::Add:
@@ -141,14 +142,15 @@
   return (X&7)+'0';
 }
 
-/// getAsCString - Return the specified array as a C compatible string, only if
+/// printAsCString - Print the specified array as a C compatible string, only if
 /// the predicate isString is true.
 ///
-static void printAsCString(std::ostream &O, const ConstantArray *CVA) {
+static void printAsCString(std::ostream &O, const ConstantArray *CVA,
+                           unsigned LastElt) {
   assert(CVA->isString() && "Array is not string compatible!");
 
   O << "\"";
-  for (unsigned i = 0; i != CVA->getNumOperands(); ++i) {
+  for (unsigned i = 0; i != LastElt; ++i) {
     unsigned char C =
         (unsigned char)cast<ConstantInt>(CVA->getOperand(i))->getRawValue();
 
@@ -187,8 +189,15 @@
     return;
   } else if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
     if (CVA->isString()) {
-      O << AsciiDirective;
-      printAsCString(O, CVA);
+      unsigned NumElts = CVA->getNumOperands();
+      if (AscizDirective && NumElts && 
+          cast<ConstantInt>(CVA->getOperand(NumElts-1))->getRawValue() == 0) {
+        O << AscizDirective;
+        printAsCString(O, CVA, NumElts-1);
+      } else {
+        O << AsciiDirective;
+        printAsCString(O, CVA, NumElts);
+      }
       O << "\n";
     } else { // Not a string.  Print the values in successive locations
       for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i)


Index: llvm/lib/CodeGen/ELFWriter.cpp
diff -u llvm/lib/CodeGen/ELFWriter.cpp:1.15 llvm/lib/CodeGen/ELFWriter.cpp:1.15.2.1
--- llvm/lib/CodeGen/ELFWriter.cpp:1.15	Fri Aug 19 11:19:21 2005
+++ llvm/lib/CodeGen/ELFWriter.cpp	Wed Nov 16 12:32:14 2005
@@ -25,7 +25,6 @@
 //  #3. ".bss" entry  - global variables without initializers.  [ if needed ]
 //  ...
 //  #N. ".shstrtab" entry - String table for the section names.
-
 //
 // NOTE: This code should eventually be extended to support 64-bit ELF (this
 // won't be hard), but we haven't done so yet!


Index: llvm/lib/CodeGen/IntrinsicLowering.cpp
diff -u llvm/lib/CodeGen/IntrinsicLowering.cpp:1.34 llvm/lib/CodeGen/IntrinsicLowering.cpp:1.34.2.1
--- llvm/lib/CodeGen/IntrinsicLowering.cpp:1.34	Wed Jul 27 01:12:33 2005
+++ llvm/lib/CodeGen/IntrinsicLowering.cpp	Wed Nov 16 12:32:14 2005
@@ -110,7 +110,8 @@
       case Intrinsic::memset:
         M.getOrInsertFunction("memset", PointerType::get(Type::SByteTy),
                               PointerType::get(Type::SByteTy),
-                              Type::IntTy, (--(--I->arg_end()))->getType(), 0);
+                              Type::IntTy, (--(--I->arg_end()))->getType(),
+                              (Type *)0);
         break;
       case Intrinsic::isunordered:
         EnsureFunctionExists(M, "isunordered", I->arg_begin(), I->arg_end(),
@@ -261,6 +262,12 @@
 
   case Intrinsic::pcmarker:
     break;    // Simply strip out pcmarker on unsupported architectures
+  case Intrinsic::readcyclecounter: {
+    std::cerr << "WARNING: this target does not support the llvm.readcyclecounter"
+              << " intrinsic.  It is being lowered to a constant 0\n";
+    CI->replaceAllUsesWith(ConstantUInt::get(Type::ULongTy, 0));
+    break;
+  }
 
   case Intrinsic::dbg_stoppoint:
   case Intrinsic::dbg_region_start:


Index: llvm/lib/CodeGen/LiveInterval.cpp
diff -u llvm/lib/CodeGen/LiveInterval.cpp:1.22 llvm/lib/CodeGen/LiveInterval.cpp:1.22.2.1
--- llvm/lib/CodeGen/LiveInterval.cpp:1.22	Tue Sep 20 23:19:08 2005
+++ llvm/lib/CodeGen/LiveInterval.cpp	Wed Nov 16 12:32:14 2005
@@ -101,6 +101,27 @@
   return false;
 }
 
+/// NontrivialOverlap - Check to see if the two live ranges specified by i and j
+/// overlap.  If so, check to see if they have value numbers that are not 
+/// iIdx/jIdx respectively.  If both conditions are true, return true.
+static inline bool NontrivialOverlap(const LiveRange &I, const LiveRange &J,
+                                     unsigned iIdx, unsigned jIdx) {
+  if (I.start == J.start) {
+    // If this is not the allowed value merge, we cannot join.
+    if (I.ValId != iIdx || J.ValId != jIdx)
+      return true;
+  } else if (I.start < J.start) {
+    if (I.end > J.start && (I.ValId != iIdx || J.ValId != jIdx)) {
+      return true;
+    }
+  } else {
+    if (J.end > I.start && (I.ValId != iIdx || J.ValId != jIdx))
+      return true;
+  }
+  
+  return false;
+}
+
 /// joinable - Two intervals are joinable if the either don't overlap at all
 /// or if the destination of the copy is a single assignment value, and it
 /// only overlaps with one value in the source interval.
@@ -125,21 +146,9 @@
   }
 
   while (i != ie && j != je) {
-    if (i->start == j->start) {
-      // If this is not the allowed value merge, we cannot join.
-      if (i->ValId != ThisValIdx || j->ValId != OtherValIdx)
-        return false;
-    } else if (i->start < j->start) {
-      if (i->end > j->start) {
-        if (i->ValId != ThisValIdx || j->ValId != OtherValIdx)
-          return false;
-      }
-    } else {
-      if (j->end > i->start) {
-        if (i->ValId != ThisValIdx || j->ValId != OtherValIdx)
-          return false;
-      }
-    }
+    if (NontrivialOverlap(*i, *j, ThisValIdx, OtherValIdx))
+      return false;
+    
     if (i->end < j->end)
       ++i;
     else
@@ -149,6 +158,43 @@
   return true;
 }
 
+/// getOverlapingRanges - Given another live interval which is defined as a
+/// copy from this one, return a list of all of the live ranges where the
+/// two overlap and have different value numbers.
+void LiveInterval::getOverlapingRanges(const LiveInterval &other, 
+                                       unsigned CopyIdx,
+                                       std::vector<LiveRange*> &Ranges) {
+  const LiveRange *SourceLR = getLiveRangeContaining(CopyIdx-1);
+  const LiveRange *DestLR = other.getLiveRangeContaining(CopyIdx);
+  assert(SourceLR && DestLR && "Not joining due to a copy?");
+  unsigned OtherValIdx = SourceLR->ValId;
+  unsigned ThisValIdx = DestLR->ValId;
+  
+  Ranges::iterator i = ranges.begin();
+  Ranges::iterator ie = ranges.end();
+  Ranges::const_iterator j = other.ranges.begin();
+  Ranges::const_iterator je = other.ranges.end();
+  
+  if (i->start < j->start) {
+    i = std::upper_bound(i, ie, j->start);
+    if (i != ranges.begin()) --i;
+  } else if (j->start < i->start) {
+    j = std::upper_bound(j, je, i->start);
+    if (j != other.ranges.begin()) --j;
+  }
+  
+  while (i != ie && j != je) {
+    if (NontrivialOverlap(*i, *j, ThisValIdx, OtherValIdx))
+      Ranges.push_back(&*i);
+    
+    if (i->end < j->end)
+      ++i;
+    else
+      ++j;
+  }
+}
+
+
 
 /// extendIntervalEndTo - This method is used when we want to extend the range
 /// specified by I to end at the specified endpoint.  To do this, we should
@@ -167,8 +213,16 @@
   // If NewEnd was in the middle of an interval, make sure to get its endpoint.
   I->end = std::max(NewEnd, prior(MergeTo)->end);
 
-  // Erase any dead ranges
+  // Erase any dead ranges.
   ranges.erase(next(I), MergeTo);
+  
+  // If the newly formed range now touches the range after it and if they have
+  // the same value number, merge the two ranges into one range.
+  Ranges::iterator Next = next(I);
+  if (Next != ranges.end() && Next->start <= I->end && Next->ValId == ValId) {
+    I->end = Next->end;
+    ranges.erase(Next);
+  }
 }
 
 


Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.149 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.149.2.1
--- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.149	Tue Sep 20 23:19:09 2005
+++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp	Wed Nov 16 12:32:14 2005
@@ -633,6 +633,49 @@
   }
 }
 
+/// IntA is defined as a copy from IntB and we know it only has one value
+/// number.  If all of the places that IntA and IntB overlap are defined by
+/// copies from IntA to IntB, we know that these two ranges can really be
+/// merged if we adjust the value numbers.  If it is safe, adjust the value
+/// numbers and return true, allowing coalescing to occur.
+bool LiveIntervals::
+AdjustIfAllOverlappingRangesAreCopiesFrom(LiveInterval &IntA,
+                                          LiveInterval &IntB,
+                                          unsigned CopyIdx) {
+  std::vector<LiveRange*> Ranges;
+  IntA.getOverlapingRanges(IntB, CopyIdx, Ranges);
+  
+  assert(!Ranges.empty() && "Why didn't we do a simple join of this?");
+  
+  unsigned IntBRep = rep(IntB.reg);
+  
+  // Check to see if all of the overlaps (entries in Ranges) are defined by a
+  // copy from IntA.  If not, exit.
+  for (unsigned i = 0, e = Ranges.size(); i != e; ++i) {
+    unsigned Idx = Ranges[i]->start;
+    MachineInstr *MI = getInstructionFromIndex(Idx);
+    unsigned SrcReg, DestReg;
+    if (!tii_->isMoveInstr(*MI, SrcReg, DestReg)) return false;
+    
+    // If this copy isn't actually defining this range, it must be a live
+    // range spanning basic blocks or something.
+    if (rep(DestReg) != rep(IntA.reg)) return false;
+    
+    // Check to see if this is coming from IntB.  If not, bail out.
+    if (rep(SrcReg) != IntBRep) return false;
+  }
+
+  // Okay, we can change this one.  Get the IntB value number that IntA is
+  // copied from.
+  unsigned ActualValNo = IntA.getLiveRangeContaining(CopyIdx-1)->ValId;
+  
+  // Change all of the value numbers to the same as what we IntA is copied from.
+  for (unsigned i = 0, e = Ranges.size(); i != e; ++i)
+    Ranges[i]->ValId = ActualValNo;
+  
+  return true;
+}
+
 void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) {
   DEBUG(std::cerr << ((Value*)MBB->getBasicBlock())->getName() << ":\n");
 
@@ -643,60 +686,72 @@
     // we only join virtual registers with allocatable
     // physical registers since we do not have liveness information
     // on not allocatable physical registers
-    unsigned regA, regB;
-    if (tii_->isMoveInstr(*mi, regA, regB) &&
-        (MRegisterInfo::isVirtualRegister(regA) || allocatableRegs_[regA]) &&
-        (MRegisterInfo::isVirtualRegister(regB) || allocatableRegs_[regB])) {
+    unsigned SrcReg, DestReg;
+    if (tii_->isMoveInstr(*mi, SrcReg, DestReg) &&
+        (MRegisterInfo::isVirtualRegister(SrcReg) || allocatableRegs_[SrcReg])&&
+        (MRegisterInfo::isVirtualRegister(DestReg)||allocatableRegs_[DestReg])){
 
       // Get representative registers.
-      regA = rep(regA);
-      regB = rep(regB);
+      SrcReg = rep(SrcReg);
+      DestReg = rep(DestReg);
 
       // If they are already joined we continue.
-      if (regA == regB)
+      if (SrcReg == DestReg)
         continue;
 
       // If they are both physical registers, we cannot join them.
-      if (MRegisterInfo::isPhysicalRegister(regA) &&
-          MRegisterInfo::isPhysicalRegister(regB))
+      if (MRegisterInfo::isPhysicalRegister(SrcReg) &&
+          MRegisterInfo::isPhysicalRegister(DestReg))
         continue;
 
       // If they are not of the same register class, we cannot join them.
-      if (differingRegisterClasses(regA, regB))
+      if (differingRegisterClasses(SrcReg, DestReg))
         continue;
 
-      LiveInterval &IntA = getInterval(regA);
-      LiveInterval &IntB = getInterval(regB);
-      assert(IntA.reg == regA && IntB.reg == regB &&
+      LiveInterval &SrcInt = getInterval(SrcReg);
+      LiveInterval &DestInt = getInterval(DestReg);
+      assert(SrcInt.reg == SrcReg && DestInt.reg == DestReg &&
              "Register mapping is horribly broken!");
 
-      DEBUG(std::cerr << "\t\tInspecting " << IntA << " and " << IntB << ": ");
+      DEBUG(std::cerr << "\t\tInspecting " << SrcInt << " and " << DestInt
+                      << ": ");
 
       // If two intervals contain a single value and are joined by a copy, it
       // does not matter if the intervals overlap, they can always be joined.
-      bool TriviallyJoinable =
-        IntA.containsOneValue() && IntB.containsOneValue();
+      bool Joinable = SrcInt.containsOneValue() && DestInt.containsOneValue();
 
       unsigned MIDefIdx = getDefIndex(getInstructionIndex(mi));
-      if ((TriviallyJoinable || IntB.joinable(IntA, MIDefIdx)) &&
-          !overlapsAliases(&IntA, &IntB)) {
-        IntB.join(IntA, MIDefIdx);
-        DEBUG(std::cerr << "Joined.  Result = " << IntB << "\n");
-
-        if (!MRegisterInfo::isPhysicalRegister(regA)) {
-          r2iMap_.erase(regA);
-          r2rMap_[regA] = regB;
+      
+      // If the intervals think that this is joinable, do so now.
+      if (!Joinable && DestInt.joinable(SrcInt, MIDefIdx))
+        Joinable = true;
+
+      // If DestInt is actually a copy from SrcInt (which we know) that is used
+      // to define another value of SrcInt, we can change the other range of
+      // SrcInt to be the value of the range that defines DestInt, allowing a
+      // coalesce.
+      if (!Joinable && DestInt.containsOneValue() &&
+          AdjustIfAllOverlappingRangesAreCopiesFrom(SrcInt, DestInt, MIDefIdx))
+        Joinable = true;
+      
+      if (!Joinable || overlapsAliases(&SrcInt, &DestInt)) {
+        DEBUG(std::cerr << "Interference!\n");
+      } else {
+        DestInt.join(SrcInt, MIDefIdx);
+        DEBUG(std::cerr << "Joined.  Result = " << DestInt << "\n");
+
+        if (!MRegisterInfo::isPhysicalRegister(SrcReg)) {
+          r2iMap_.erase(SrcReg);
+          r2rMap_[SrcReg] = DestReg;
         } else {
           // Otherwise merge the data structures the other way so we don't lose
           // the physreg information.
-          r2rMap_[regB] = regA;
-          IntB.reg = regA;
-          IntA.swap(IntB);
-          r2iMap_.erase(regB);
+          r2rMap_[DestReg] = SrcReg;
+          DestInt.reg = SrcReg;
+          SrcInt.swap(DestInt);
+          r2iMap_.erase(DestReg);
         }
         ++numJoins;
-      } else {
-        DEBUG(std::cerr << "Interference!\n");
       }
     }
   }


Index: llvm/lib/CodeGen/Passes.cpp
diff -u llvm/lib/CodeGen/Passes.cpp:1.15 llvm/lib/CodeGen/Passes.cpp:1.15.4.1
--- llvm/lib/CodeGen/Passes.cpp:1.15	Thu Apr 21 17:33:33 2005
+++ llvm/lib/CodeGen/Passes.cpp	Wed Nov 16 12:32:14 2005
@@ -18,7 +18,7 @@
 using namespace llvm;
 
 namespace {
-  enum RegAllocName { simple, local, linearscan, iterativescan };
+  enum RegAllocName { simple, local, linearscan };
 
   cl::opt<RegAllocName>
   RegAlloc(
@@ -29,7 +29,6 @@
        clEnumVal(simple,        "  simple register allocator"),
        clEnumVal(local,         "  local register allocator"),
        clEnumVal(linearscan,    "  linear scan register allocator"),
-       clEnumVal(iterativescan, "  iterative scan register allocator"),
        clEnumValEnd),
     cl::init(linearscan));
 }
@@ -45,8 +44,6 @@
     return createLocalRegisterAllocator();
   case linearscan:
     return createLinearScanRegisterAllocator();
-  case iterativescan:
-    return createIterativeScanRegisterAllocator();
   }
 }
 


Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp
diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.49 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.49.2.1
--- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.49	Fri Sep 30 12:19:22 2005
+++ llvm/lib/CodeGen/PrologEpilogInserter.cpp	Wed Nov 16 12:32:14 2005
@@ -258,6 +258,7 @@
   MachineFrameInfo *FFI = Fn.getFrameInfo();
 
   unsigned StackAlignment = TFI.getStackAlignment();
+  unsigned MaxAlign = 0;
 
   // Start at the beginning of the local area.
   // The Offset is the distance from the stack top in the direction
@@ -295,9 +296,11 @@
       Offset += FFI->getObjectSize(i);
 
     unsigned Align = FFI->getObjectAlignment(i);
-    assert(Align <= StackAlignment && "Cannot align stack object to higher "
-           "alignment boundary than the stack itself!");
-    Offset = (Offset+Align-1)/Align*Align;   // Adjust to Alignment boundary...
+    // If the alignment of this object is greater than that of the stack, then
+    // increase the stack alignment to match.
+    MaxAlign = std::max(MaxAlign, Align);
+    // Adjust to alignment boundary
+    Offset = (Offset+Align-1)/Align*Align;
 
     if (StackGrowsDown) {
       FFI->setObjectOffset(i, -Offset);        // Set the computed offset
@@ -315,6 +318,10 @@
 
   // Set the final value of the stack pointer...
   FFI->setStackSize(Offset+TFI.getOffsetOfLocalArea());
+
+  // Remember the required stack alignment in case targets need it to perform
+  // dynamic stack alignment.
+  FFI->setMaxAlignment(MaxAlign);
 }
 
 


Index: llvm/lib/CodeGen/RegAllocLocal.cpp
diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.74 llvm/lib/CodeGen/RegAllocLocal.cpp:1.74.2.1
--- llvm/lib/CodeGen/RegAllocLocal.cpp:1.74	Thu Sep 29 20:29:00 2005
+++ llvm/lib/CodeGen/RegAllocLocal.cpp	Wed Nov 16 12:32:14 2005
@@ -488,9 +488,11 @@
 
 void RA::AllocateBasicBlock(MachineBasicBlock &MBB) {
   // loop over each instruction
-  MachineBasicBlock::iterator MI = MBB.begin();
-  for (; MI != MBB.end(); ++MI) {
-    const TargetInstrDescriptor &TID = TM->getInstrInfo()->get(MI->getOpcode());
+  MachineBasicBlock::iterator MII = MBB.begin();
+  const TargetInstrInfo &TII = *TM->getInstrInfo();
+  while (MII != MBB.end()) {
+    MachineInstr *MI = MII++;
+    const TargetInstrDescriptor &TID = TII.get(MI->getOpcode());
     DEBUG(std::cerr << "\nStarting RegAlloc of: " << *MI;
           std::cerr << "  Regs have values: ";
           for (unsigned i = 0; i != RegInfo->getNumRegs(); ++i)
@@ -621,9 +623,14 @@
         removePhysReg(PhysReg);
       }
     }
+    
+    // Finally, if this is a noop copy instruction, zap it.
+    unsigned SrcReg, DstReg;
+    if (TII.isMoveInstr(*MI, SrcReg, DstReg) && SrcReg == DstReg)
+      MBB.erase(MI);
   }
 
-  MI = MBB.getFirstTerminator();
+  MachineBasicBlock::iterator MI = MBB.getFirstTerminator();
 
   // Spill all physical registers holding virtual registers now.
   for (unsigned i = 0, e = RegInfo->getNumRegs(); i != e; ++i)
@@ -633,7 +640,8 @@
       else
         removePhysReg(i);
 
-#ifndef NDEBUG
+#if 0
+  // This checking code is very expensive.
   bool AllOk = true;
   for (unsigned i = MRegisterInfo::FirstVirtualRegister,
            e = MF->getSSARegMap()->getLastVirtReg(); i <= e; ++i)


Index: llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
diff -u llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.30 llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.30.4.1
--- llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.30	Thu Apr 21 17:33:33 2005
+++ llvm/lib/CodeGen/TwoAddressInstructionPass.cpp	Wed Nov 16 12:32:14 2005
@@ -46,7 +46,7 @@
   Statistic<> NumTwoAddressInstrs("twoaddressinstruction",
                                   "Number of two-address instructions");
   Statistic<> NumCommuted("twoaddressinstruction",
-                          "Number of instructions commuted to coallesce");
+                          "Number of instructions commuted to coalesce");
   Statistic<> NumConvertedTo3Addr("twoaddressinstruction",
                                 "Number of instructions promoted to 3-address");
 
@@ -127,7 +127,7 @@
 
         // If this instruction is not the killing user of B, see if we can
         // rearrange the code to make it so.  Making it the killing user will
-        // allow us to coallesce A and B together, eliminating the copy we are
+        // allow us to coalesce A and B together, eliminating the copy we are
         // about to insert.
         if (!LV.KillsRegister(mi, regB)) {
           const TargetInstrDescriptor &TID = TII.get(opcode);






More information about the llvm-commits mailing list