aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-07-01 08:19:36 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-07-01 08:19:36 +0000
commit459a7c6b6ad9c4fcb9f119aa6eaaf2769b00d9b1 (patch)
tree006dc09ed750a6cf80ca8dbd944db91063491f3e /lib
parentd6bb283de9f81428762f13b7f6bae31adaba5768 (diff)
Remove special handling of implicit_def. Fix a couple more bugs in liveintervalanalysis and coalescer handling of implicit_def.
Note, isUndef marker must be placed even on implicit_def def operand or else the scavenger will not ignore it. This is necessary because -O0 path does not use liveintervalanalysis, it treats implicit_def just like any other def. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74601 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp75
-rw-r--r--lib/CodeGen/RegisterScavenging.cpp31
-rw-r--r--lib/CodeGen/SimpleRegisterCoalescing.cpp19
3 files changed, 74 insertions, 51 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 9339c951a8..52a30bc067 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -124,7 +124,9 @@ void LiveIntervals::processImplicitDefs() {
ImpDefMIs.push_back(MI);
continue;
}
- for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
+
+ bool ChangedToImpDef = false;
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand& MO = MI->getOperand(i);
if (!MO.isReg() || !MO.isUse())
continue;
@@ -133,16 +135,35 @@ void LiveIntervals::processImplicitDefs() {
continue;
if (!ImpDefRegs.count(Reg))
continue;
+ // Use is a copy, just turn it into an implicit_def.
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+ if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
+ Reg == SrcReg) {
+ bool isKill = MO.isKill();
+ MI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
+ for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j)
+ MI->RemoveOperand(j);
+ if (isKill)
+ ImpDefRegs.erase(Reg);
+ ChangedToImpDef = true;
+ break;
+ }
+
MO.setIsUndef();
if (MO.isKill() || MI->isRegTiedToDefOperand(i))
ImpDefRegs.erase(Reg);
}
- for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
- MachineOperand& MO = MI->getOperand(i);
- if (!MO.isReg() || !MO.isDef())
- continue;
- ImpDefRegs.erase(MO.getReg());
+ if (ChangedToImpDef) {
+ // Backtrack to process this new implicit_def.
+ --I;
+ } else {
+ for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
+ MachineOperand& MO = MI->getOperand(i);
+ if (!MO.isReg() || !MO.isDef())
+ continue;
+ ImpDefRegs.erase(MO.getReg());
+ }
}
}
@@ -155,33 +176,39 @@ void LiveIntervals::processImplicitDefs() {
continue;
if (!ImpDefRegs.count(Reg))
continue;
- bool HasLocalUse = false;
- for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(Reg),
- RE = mri_->reg_end(); RI != RE; ) {
- MachineOperand &RMO = RI.getOperand();
- MachineInstr *RMI = &*RI;
- ++RI;
- if (RMO.isDef()) {
- // Don't expect another def of the same register.
- assert(RMI == MI &&
- "Register with multiple defs including an implicit_def?");
- continue;
+
+ // If there are multiple defs of the same register and at least one
+ // is not an implicit_def, do not insert implicit_def's before the
+ // uses.
+ bool Skip = false;
+ for (MachineRegisterInfo::def_iterator DI = mri_->def_begin(Reg),
+ DE = mri_->def_end(); DI != DE; ++DI) {
+ if (DI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF) {
+ Skip = true;
+ break;
}
+ }
+ if (Skip)
+ continue;
+
+ for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg),
+ UE = mri_->use_end(); UI != UE; ) {
+ MachineOperand &RMO = UI.getOperand();
+ MachineInstr *RMI = &*UI;
+ ++UI;
MachineBasicBlock *RMBB = RMI->getParent();
- if (RMBB == MBB) {
- HasLocalUse = true;
+ if (RMBB == MBB)
continue;
- }
const TargetRegisterClass* RC = mri_->getRegClass(Reg);
unsigned NewVReg = mri_->createVirtualRegister(RC);
- BuildMI(*RMBB, RMI, RMI->getDebugLoc(),
- tii_->get(TargetInstrInfo::IMPLICIT_DEF), NewVReg);
+ MachineInstrBuilder MIB =
+ BuildMI(*RMBB, RMI, RMI->getDebugLoc(),
+ tii_->get(TargetInstrInfo::IMPLICIT_DEF), NewVReg);
+ (*MIB).getOperand(0).setIsUndef();
RMO.setReg(NewVReg);
RMO.setIsUndef();
RMO.setIsKill();
}
- if (!HasLocalUse)
- MI->eraseFromParent();
}
ImpDefRegs.clear();
ImpDefMIs.clear();
diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp
index 58f4284ac7..d7fe7a2d54 100644
--- a/lib/CodeGen/RegisterScavenging.cpp
+++ b/lib/CodeGen/RegisterScavenging.cpp
@@ -57,28 +57,22 @@ static bool RedefinesSuperRegPart(const MachineInstr *MI,
}
/// setUsed - Set the register and its sub-registers as being used.
-void RegScavenger::setUsed(unsigned Reg, bool ImpDef) {
+void RegScavenger::setUsed(unsigned Reg) {
RegsAvailable.reset(Reg);
- ImplicitDefed[Reg] = ImpDef;
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
- unsigned SubReg = *SubRegs; ++SubRegs) {
+ unsigned SubReg = *SubRegs; ++SubRegs)
RegsAvailable.reset(SubReg);
- ImplicitDefed[SubReg] = ImpDef;
- }
}
/// setUnused - Set the register and its sub-registers as being unused.
void RegScavenger::setUnused(unsigned Reg, const MachineInstr *MI) {
RegsAvailable.set(Reg);
- ImplicitDefed.reset(Reg);
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
unsigned SubReg = *SubRegs; ++SubRegs)
- if (!RedefinesSuperRegPart(MI, Reg, TRI)) {
+ if (!RedefinesSuperRegPart(MI, Reg, TRI))
RegsAvailable.set(SubReg);
- ImplicitDefed.reset(SubReg);
- }
}
void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
@@ -94,7 +88,6 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
if (!MBB) {
NumPhysRegs = TRI->getNumRegs();
RegsAvailable.resize(NumPhysRegs);
- ImplicitDefed.resize(NumPhysRegs);
// Create reserved registers bitvector.
ReservedRegs = TRI->getReservedRegs(MF);
@@ -113,7 +106,6 @@ void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) {
ScavengeRestore = NULL;
CurrDist = 0;
DistanceMap.clear();
- ImplicitDefed.reset();
// All registers started out unused.
RegsAvailable.set();
@@ -195,7 +187,10 @@ void RegScavenger::forward() {
ScavengeRestore = NULL;
}
- bool IsImpDef = MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF;
+#if 0
+ if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
+ return;
+#endif
// Separate register operands into 3 classes: uses, defs, earlyclobbers.
SmallVector<std::pair<const MachineOperand*,unsigned>, 4> UseMOs;
@@ -221,14 +216,7 @@ void RegScavenger::forward() {
assert(isUsed(Reg) && "Using an undefined register!");
- // Kill of implicit_def defined registers are ignored. e.g.
- // entry: 0x2029ab8, LLVM BB @0x1b06080, ID#0:
- // Live Ins: %R0
- // %R0<def> = IMPLICIT_DEF
- // %R0<def> = IMPLICIT_DEF
- // STR %R0<kill>, %R0, %reg0, 0, 14, %reg0, Mem:ST(4,4) [0x1b06510 + 0]
- // %R1<def> = LDR %R0, %reg0, 24, 14, %reg0, Mem:LD(4,4) [0x1b065bc + 0]
- if (MO.isKill() && !isReserved(Reg) && !isImplicitlyDefined(Reg)) {
+ if (MO.isKill() && !isReserved(Reg)) {
KillRegs.set(Reg);
// Mark sub-registers as used.
@@ -278,10 +266,9 @@ void RegScavenger::forward() {
// Implicit def is allowed to "re-define" any register. Similarly,
// implicitly defined registers can be clobbered.
assert((isReserved(Reg) || isUnused(Reg) ||
- IsImpDef || isImplicitlyDefined(Reg) ||
isLiveInButUnusedBefore(Reg, MI, MBB, TRI, MRI)) &&
"Re-defining a live register!");
- setUsed(Reg, IsImpDef);
+ setUsed(Reg);
}
}
diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp
index c2105e617b..7e7d6b8f68 100644
--- a/lib/CodeGen/SimpleRegisterCoalescing.cpp
+++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp
@@ -2669,19 +2669,28 @@ SimpleRegisterCoalescing::TurnCopyIntoImpDef(MachineBasicBlock::iterator &I,
CopyMI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
for (int i = CopyMI->getNumOperands() - 1, e = 0; i > e; --i)
CopyMI->RemoveOperand(i);
+ CopyMI->getOperand(0).setIsUndef();
bool NoUse = mri_->use_empty(SrcReg);
if (NoUse) {
- for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(SrcReg),
- E = mri_->reg_end(); I != E; ) {
- assert(I.getOperand().isDef());
- MachineInstr *DefMI = &*I;
- ++I;
+ for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(SrcReg),
+ RE = mri_->reg_end(); RI != RE; ) {
+ assert(RI.getOperand().isDef());
+ MachineInstr *DefMI = &*RI;
+ ++RI;
// The implicit_def source has no other uses, delete it.
assert(DefMI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF);
li_->RemoveMachineInstrFromMaps(DefMI);
DefMI->eraseFromParent();
}
}
+
+ // Mark uses of implicit_def isUndef.
+ for (MachineRegisterInfo::use_iterator RI = mri_->use_begin(DstReg),
+ RE = mri_->use_end(); RI != RE; ++RI) {
+ assert((*RI).getParent() == MBB);
+ RI.getOperand().setIsUndef();
+ }
+
++I;
return true;
}