aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/VirtRegMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/VirtRegMap.cpp')
-rw-r--r--lib/CodeGen/VirtRegMap.cpp108
1 files changed, 70 insertions, 38 deletions
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp
index c6ac4b208d..ebdbb86c2b 100644
--- a/lib/CodeGen/VirtRegMap.cpp
+++ b/lib/CodeGen/VirtRegMap.cpp
@@ -242,10 +242,12 @@ namespace {
/// blocks that have low register pressure (the vreg may be spilled due to
/// register pressure in other blocks).
class VISIBILITY_HIDDEN LocalSpiller : public Spiller {
+ SSARegMap *RegMap;
const MRegisterInfo *MRI;
const TargetInstrInfo *TII;
public:
bool runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM) {
+ RegMap = MF.getSSARegMap();
MRI = MF.getTarget().getRegisterInfo();
TII = MF.getTarget().getInstrInfo();
DOUT << "\n**** Local spiller rewriting function '"
@@ -776,25 +778,33 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
if (!MO.isRegister() || MO.getReg() == 0)
continue; // Ignore non-register operands.
- if (MRegisterInfo::isPhysicalRegister(MO.getReg())) {
+ unsigned VirtReg = MO.getReg();
+ if (MRegisterInfo::isPhysicalRegister(VirtReg)) {
// Ignore physregs for spilling, but remember that it is used by this
// function.
- MF.setPhysRegUsed(MO.getReg());
- ReusedOperands.markClobbered(MO.getReg());
+ MF.setPhysRegUsed(VirtReg);
+ ReusedOperands.markClobbered(VirtReg);
continue;
}
- assert(MRegisterInfo::isVirtualRegister(MO.getReg()) &&
+ assert(MRegisterInfo::isVirtualRegister(VirtReg) &&
"Not a virtual or a physical register?");
- unsigned VirtReg = MO.getReg();
+ unsigned SubIdx = 0;
+ bool isSubReg = RegMap->isSubRegister(VirtReg);
+ if (isSubReg) {
+ SubIdx = RegMap->getSubRegisterIndex(VirtReg);
+ VirtReg = RegMap->getSuperRegister(VirtReg);
+ }
+
if (VRM.isAssignedReg(VirtReg)) {
// This virtual register was assigned a physreg!
unsigned Phys = VRM.getPhys(VirtReg);
MF.setPhysRegUsed(Phys);
if (MO.isDef())
ReusedOperands.markClobbered(Phys);
- MI.getOperand(i).setReg(Phys);
+ unsigned RReg = isSubReg ? MRI->getSubReg(Phys, SubIdx) : Phys;
+ MI.getOperand(i).setReg(RReg);
continue;
}
@@ -817,6 +827,24 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
if (ReuseSlot != VirtRegMap::NO_STACK_SLOT)
PhysReg = Spills.getSpillSlotOrReMatPhysReg(ReuseSlot);
}
+
+ // If this is a sub-register use, make sure the reuse register is in the
+ // right register class. For example, for x86 not all of the 32-bit
+ // registers have accessible sub-registers.
+ // Similarly so for EXTRACT_SUBREG. Consider this:
+ // EDI = op
+ // MOV32_mr fi#1, EDI
+ // ...
+ // = EXTRACT_SUBREG fi#1
+ // fi#1 is available in EDI, but it cannot be reused because it's not in
+ // the right register file.
+ if (PhysReg &&
+ (isSubReg || MI.getOpcode() == TargetInstrInfo::EXTRACT_SUBREG)) {
+ const TargetRegisterClass* RC = RegMap->getRegClass(VirtReg);
+ if (!RC->contains(PhysReg))
+ PhysReg = 0;
+ }
+
if (PhysReg) {
// This spilled operand might be part of a two-address operand. If this
// is the case, then changing it will necessarily require changing the
@@ -824,6 +852,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
// aren't allowed to modify the reused register. If none of these cases
// apply, reuse it.
bool CanReuse = true;
+
int ti = TID->getOperandConstraint(i, TOI::TIED_TO);
if (ti != -1 &&
MI.getOperand(ti).isRegister() &&
@@ -845,7 +874,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
<< MRI->getName(PhysReg) << " for vreg"
<< VirtReg <<" instead of reloading into physreg "
<< MRI->getName(VRM.getPhys(VirtReg)) << "\n";
- MI.getOperand(i).setReg(PhysReg);
+ unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
+ MI.getOperand(i).setReg(RReg);
// The only technical detail we have is that we don't know that
// PhysReg won't be clobbered by a reloaded stack slot that occurs
@@ -883,7 +913,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
}
}
continue;
- }
+ } // CanReuse
// Otherwise we have a situation where we have a two-address instruction
// whose mod/ref operand needs to be reloaded. This reload is already
@@ -917,13 +947,14 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
DOUT << " from physreg " << MRI->getName(PhysReg) << " for vreg"
<< VirtReg
<< " instead of reloading into same physreg.\n";
- MI.getOperand(i).setReg(PhysReg);
+ unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
+ MI.getOperand(i).setReg(RReg);
ReusedOperands.markClobbered(PhysReg);
++NumReused;
continue;
}
- const TargetRegisterClass* RC = MF.getSSARegMap()->getRegClass(VirtReg);
+ const TargetRegisterClass* RC = RegMap->getRegClass(VirtReg);
MF.setPhysRegUsed(DesignatedReg);
ReusedOperands.markClobbered(DesignatedReg);
MRI->copyRegToReg(MBB, &MI, DesignatedReg, PhysReg, RC, RC);
@@ -935,16 +966,17 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
Spills.ClobberPhysReg(DesignatedReg);
Spills.addAvailable(ReuseSlot, &MI, DesignatedReg);
- MI.getOperand(i).setReg(DesignatedReg);
+ unsigned RReg =
+ isSubReg ? MRI->getSubReg(DesignatedReg, SubIdx) : DesignatedReg;
+ MI.getOperand(i).setReg(RReg);
DOUT << '\t' << *prior(MII);
++NumReused;
continue;
- }
+ } // is (PhysReg)
// Otherwise, reload it and remember that we have it.
PhysReg = VRM.getPhys(VirtReg);
assert(PhysReg && "Must map virtreg to physreg!");
- const TargetRegisterClass* RC = MF.getSSARegMap()->getRegClass(VirtReg);
// Note that, if we reused a register for a previous operand, the
// register we want to reload into might not actually be
@@ -960,6 +992,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
MRI->reMaterialize(MBB, &MI, PhysReg, VRM.getReMaterializedMI(VirtReg));
++NumReMats;
} else {
+ const TargetRegisterClass* RC = RegMap->getRegClass(VirtReg);
MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, SSorRMId, RC);
++NumLoads;
}
@@ -974,7 +1007,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
// unless it's a two-address operand.
if (TID->getOperandConstraint(i, TOI::TIED_TO) == -1)
MI.getOperand(i).setIsKill();
- MI.getOperand(i).setReg(PhysReg);
+ unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
+ MI.getOperand(i).setReg(RReg);
UpdateKills(*prior(MII), RegKills, KillOps);
DOUT << '\t' << *prior(MII);
}
@@ -1002,30 +1036,28 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
// straight load from the virt reg slot.
if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) {
int FrameIdx;
- if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
- if (FrameIdx == SS) {
- // If this spill slot is available, turn it into a copy (or nothing)
- // instead of leaving it as a load!
- if (unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SS)) {
- DOUT << "Promoted Load To Copy: " << MI;
- if (DestReg != InReg) {
- const TargetRegisterClass *RC =
- MF.getSSARegMap()->getRegClass(VirtReg);
- MRI->copyRegToReg(MBB, &MI, DestReg, InReg, RC, RC);
- // Revisit the copy so we make sure to notice the effects of the
- // operation on the destreg (either needing to RA it if it's
- // virtual or needing to clobber any values if it's physical).
- NextMII = &MI;
- --NextMII; // backtrack to the copy.
- BackTracked = true;
- } else
- DOUT << "Removing now-noop copy: " << MI;
+ unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx);
+ if (DestReg && FrameIdx == SS) {
+ // If this spill slot is available, turn it into a copy (or nothing)
+ // instead of leaving it as a load!
+ if (unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SS)) {
+ DOUT << "Promoted Load To Copy: " << MI;
+ if (DestReg != InReg) {
+ const TargetRegisterClass *RC = RegMap->getRegClass(VirtReg);
+ MRI->copyRegToReg(MBB, &MI, DestReg, InReg, RC, RC);
+ // Revisit the copy so we make sure to notice the effects of the
+ // operation on the destreg (either needing to RA it if it's
+ // virtual or needing to clobber any values if it's physical).
+ NextMII = &MI;
+ --NextMII; // backtrack to the copy.
+ BackTracked = true;
+ } else
+ DOUT << "Removing now-noop copy: " << MI;
- VRM.RemoveFromFoldedVirtMap(&MI);
- MBB.erase(&MI);
- Erased = true;
- goto ProcessNextInst;
- }
+ VRM.RemoveFromFoldedVirtMap(&MI);
+ MBB.erase(&MI);
+ Erased = true;
+ goto ProcessNextInst;
}
}
}
@@ -1121,7 +1153,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
// The only vregs left are stack slot definitions.
int StackSlot = VRM.getStackSlot(VirtReg);
- const TargetRegisterClass *RC = MF.getSSARegMap()->getRegClass(VirtReg);
+ const TargetRegisterClass *RC = RegMap->getRegClass(VirtReg);
// If this def is part of a two-address operand, make sure to execute
// the store from the correct physical register.