[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