aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/LiveIntervalAnalysis.cpp
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/CodeGen/LiveIntervalAnalysis.cpp
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/CodeGen/LiveIntervalAnalysis.cpp')
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp75
1 files changed, 51 insertions, 24 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();