aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2007-11-02 17:35:08 +0000
committerEvan Cheng <evan.cheng@apple.com>2007-11-02 17:35:08 +0000
commita1b89c2ad478ffac5e84a0323e451b8bf8322ba7 (patch)
treef80776d3b3e4593908bef8c667d73e2756f68b70 /lib/CodeGen
parente7037c26b6ea939dbb9df9bf655ac4ea8232c23d (diff)
downloadexternal_llvm-a1b89c2ad478ffac5e84a0323e451b8bf8322ba7.zip
external_llvm-a1b89c2ad478ffac5e84a0323e451b8bf8322ba7.tar.gz
external_llvm-a1b89c2ad478ffac5e84a0323e451b8bf8322ba7.tar.bz2
One more extract_subreg coalescing bug.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43644 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/VirtRegMap.cpp38
1 files changed, 33 insertions, 5 deletions
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp
index f8a104f..9f5d33f 100644
--- a/lib/CodeGen/VirtRegMap.cpp
+++ b/lib/CodeGen/VirtRegMap.cpp
@@ -835,6 +835,19 @@ bool LocalSpiller::PrepForUnfoldOpti(MachineBasicBlock &MBB,
return false;
}
+/// findSuperReg - Find the SubReg's super-register of given register class
+/// where its SubIdx sub-register is SubReg.
+static unsigned findSuperReg(const TargetRegisterClass *RC, unsigned SubReg,
+ unsigned SubIdx, const MRegisterInfo *MRI) {
+ for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end();
+ I != E; ++I) {
+ unsigned Reg = *I;
+ if (MRI->getSubReg(Reg, SubIdx) == SubReg)
+ return Reg;
+ }
+ return 0;
+}
+
/// rewriteMBB - Keep track of which spills are available even after the
/// register allocator is done with them. If possible, avoid reloading vregs.
void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
@@ -1056,7 +1069,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
<< " instead of reloading into same physreg.\n";
unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
MI.getOperand(i).setReg(RReg);
- ReusedOperands.markClobbered(PhysReg);
+ ReusedOperands.markClobbered(RReg);
++NumReused;
continue;
}
@@ -1295,6 +1308,13 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
continue;
}
+ unsigned SubIdx = 0;
+ bool isSubReg = RegMap->isSubRegister(VirtReg);
+ if (isSubReg) {
+ SubIdx = RegMap->getSubRegisterIndex(VirtReg);
+ VirtReg = RegMap->getSuperRegister(VirtReg);
+ }
+
bool DoReMat = VRM.isReMaterialized(VirtReg);
if (DoReMat)
ReMatDefs.insert(&MI);
@@ -1307,9 +1327,15 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
// the store from the correct physical register.
unsigned PhysReg;
int TiedOp = MI.getInstrDescriptor()->findTiedToSrcOperand(i);
- if (TiedOp != -1)
+ if (TiedOp != -1) {
PhysReg = MI.getOperand(TiedOp).getReg();
- else {
+ if (isSubReg) {
+ unsigned SuperReg = findSuperReg(RC, PhysReg, SubIdx, MRI);
+ assert(SuperReg && MRI->getSubReg(SuperReg, SubIdx) == PhysReg &&
+ "Can't find corresponding super-register!");
+ PhysReg = SuperReg;
+ }
+ } else {
PhysReg = VRM.getPhys(VirtReg);
if (ReusedOperands.isClobbered(PhysReg)) {
// Another def has taken the assigned physreg. It must have been a
@@ -1320,8 +1346,10 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
}
MF.setPhysRegUsed(PhysReg);
- ReusedOperands.markClobbered(PhysReg);
- MI.getOperand(i).setReg(PhysReg);
+ unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
+ ReusedOperands.markClobbered(RReg);
+ MI.getOperand(i).setReg(RReg);
+
if (!MO.isDead()) {
MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC);
DOUT << "Store:\t" << *next(MII);