mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-02 07:32:52 +00:00
Clean up sub-register implementation by moving subReg information back to
MachineOperand auxInfo. Previous clunky implementation uses an external map to track sub-register uses. That works because register allocator uses a new virtual register for each spilled use. With interval splitting (coming soon), we may have multiple uses of the same register some of which are of using different sub-registers from others. It's too fragile to constantly update the information. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44104 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f9572a4c2b
commit
c498b0281f
@ -76,6 +76,10 @@ private:
|
||||
/// offset - Offset to address of global or external, only valid for
|
||||
/// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
|
||||
int offset;
|
||||
|
||||
/// subReg - SubRegister number, only valid for MO_Register. A value of 0
|
||||
/// indicates the MO_Register has no subReg.
|
||||
unsigned subReg;
|
||||
} auxInfo;
|
||||
|
||||
MachineOperand() {}
|
||||
@ -182,6 +186,10 @@ public:
|
||||
"Wrong MachineOperand accessor");
|
||||
return auxInfo.offset;
|
||||
}
|
||||
unsigned getSubReg() const {
|
||||
assert(isRegister() && "Wrong MachineOperand accessor");
|
||||
return auxInfo.subReg;
|
||||
}
|
||||
const char *getSymbolName() const {
|
||||
assert(isExternalSymbol() && "Wrong MachineOperand accessor");
|
||||
return contents.SymbolName;
|
||||
@ -267,6 +275,10 @@ public:
|
||||
"Wrong MachineOperand accessor");
|
||||
auxInfo.offset = Offset;
|
||||
}
|
||||
void setSubReg(unsigned subReg) {
|
||||
assert(isRegister() && "Wrong MachineOperand accessor");
|
||||
auxInfo.subReg = subReg;
|
||||
}
|
||||
void setConstantPoolIndex(unsigned Idx) {
|
||||
assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
|
||||
contents.immedVal = Idx;
|
||||
@ -451,7 +463,8 @@ public:
|
||||
/// addRegOperand - Add a register operand.
|
||||
///
|
||||
void addRegOperand(unsigned Reg, bool IsDef, bool IsImp = false,
|
||||
bool IsKill = false, bool IsDead = false) {
|
||||
bool IsKill = false, bool IsDead = false,
|
||||
unsigned SubReg = 0) {
|
||||
MachineOperand &Op = AddNewOperand(IsImp);
|
||||
Op.opType = MachineOperand::MO_Register;
|
||||
Op.IsDef = IsDef;
|
||||
@ -459,6 +472,7 @@ public:
|
||||
Op.IsKill = IsKill;
|
||||
Op.IsDead = IsDead;
|
||||
Op.contents.RegNo = Reg;
|
||||
Op.auxInfo.subReg = SubReg;
|
||||
}
|
||||
|
||||
/// addImmOperand - Add a zero extended constant argument to the
|
||||
|
@ -39,8 +39,8 @@ public:
|
||||
const
|
||||
MachineInstrBuilder &addReg(unsigned RegNo, bool isDef = false,
|
||||
bool isImp = false, bool isKill = false,
|
||||
bool isDead = false) const {
|
||||
MI->addRegOperand(RegNo, isDef, isImp, isKill, isDead);
|
||||
bool isDead = false, unsigned SubReg = 0) const {
|
||||
MI->addRegOperand(RegNo, isDef, isImp, isKill, isDead, SubReg);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@ class TargetRegisterClass;
|
||||
|
||||
class SSARegMap {
|
||||
IndexedMap<const TargetRegisterClass*, VirtReg2IndexFunctor> RegClassMap;
|
||||
IndexedMap<std::pair<unsigned, unsigned>, VirtReg2IndexFunctor> RegSubIdxMap;
|
||||
unsigned NextRegNum;
|
||||
|
||||
public:
|
||||
@ -43,30 +42,12 @@ class SSARegMap {
|
||||
assert(RegClass && "Cannot create register without RegClass!");
|
||||
RegClassMap.grow(NextRegNum);
|
||||
RegClassMap[NextRegNum] = RegClass;
|
||||
RegSubIdxMap.grow(NextRegNum);
|
||||
RegSubIdxMap[NextRegNum] = std::make_pair(0,0);
|
||||
return NextRegNum++;
|
||||
}
|
||||
|
||||
unsigned getLastVirtReg() const {
|
||||
return NextRegNum - 1;
|
||||
}
|
||||
|
||||
void setIsSubRegister(unsigned Reg, unsigned SuperReg, unsigned SubIdx) {
|
||||
RegSubIdxMap[Reg] = std::make_pair(SuperReg, SubIdx);
|
||||
}
|
||||
|
||||
bool isSubRegister(unsigned Reg) const {
|
||||
return RegSubIdxMap[Reg].first != 0;
|
||||
}
|
||||
|
||||
unsigned getSuperRegister(unsigned Reg) const {
|
||||
return RegSubIdxMap[Reg].first;
|
||||
}
|
||||
|
||||
unsigned getSubRegisterIndex(unsigned Reg) const {
|
||||
return RegSubIdxMap[Reg].second;
|
||||
}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -670,12 +670,8 @@ rewriteInstructionForSpills(const LiveInterval &li,
|
||||
unsigned RegI = Reg;
|
||||
if (Reg == 0 || MRegisterInfo::isPhysicalRegister(Reg))
|
||||
continue;
|
||||
bool isSubReg = RegMap->isSubRegister(Reg);
|
||||
unsigned SubIdx = 0;
|
||||
if (isSubReg) {
|
||||
SubIdx = RegMap->getSubRegisterIndex(Reg);
|
||||
Reg = RegMap->getSuperRegister(Reg);
|
||||
}
|
||||
unsigned SubIdx = mop.getSubReg();
|
||||
bool isSubReg = SubIdx != 0;
|
||||
if (Reg != li.reg)
|
||||
continue;
|
||||
|
||||
@ -710,8 +706,6 @@ rewriteInstructionForSpills(const LiveInterval &li,
|
||||
// Create a new virtual register for the spill interval.
|
||||
unsigned NewVReg = RegMap->createVirtualRegister(rc);
|
||||
vrm.grow();
|
||||
if (isSubReg)
|
||||
RegMap->setIsSubRegister(NewVReg, NewVReg, SubIdx);
|
||||
|
||||
// Scan all of the operands of this instruction rewriting operands
|
||||
// to use NewVReg instead of li.reg as appropriate. We do this for
|
||||
|
@ -39,6 +39,7 @@ void MachineInstr::addImplicitDefUseOperands() {
|
||||
Op.IsKill = false;
|
||||
Op.IsDead = false;
|
||||
Op.contents.RegNo = *ImpDefs;
|
||||
Op.auxInfo.subReg = 0;
|
||||
Operands.push_back(Op);
|
||||
}
|
||||
if (TID->ImplicitUses)
|
||||
@ -50,6 +51,7 @@ void MachineInstr::addImplicitDefUseOperands() {
|
||||
Op.IsKill = false;
|
||||
Op.IsDead = false;
|
||||
Op.contents.RegNo = *ImpUses;
|
||||
Op.auxInfo.subReg = 0;
|
||||
Operands.push_back(Op);
|
||||
}
|
||||
}
|
||||
|
@ -1387,6 +1387,7 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
|
||||
r2rRevMap_.grow(RegMap->getLastVirtReg());
|
||||
|
||||
// Join (coalesce) intervals if requested.
|
||||
IndexedMap<unsigned, VirtReg2IndexFunctor> RegSubIdxMap;
|
||||
if (EnableJoining) {
|
||||
joinIntervals();
|
||||
DOUT << "********** INTERVALS POST JOINING **********\n";
|
||||
@ -1404,10 +1405,11 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
|
||||
|
||||
// Transfer sub-registers info to SSARegMap now that coalescing information
|
||||
// is complete.
|
||||
RegSubIdxMap.grow(mf_->getSSARegMap()->getLastVirtReg()+1);
|
||||
while (!SubRegIdxes.empty()) {
|
||||
std::pair<unsigned, unsigned> RI = SubRegIdxes.back();
|
||||
SubRegIdxes.pop_back();
|
||||
mf_->getSSARegMap()->setIsSubRegister(RI.first, rep(RI.first), RI.second);
|
||||
RegSubIdxMap[RI.first] = RI.second;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1448,12 +1450,13 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
|
||||
// replace register with representative register
|
||||
unsigned OrigReg = mop.getReg();
|
||||
unsigned reg = rep(OrigReg);
|
||||
// Don't rewrite if it is a sub-register of a virtual register.
|
||||
if (!RegMap->isSubRegister(OrigReg))
|
||||
unsigned SubIdx = RegSubIdxMap[OrigReg];
|
||||
if (SubIdx && MRegisterInfo::isPhysicalRegister(reg))
|
||||
mii->getOperand(i).setReg(mri_->getSubReg(reg, SubIdx));
|
||||
else {
|
||||
mii->getOperand(i).setReg(reg);
|
||||
else if (MRegisterInfo::isPhysicalRegister(reg))
|
||||
mii->getOperand(i).setReg(mri_->getSubReg(reg,
|
||||
RegMap->getSubRegisterIndex(OrigReg)));
|
||||
mii->getOperand(i).setSubReg(SubIdx);
|
||||
}
|
||||
|
||||
// Multiple uses of reg by the same instruction. It should not
|
||||
// contribute to spill weight again.
|
||||
|
@ -788,8 +788,7 @@ bool LocalSpiller::PrepForUnfoldOpti(MachineBasicBlock &MBB,
|
||||
if (!MO.isRegister() || MO.getReg() == 0 || !MO.isUse())
|
||||
continue;
|
||||
unsigned VirtReg = MO.getReg();
|
||||
if (MRegisterInfo::isPhysicalRegister(VirtReg) ||
|
||||
RegMap->isSubRegister(VirtReg))
|
||||
if (MRegisterInfo::isPhysicalRegister(VirtReg) || MO.getSubReg())
|
||||
continue;
|
||||
if (VRM.isAssignedReg(VirtReg)) {
|
||||
unsigned PhysReg = VRM.getPhys(VirtReg);
|
||||
@ -911,20 +910,14 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
|
||||
assert(MRegisterInfo::isVirtualRegister(VirtReg) &&
|
||||
"Not a virtual or a physical register?");
|
||||
|
||||
unsigned SubIdx = 0;
|
||||
bool isSubReg = RegMap->isSubRegister(VirtReg);
|
||||
if (isSubReg) {
|
||||
SubIdx = RegMap->getSubRegisterIndex(VirtReg);
|
||||
VirtReg = RegMap->getSuperRegister(VirtReg);
|
||||
}
|
||||
|
||||
unsigned SubIdx = MO.getSubReg();
|
||||
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);
|
||||
unsigned RReg = isSubReg ? MRI->getSubReg(Phys, SubIdx) : Phys;
|
||||
unsigned RReg = SubIdx ? MRI->getSubReg(Phys, SubIdx) : Phys;
|
||||
MI.getOperand(i).setReg(RReg);
|
||||
continue;
|
||||
}
|
||||
@ -960,7 +953,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
|
||||
// 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)) {
|
||||
(SubIdx || MI.getOpcode() == TargetInstrInfo::EXTRACT_SUBREG)) {
|
||||
const TargetRegisterClass* RC = RegMap->getRegClass(VirtReg);
|
||||
if (!RC->contains(PhysReg))
|
||||
PhysReg = 0;
|
||||
@ -994,7 +987,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
|
||||
<< MRI->getName(PhysReg) << " for vreg"
|
||||
<< VirtReg <<" instead of reloading into physreg "
|
||||
<< MRI->getName(VRM.getPhys(VirtReg)) << "\n";
|
||||
unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
|
||||
unsigned RReg = SubIdx ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
|
||||
MI.getOperand(i).setReg(RReg);
|
||||
|
||||
// The only technical detail we have is that we don't know that
|
||||
@ -1067,7 +1060,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
|
||||
DOUT << " from physreg " << MRI->getName(PhysReg) << " for vreg"
|
||||
<< VirtReg
|
||||
<< " instead of reloading into same physreg.\n";
|
||||
unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
|
||||
unsigned RReg = SubIdx ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
|
||||
MI.getOperand(i).setReg(RReg);
|
||||
ReusedOperands.markClobbered(RReg);
|
||||
++NumReused;
|
||||
@ -1087,7 +1080,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
|
||||
|
||||
Spills.addAvailable(ReuseSlot, &MI, DesignatedReg);
|
||||
unsigned RReg =
|
||||
isSubReg ? MRI->getSubReg(DesignatedReg, SubIdx) : DesignatedReg;
|
||||
SubIdx ? MRI->getSubReg(DesignatedReg, SubIdx) : DesignatedReg;
|
||||
MI.getOperand(i).setReg(RReg);
|
||||
DOUT << '\t' << *prior(MII);
|
||||
++NumReused;
|
||||
@ -1127,7 +1120,7 @@ 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();
|
||||
unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
|
||||
unsigned RReg = SubIdx ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
|
||||
MI.getOperand(i).setReg(RReg);
|
||||
UpdateKills(*prior(MII), RegKills, KillOps);
|
||||
DOUT << '\t' << *prior(MII);
|
||||
@ -1308,13 +1301,7 @@ 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);
|
||||
}
|
||||
|
||||
unsigned SubIdx = MO.getSubReg();
|
||||
bool DoReMat = VRM.isReMaterialized(VirtReg);
|
||||
if (DoReMat)
|
||||
ReMatDefs.insert(&MI);
|
||||
@ -1329,7 +1316,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
|
||||
int TiedOp = MI.getInstrDescriptor()->findTiedToSrcOperand(i);
|
||||
if (TiedOp != -1) {
|
||||
PhysReg = MI.getOperand(TiedOp).getReg();
|
||||
if (isSubReg) {
|
||||
if (SubIdx) {
|
||||
unsigned SuperReg = findSuperReg(RC, PhysReg, SubIdx, MRI);
|
||||
assert(SuperReg && MRI->getSubReg(SuperReg, SubIdx) == PhysReg &&
|
||||
"Can't find corresponding super-register!");
|
||||
@ -1346,7 +1333,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) {
|
||||
}
|
||||
|
||||
MF.setPhysRegUsed(PhysReg);
|
||||
unsigned RReg = isSubReg ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
|
||||
unsigned RReg = SubIdx ? MRI->getSubReg(PhysReg, SubIdx) : PhysReg;
|
||||
ReusedOperands.markClobbered(RReg);
|
||||
MI.getOperand(i).setReg(RReg);
|
||||
|
||||
|
@ -616,6 +616,15 @@ void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
|
||||
case X86::PsMOVZX64rr32:
|
||||
O << TAI->getCommentString() << " ZERO-EXTEND " << "\n\t";
|
||||
break;
|
||||
case X86::MOV8mr: {
|
||||
const MachineOperand &MO = MI->getOperand(4);
|
||||
switch (MO.getReg()) {
|
||||
default: abort();
|
||||
case X86::AH: case X86::DH: case X86::CH: case X86::BH:
|
||||
case X86::AL: case X86::DL: case X86::CL: case X86::BL:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call the autogenerated instruction printer routines.
|
||||
|
@ -773,7 +773,8 @@ bool X86RegisterInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||
static const MachineInstrBuilder &X86InstrAddOperand(MachineInstrBuilder &MIB,
|
||||
MachineOperand &MO) {
|
||||
if (MO.isRegister())
|
||||
MIB = MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit());
|
||||
MIB = MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit(),
|
||||
false, false, MO.getSubReg());
|
||||
else if (MO.isImmediate())
|
||||
MIB = MIB.addImm(MO.getImm());
|
||||
else if (MO.isFrameIndex())
|
||||
@ -1498,8 +1499,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
|
||||
unsigned Opc = (Amount < 128) ?
|
||||
(Is64Bit ? X86::ADD64ri8 : X86::ADD32ri8) :
|
||||
(Is64Bit ? X86::ADD64ri32 : X86::ADD32ri);
|
||||
New = BuildMI(TII.get(Opc), StackPtr)
|
||||
.addReg(StackPtr).addImm(Amount);
|
||||
New = BuildMI(TII.get(Opc), StackPtr).addReg(StackPtr).addImm(Amount);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user