[llvm-commits] [llvm] r49542 - in /llvm/trunk: include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/VirtRegMap.cpp lib/CodeGen/VirtRegMap.h
Evan Cheng
evan.cheng at apple.com
Fri Apr 11 10:53:36 PDT 2008
Author: evancheng
Date: Fri Apr 11 12:53:36 2008
New Revision: 49542
URL: http://llvm.org/viewvc/llvm-project?rev=49542&view=rev
Log:
Use of implicit_def is not part of live interval. Create empty intervals for the uses when the live interval is being spilled.
Modified:
llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h
llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
llvm/trunk/lib/CodeGen/VirtRegMap.cpp
llvm/trunk/lib/CodeGen/VirtRegMap.h
Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=49542&r1=49541&r2=49542&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original)
+++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Fri Apr 11 12:53:36 2008
@@ -394,9 +394,11 @@
BitVector &RestoreMBBs,
std::map<unsigned,std::vector<SRInfo> >&RestoreIdxes);
- /// removeSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
- /// spilled.
- void removeSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm);
+ /// handleSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
+ /// spilled and create empty intervals for their uses.
+ void handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm,
+ const TargetRegisterClass* rc,
+ std::vector<LiveInterval*> &NewLIs);
/// rewriteImplicitOps - Rewrite implicit use operands of MI (i.e. uses of
/// interval on to-be re-materialized operands of MI) with new register.
Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=49542&r1=49541&r2=49542&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Fri Apr 11 12:53:36 2008
@@ -1319,19 +1319,37 @@
Restores[i].index = -1;
}
-/// removeSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
-/// spilled.
-void LiveIntervals::removeSpilledImpDefs(const LiveInterval &li,
- VirtRegMap &vrm) {
+/// handleSpilledImpDefs - Remove IMPLICIT_DEF instructions which are being
+/// spilled and create empty intervals for their uses.
+void
+LiveIntervals::handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm,
+ const TargetRegisterClass* rc,
+ std::vector<LiveInterval*> &NewLIs) {
for (MachineRegisterInfo::reg_iterator ri = mri_->reg_begin(li.reg),
re = mri_->reg_end(); ri != re; ) {
+ MachineOperand &O = ri.getOperand();
MachineInstr *MI = &*ri;
++ri;
- if (MI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF)
- continue;
- RemoveMachineInstrFromMaps(MI);
- vrm.RemoveMachineInstrFromMaps(MI);
- MI->eraseFromParent();
+ if (O.isDef()) {
+ assert(MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF &&
+ "Register def was not rewritten?");
+ RemoveMachineInstrFromMaps(MI);
+ vrm.RemoveMachineInstrFromMaps(MI);
+ MI->eraseFromParent();
+ } else {
+ // This must be an use of an implicit_def so it's not part of the live
+ // interval. Create a new empty live interval for it.
+ // FIXME: Can we simply erase some of the instructions? e.g. Stores?
+ unsigned NewVReg = mri_->createVirtualRegister(rc);
+ vrm.grow();
+ vrm.setIsImplicitlyDefined(NewVReg);
+ NewLIs.push_back(&getOrCreateInterval(NewVReg));
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (MO.isReg() && MO.getReg() == li.reg)
+ MO.setReg(NewVReg);
+ }
+ }
}
}
@@ -1415,7 +1433,7 @@
IsFirstRange = false;
}
- removeSpilledImpDefs(li, vrm);
+ handleSpilledImpDefs(li, vrm, rc, NewLIs);
return NewLIs;
}
@@ -1485,7 +1503,7 @@
// Insert spills / restores if we are splitting.
if (!TrySplit) {
- removeSpilledImpDefs(li, vrm);
+ handleSpilledImpDefs(li, vrm, rc, NewLIs);
return NewLIs;
}
@@ -1640,7 +1658,7 @@
}
}
- removeSpilledImpDefs(li, vrm);
+ handleSpilledImpDefs(li, vrm, rc, RetNewLIs);
return RetNewLIs;
}
Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=49542&r1=49541&r2=49542&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original)
+++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Fri Apr 11 12:53:36 2008
@@ -21,6 +21,7 @@
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
@@ -69,6 +70,8 @@
Virt2SplitKillMap(0), ReMatMap(NULL), ReMatId(MAX_STACK_SLOT+1),
LowSpillSlot(NO_STACK_SLOT), HighSpillSlot(NO_STACK_SLOT) {
SpillSlotToUsesMap.resize(8);
+ ImplicitDefed.resize(MF.getRegInfo().getLastVirtReg()+1-
+ TargetRegisterInfo::FirstVirtualRegister);
grow();
}
@@ -80,6 +83,7 @@
Virt2SplitMap.grow(LastVirtReg);
Virt2SplitKillMap.grow(LastVirtReg);
ReMatMap.grow(LastVirtReg);
+ ImplicitDefed.resize(LastVirtReg-TargetRegisterInfo::FirstVirtualRegister+1);
}
int VirtRegMap::assignVirt2StackSlot(unsigned virtReg) {
@@ -1155,6 +1159,8 @@
// We want to process implicit virtual register uses first.
if (MO.isImplicit())
+ // If the virtual register is implicitly defined, emit a implicit_def
+ // before so scavenger knows it's "defined".
VirtUseOps.insert(VirtUseOps.begin(), i);
else
VirtUseOps.push_back(i);
@@ -1177,6 +1183,8 @@
ReusedOperands.markClobbered(Phys);
unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys;
MI.getOperand(i).setReg(RReg);
+ if (VRM.isImplicitlyDefined(VirtReg))
+ BuildMI(MBB, MI, TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg);
continue;
}
Modified: llvm/trunk/lib/CodeGen/VirtRegMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.h?rev=49542&r1=49541&r2=49542&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/VirtRegMap.h (original)
+++ llvm/trunk/lib/CodeGen/VirtRegMap.h Fri Apr 11 12:53:36 2008
@@ -18,6 +18,7 @@
#define LLVM_CODEGEN_VIRTREGMAP_H
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -116,6 +117,10 @@
/// SpillSlotToUsesMap - Records uses for each register spill slot.
SmallVector<SmallPtrSet<MachineInstr*, 4>, 8> SpillSlotToUsesMap;
+ /// ImplicitDefed - One bit for each virtual register. If set it indicates
+ /// the register is implicitly defined.
+ BitVector ImplicitDefed;
+
VirtRegMap(const VirtRegMap&); // DO NOT IMPLEMENT
void operator=(const VirtRegMap&); // DO NOT IMPLEMENT
@@ -382,6 +387,16 @@
return !SpillSlotToUsesMap[FrameIndex-LowSpillSlot].empty();
}
+ /// @brief Mark the specified register as being implicitly defined.
+ void setIsImplicitlyDefined(unsigned VirtReg) {
+ ImplicitDefed.set(VirtReg-TargetRegisterInfo::FirstVirtualRegister);
+ }
+
+ /// @brief Returns true if the virtual register is implicitly defined.
+ bool isImplicitlyDefined(unsigned VirtReg) const {
+ return ImplicitDefed[VirtReg-TargetRegisterInfo::FirstVirtualRegister];
+ }
+
/// @brief Updates information about the specified virtual register's value
/// folded into newMI machine instruction.
void virtFolded(unsigned VirtReg, MachineInstr *OldMI, MachineInstr *NewMI,
More information about the llvm-commits
mailing list