From c498b0281fa81bc213ad1a1228664d480936c0e6 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 14 Nov 2007 07:59:08 +0000 Subject: [PATCH] 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 --- include/llvm/CodeGen/MachineInstr.h | 16 +++++++++- include/llvm/CodeGen/MachineInstrBuilder.h | 4 +-- include/llvm/CodeGen/SSARegMap.h | 19 ------------ lib/CodeGen/LiveIntervalAnalysis.cpp | 10 ++----- lib/CodeGen/MachineInstr.cpp | 2 ++ lib/CodeGen/SimpleRegisterCoalescing.cpp | 15 ++++++---- lib/CodeGen/VirtRegMap.cpp | 35 +++++++--------------- lib/Target/X86/X86ATTAsmPrinter.cpp | 9 ++++++ lib/Target/X86/X86RegisterInfo.cpp | 6 ++-- 9 files changed, 53 insertions(+), 63 deletions(-) diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 9d0d8d950e0..93b739d125e 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -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 diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index b2361a51b1e..c62f67b38f2 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -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; } diff --git a/include/llvm/CodeGen/SSARegMap.h b/include/llvm/CodeGen/SSARegMap.h index a92222a5c36..97d8d6988c4 100644 --- a/include/llvm/CodeGen/SSARegMap.h +++ b/include/llvm/CodeGen/SSARegMap.h @@ -26,7 +26,6 @@ class TargetRegisterClass; class SSARegMap { IndexedMap RegClassMap; - IndexedMap, 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 diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index ac5fc8ca020..833868a4585 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -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 diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index a3485bc524c..c5145ff1809 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -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); } } diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index 623d2951d09..b919e8a80ba 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -1387,6 +1387,7 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) { r2rRevMap_.grow(RegMap->getLastVirtReg()); // Join (coalesce) intervals if requested. + IndexedMap 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 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. diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 9f5d33f416b..bc63066056d 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -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); diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp index cee802d1650..f46ebb840c2 100644 --- a/lib/Target/X86/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/X86ATTAsmPrinter.cpp @@ -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. diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 71f8d0e7855..25b6375ce32 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -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); } }