From: Evan Cheng Date: Fri, 5 Oct 2007 01:34:55 +0000 (+0000) Subject: Added storeRegToAddr, loadRegFromAddr, and unfoldMemoryOperand's. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=75b4e46b8a39cac5bcec1365bb25f395611d0be2;p=oota-llvm.git Added storeRegToAddr, loadRegFromAddr, and unfoldMemoryOperand's. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42624 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index a8ed043d73d..4d46ec9cdd8 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -26,6 +26,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineLocation.h" +#include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetInstrInfo.h" @@ -232,82 +233,85 @@ X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm, unsigned MemOp = OpTbl2Addr[i][1]; if (!RegOp2MemOpTable2Addr.insert(std::make_pair((unsigned*)RegOp, MemOp))) assert(false && "Duplicated entries?"); - if (!MemOp2RegOpTable.insert(std::make_pair((unsigned*)MemOp, RegOp))) + unsigned AuxInfo = 0 | (1 << 4) | (1 << 5); // Index 0,folded load and store + if (!MemOp2RegOpTable.insert(std::make_pair((unsigned*)MemOp, + std::make_pair(RegOp, AuxInfo)))) AmbEntries.push_back(MemOp); } - static const unsigned OpTbl0[][2] = { - { X86::CALL32r, X86::CALL32m }, - { X86::CALL64r, X86::CALL64m }, - { X86::CMP16ri, X86::CMP16mi }, - { X86::CMP16ri8, X86::CMP16mi8 }, - { X86::CMP32ri, X86::CMP32mi }, - { X86::CMP32ri8, X86::CMP32mi8 }, - { X86::CMP64ri32, X86::CMP64mi32 }, - { X86::CMP64ri8, X86::CMP64mi8 }, - { X86::CMP8ri, X86::CMP8mi }, - { X86::DIV16r, X86::DIV16m }, - { X86::DIV32r, X86::DIV32m }, - { X86::DIV64r, X86::DIV64m }, - { X86::DIV8r, X86::DIV8m }, - { X86::FsMOVAPDrr, X86::MOVSDmr }, - { X86::FsMOVAPSrr, X86::MOVSSmr }, - { X86::IDIV16r, X86::IDIV16m }, - { X86::IDIV32r, X86::IDIV32m }, - { X86::IDIV64r, X86::IDIV64m }, - { X86::IDIV8r, X86::IDIV8m }, - { X86::IMUL16r, X86::IMUL16m }, - { X86::IMUL32r, X86::IMUL32m }, - { X86::IMUL64r, X86::IMUL64m }, - { X86::IMUL8r, X86::IMUL8m }, - { X86::JMP32r, X86::JMP32m }, - { X86::JMP64r, X86::JMP64m }, - { X86::MOV16ri, X86::MOV16mi }, - { X86::MOV16rr, X86::MOV16mr }, - { X86::MOV32ri, X86::MOV32mi }, - { X86::MOV32rr, X86::MOV32mr }, - { X86::MOV64ri32, X86::MOV64mi32 }, - { X86::MOV64rr, X86::MOV64mr }, - { X86::MOV8ri, X86::MOV8mi }, - { X86::MOV8rr, X86::MOV8mr }, - { X86::MOVAPDrr, X86::MOVAPDmr }, - { X86::MOVAPSrr, X86::MOVAPSmr }, - { X86::MOVPDI2DIrr, X86::MOVPDI2DImr }, - { X86::MOVPQIto64rr,X86::MOVPQIto64mr }, - { X86::MOVPS2SSrr, X86::MOVPS2SSmr }, - { X86::MOVSDrr, X86::MOVSDmr }, - { X86::MOVSDto64rr, X86::MOVSDto64mr }, - { X86::MOVSS2DIrr, X86::MOVSS2DImr }, - { X86::MOVSSrr, X86::MOVSSmr }, - { X86::MOVUPDrr, X86::MOVUPDmr }, - { X86::MOVUPSrr, X86::MOVUPSmr }, - { X86::MUL16r, X86::MUL16m }, - { X86::MUL32r, X86::MUL32m }, - { X86::MUL64r, X86::MUL64m }, - { X86::MUL8r, X86::MUL8m }, - { X86::SETAEr, X86::SETAEm }, - { X86::SETAr, X86::SETAm }, - { X86::SETBEr, X86::SETBEm }, - { X86::SETBr, X86::SETBm }, - { X86::SETEr, X86::SETEm }, - { X86::SETGEr, X86::SETGEm }, - { X86::SETGr, X86::SETGm }, - { X86::SETLEr, X86::SETLEm }, - { X86::SETLr, X86::SETLm }, - { X86::SETNEr, X86::SETNEm }, - { X86::SETNPr, X86::SETNPm }, - { X86::SETNSr, X86::SETNSm }, - { X86::SETPr, X86::SETPm }, - { X86::SETSr, X86::SETSm }, - { X86::TAILJMPr, X86::TAILJMPm }, - { X86::TEST16ri, X86::TEST16mi }, - { X86::TEST32ri, X86::TEST32mi }, - { X86::TEST64ri32, X86::TEST64mi32 }, - { X86::TEST8ri, X86::TEST8mi }, - { X86::XCHG16rr, X86::XCHG16mr }, - { X86::XCHG32rr, X86::XCHG32mr }, - { X86::XCHG64rr, X86::XCHG64mr }, - { X86::XCHG8rr, X86::XCHG8mr } + // If the third value is 1, then it's folding either a load or a store. + static const unsigned OpTbl0[][3] = { + { X86::CALL32r, X86::CALL32m, 1 }, + { X86::CALL64r, X86::CALL64m, 1 }, + { X86::CMP16ri, X86::CMP16mi, 1 }, + { X86::CMP16ri8, X86::CMP16mi8, 1 }, + { X86::CMP32ri, X86::CMP32mi, 1 }, + { X86::CMP32ri8, X86::CMP32mi8, 1 }, + { X86::CMP64ri32, X86::CMP64mi32, 1 }, + { X86::CMP64ri8, X86::CMP64mi8, 1 }, + { X86::CMP8ri, X86::CMP8mi, 1 }, + { X86::DIV16r, X86::DIV16m, 1 }, + { X86::DIV32r, X86::DIV32m, 1 }, + { X86::DIV64r, X86::DIV64m, 1 }, + { X86::DIV8r, X86::DIV8m, 1 }, + { X86::FsMOVAPDrr, X86::MOVSDmr, 0 }, + { X86::FsMOVAPSrr, X86::MOVSSmr, 0 }, + { X86::IDIV16r, X86::IDIV16m, 1 }, + { X86::IDIV32r, X86::IDIV32m, 1 }, + { X86::IDIV64r, X86::IDIV64m, 1 }, + { X86::IDIV8r, X86::IDIV8m, 1 }, + { X86::IMUL16r, X86::IMUL16m, 1 }, + { X86::IMUL32r, X86::IMUL32m, 1 }, + { X86::IMUL64r, X86::IMUL64m, 1 }, + { X86::IMUL8r, X86::IMUL8m, 1 }, + { X86::JMP32r, X86::JMP32m, 1 }, + { X86::JMP64r, X86::JMP64m, 1 }, + { X86::MOV16ri, X86::MOV16mi, 0 }, + { X86::MOV16rr, X86::MOV16mr, 0 }, + { X86::MOV32ri, X86::MOV32mi, 0 }, + { X86::MOV32rr, X86::MOV32mr, 0 }, + { X86::MOV64ri32, X86::MOV64mi32, 0 }, + { X86::MOV64rr, X86::MOV64mr, 0 }, + { X86::MOV8ri, X86::MOV8mi, 0 }, + { X86::MOV8rr, X86::MOV8mr, 0 }, + { X86::MOVAPDrr, X86::MOVAPDmr, 0 }, + { X86::MOVAPSrr, X86::MOVAPSmr, 0 }, + { X86::MOVPDI2DIrr, X86::MOVPDI2DImr, 0 }, + { X86::MOVPQIto64rr,X86::MOVPQIto64mr, 0 }, + { X86::MOVPS2SSrr, X86::MOVPS2SSmr, 0 }, + { X86::MOVSDrr, X86::MOVSDmr, 0 }, + { X86::MOVSDto64rr, X86::MOVSDto64mr, 0 }, + { X86::MOVSS2DIrr, X86::MOVSS2DImr, 0 }, + { X86::MOVSSrr, X86::MOVSSmr, 0 }, + { X86::MOVUPDrr, X86::MOVUPDmr, 0 }, + { X86::MOVUPSrr, X86::MOVUPSmr, 0 }, + { X86::MUL16r, X86::MUL16m, 1 }, + { X86::MUL32r, X86::MUL32m, 1 }, + { X86::MUL64r, X86::MUL64m, 1 }, + { X86::MUL8r, X86::MUL8m, 1 }, + { X86::SETAEr, X86::SETAEm, 0 }, + { X86::SETAr, X86::SETAm, 0 }, + { X86::SETBEr, X86::SETBEm, 0 }, + { X86::SETBr, X86::SETBm, 0 }, + { X86::SETEr, X86::SETEm, 0 }, + { X86::SETGEr, X86::SETGEm, 0 }, + { X86::SETGr, X86::SETGm, 0 }, + { X86::SETLEr, X86::SETLEm, 0 }, + { X86::SETLr, X86::SETLm, 0 }, + { X86::SETNEr, X86::SETNEm, 0 }, + { X86::SETNPr, X86::SETNPm, 0 }, + { X86::SETNSr, X86::SETNSm, 0 }, + { X86::SETPr, X86::SETPm, 0 }, + { X86::SETSr, X86::SETSm, 0 }, + { X86::TAILJMPr, X86::TAILJMPm, 1 }, + { X86::TEST16ri, X86::TEST16mi, 1 }, + { X86::TEST32ri, X86::TEST32mi, 1 }, + { X86::TEST64ri32, X86::TEST64mi32, 1 }, + { X86::TEST8ri, X86::TEST8mi, 1 }, + { X86::XCHG16rr, X86::XCHG16mr, 0 }, + { X86::XCHG32rr, X86::XCHG32mr, 0 }, + { X86::XCHG64rr, X86::XCHG64mr, 0 }, + { X86::XCHG8rr, X86::XCHG8mr, 0 } }; for (unsigned i = 0, e = array_lengthof(OpTbl0); i != e; ++i) { @@ -315,7 +319,11 @@ X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm, unsigned MemOp = OpTbl0[i][1]; if (!RegOp2MemOpTable0.insert(std::make_pair((unsigned*)RegOp, MemOp))) assert(false && "Duplicated entries?"); - if (!MemOp2RegOpTable.insert(std::make_pair((unsigned*)MemOp, RegOp))) + unsigned FoldedLoad = OpTbl0[i][2]; + // Index 0, folded load or store. + unsigned AuxInfo = 0 | (FoldedLoad << 4) | ((FoldedLoad^1) << 5); + if (!MemOp2RegOpTable.insert(std::make_pair((unsigned*)MemOp, + std::make_pair(RegOp, AuxInfo)))) AmbEntries.push_back(MemOp); } @@ -436,7 +444,9 @@ X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm, unsigned MemOp = OpTbl1[i][1]; if (!RegOp2MemOpTable1.insert(std::make_pair((unsigned*)RegOp, MemOp))) assert(false && "Duplicated entries?"); - if (!MemOp2RegOpTable.insert(std::make_pair((unsigned*)MemOp, RegOp))) + unsigned AuxInfo = 1 | (1 << 4); // Index 1, folded load + if (!MemOp2RegOpTable.insert(std::make_pair((unsigned*)MemOp, + std::make_pair(RegOp, AuxInfo)))) AmbEntries.push_back(MemOp); } @@ -627,7 +637,9 @@ X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm, unsigned MemOp = OpTbl2[i][1]; if (!RegOp2MemOpTable2.insert(std::make_pair((unsigned*)RegOp, MemOp))) assert(false && "Duplicated entries?"); - if (!MemOp2RegOpTable.insert(std::make_pair((unsigned*)MemOp, RegOp))) + unsigned AuxInfo = 2 | (1 << 4); // Index 1, folded load + if (!MemOp2RegOpTable.insert(std::make_pair((unsigned*)MemOp, + std::make_pair(RegOp, AuxInfo)))) AmbEntries.push_back(MemOp); } @@ -722,11 +734,30 @@ bool X86RegisterInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, return true; } -void X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx, - const TargetRegisterClass *RC) const { - unsigned Opc; +static const MachineInstrBuilder &X86InstrAddOperand(MachineInstrBuilder &MIB, + MachineOperand &MO) { + if (MO.isRegister()) + MIB = MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit()); + else if (MO.isImmediate()) + MIB = MIB.addImm(MO.getImm()); + else if (MO.isFrameIndex()) + MIB = MIB.addFrameIndex(MO.getFrameIndex()); + else if (MO.isGlobalAddress()) + MIB = MIB.addGlobalAddress(MO.getGlobal(), MO.getOffset()); + else if (MO.isConstantPoolIndex()) + MIB = MIB.addConstantPoolIndex(MO.getConstantPoolIndex(), MO.getOffset()); + else if (MO.isJumpTableIndex()) + MIB = MIB.addJumpTableIndex(MO.getJumpTableIndex()); + else if (MO.isExternalSymbol()) + MIB = MIB.addExternalSymbol(MO.getSymbolName()); + else + assert(0 && "Unknown operand for X86InstrAddOperand!"); + + return MIB; +} + +static unsigned getStoreRegOpcode(const TargetRegisterClass *RC) { + unsigned Opc = 0; if (RC == &X86::GR64RegClass) { Opc = X86::MOV64mr; } else if (RC == &X86::GR32RegClass) { @@ -757,15 +788,33 @@ void X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, assert(0 && "Unknown regclass"); abort(); } + + return Opc; +} + +void X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned SrcReg, int FrameIdx, + const TargetRegisterClass *RC) const { + unsigned Opc = getStoreRegOpcode(RC); addFrameReference(BuildMI(MBB, MI, TII.get(Opc)), FrameIdx) .addReg(SrcReg, false, false, true); } -void X86RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned DestReg, int FrameIdx, - const TargetRegisterClass *RC) const{ - unsigned Opc; +void X86RegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const { + unsigned Opc = getStoreRegOpcode(RC); + MachineInstrBuilder MIB = BuildMI(TII.get(Opc)); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) + MIB = X86InstrAddOperand(MIB, Addr[i]); + MIB.addReg(SrcReg, false, false, true); + NewMIs.push_back(MIB); +} + +static unsigned getLoadRegOpcode(const TargetRegisterClass *RC) { + unsigned Opc = 0; if (RC == &X86::GR64RegClass) { Opc = X86::MOV64rm; } else if (RC == &X86::GR32RegClass) { @@ -796,9 +845,29 @@ void X86RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, assert(0 && "Unknown regclass"); abort(); } + + return Opc; +} + +void X86RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, int FrameIdx, + const TargetRegisterClass *RC) const{ + unsigned Opc = getLoadRegOpcode(RC); addFrameReference(BuildMI(MBB, MI, TII.get(Opc), DestReg), FrameIdx); } +void X86RegisterInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const { + unsigned Opc = getLoadRegOpcode(RC); + MachineInstrBuilder MIB = BuildMI(TII.get(Opc), DestReg); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) + MIB = X86InstrAddOperand(MIB, Addr[i]); + NewMIs.push_back(MIB); +} + void X86RegisterInfo::copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, @@ -905,28 +974,6 @@ void X86RegisterInfo::reMaterialize(MachineBasicBlock &MBB, } } -static const MachineInstrBuilder &FuseInstrAddOperand(MachineInstrBuilder &MIB, - MachineOperand &MO) { - if (MO.isRegister()) - MIB = MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit()); - else if (MO.isImmediate()) - MIB = MIB.addImm(MO.getImm()); - else if (MO.isFrameIndex()) - MIB = MIB.addFrameIndex(MO.getFrameIndex()); - else if (MO.isGlobalAddress()) - MIB = MIB.addGlobalAddress(MO.getGlobal(), MO.getOffset()); - else if (MO.isConstantPoolIndex()) - MIB = MIB.addConstantPoolIndex(MO.getConstantPoolIndex(), MO.getOffset()); - else if (MO.isJumpTableIndex()) - MIB = MIB.addJumpTableIndex(MO.getJumpTableIndex()); - else if (MO.isExternalSymbol()) - MIB = MIB.addExternalSymbol(MO.getSymbolName()); - else - assert(0 && "Unknown operand for FuseInst!"); - - return MIB; -} - static MachineInstr *FuseTwoAddrInst(unsigned Opcode, SmallVector &MOs, MachineInstr *MI, const TargetInstrInfo &TII) { @@ -936,14 +983,14 @@ static MachineInstr *FuseTwoAddrInst(unsigned Opcode, MachineInstrBuilder MIB = BuildMI(TII.get(Opcode)); unsigned NumAddrOps = MOs.size(); for (unsigned i = 0; i != NumAddrOps; ++i) - MIB = FuseInstrAddOperand(MIB, MOs[i]); + MIB = X86InstrAddOperand(MIB, MOs[i]); if (NumAddrOps < 4) // FrameIndex only MIB.addImm(1).addReg(0).addImm(0); // Loop over the rest of the ri operands, converting them over. for (unsigned i = 0; i != NumOps; ++i) { MachineOperand &MO = MI->getOperand(i+2); - MIB = FuseInstrAddOperand(MIB, MO); + MIB = X86InstrAddOperand(MIB, MO); } return MIB; } @@ -959,11 +1006,11 @@ static MachineInstr *FuseInst(unsigned Opcode, unsigned OpNo, assert(MO.isRegister() && "Expected to fold into reg operand!"); unsigned NumAddrOps = MOs.size(); for (unsigned i = 0; i != NumAddrOps; ++i) - MIB = FuseInstrAddOperand(MIB, MOs[i]); + MIB = X86InstrAddOperand(MIB, MOs[i]); if (NumAddrOps < 4) // FrameIndex only MIB.addImm(1).addReg(0).addImm(0); } else { - MIB = FuseInstrAddOperand(MIB, MO); + MIB = X86InstrAddOperand(MIB, MO); } } return MIB; @@ -976,7 +1023,7 @@ static MachineInstr *MakeM0Inst(const TargetInstrInfo &TII, unsigned Opcode, unsigned NumAddrOps = MOs.size(); for (unsigned i = 0; i != NumAddrOps; ++i) - MIB = FuseInstrAddOperand(MIB, MOs[i]); + MIB = X86InstrAddOperand(MIB, MOs[i]); if (NumAddrOps < 4) // FrameIndex only MIB.addImm(1).addReg(0).addImm(0); return MIB.addImm(0); @@ -1066,6 +1113,156 @@ MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNu return foldMemoryOperand(MI, OpNum, MOs); } +bool X86RegisterInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, + SSARegMap *RegMap, + SmallVector &NewMIs) const { + DenseMap >::iterator I = + MemOp2RegOpTable.find((unsigned*)MI->getOpcode()); + if (I == MemOp2RegOpTable.end()) + return false; + unsigned Opc = I->second.first; + unsigned Index = I->second.second & 0xf; + bool HasLoad = I->second.second & (1 << 4); + bool HasStore = I->second.second & (1 << 5); + const TargetInstrDescriptor &TID = TII.get(Opc); + const TargetOperandInfo &TOI = TID.OpInfo[Index]; + const TargetRegisterClass *RC = (TOI.Flags & M_LOOK_UP_PTR_REG_CLASS) + ? TII.getPointerRegClass() : getRegClass(TOI.RegClass); + SmallVector AddrOps; + SmallVector BeforeOps; + SmallVector AfterOps; + SmallVector ImpOps; + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + MachineOperand &Op = MI->getOperand(i); + if (i >= Index && i < Index+4) + AddrOps.push_back(Op); + else if (Op.isRegister() && Op.isImplicit()) + ImpOps.push_back(Op); + else if (i < Index) + BeforeOps.push_back(Op); + else if (i > Index) + AfterOps.push_back(Op); + } + + // Emit the load instruction. + unsigned LoadReg = 0; + if (HasLoad) { + LoadReg = RegMap->createVirtualRegister(RC); + loadRegFromAddr(MF, LoadReg, AddrOps, RC, NewMIs); + if (HasStore) { + // Address operands cannot be marked isKill. + for (unsigned i = 1; i != 5; ++i) { + MachineOperand &MO = NewMIs[0]->getOperand(i); + if (MO.isRegister()) + MO.unsetIsKill(); + } + } + } + + // Emit the data processing instruction. + MachineInstrBuilder MIB = BuildMI(TII.get(Opc)); + unsigned StoreReg = 0; + const TargetRegisterClass *DstRC = 0; + if (HasStore) { + const TargetOperandInfo &DstTOI = TID.OpInfo[0]; + DstRC = (DstTOI.Flags & M_LOOK_UP_PTR_REG_CLASS) + ? TII.getPointerRegClass() : getRegClass(DstTOI.RegClass); + StoreReg = RegMap->createVirtualRegister(RC); + MIB.addReg(StoreReg, true); + } + for (unsigned i = 0, e = BeforeOps.size(); i != e; ++i) + MIB = X86InstrAddOperand(MIB, BeforeOps[i]); + if (LoadReg) + MIB.addReg(LoadReg); + for (unsigned i = 0, e = AfterOps.size(); i != e; ++i) + MIB = X86InstrAddOperand(MIB, AfterOps[i]); + NewMIs.push_back(MIB); + + // Emit the store instruction. + if (HasStore) + storeRegToAddr(MF, StoreReg, AddrOps, DstRC, NewMIs); + + return true; +} + + +bool +X86RegisterInfo::unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, + SmallVector &NewNodes) const { + if (!N->isTargetOpcode()) + return false; + + DenseMap >::iterator I = + MemOp2RegOpTable.find((unsigned*)N->getTargetOpcode()); + if (I == MemOp2RegOpTable.end()) + return false; + unsigned Opc = I->second.first; + unsigned Index = I->second.second & 0xf; + bool HasLoad = I->second.second & (1 << 4); + bool HasStore = I->second.second & (1 << 5); + const TargetInstrDescriptor &TID = TII.get(Opc); + const TargetOperandInfo &TOI = TID.OpInfo[Index]; + const TargetRegisterClass *RC = (TOI.Flags & M_LOOK_UP_PTR_REG_CLASS) + ? TII.getPointerRegClass() : getRegClass(TOI.RegClass); + std::vector AddrOps; + std::vector BeforeOps; + std::vector AfterOps; + unsigned NumOps = N->getNumOperands(); + for (unsigned i = 0; i != NumOps-1; ++i) { + SDOperand Op = N->getOperand(i); + if (i >= Index && i < Index+4) + AddrOps.push_back(Op); + else if (i < Index) + BeforeOps.push_back(Op); + else if (i > Index) + AfterOps.push_back(Op); + } + SDOperand Chain = N->getOperand(NumOps-1); + AddrOps.push_back(Chain); + + // Emit the load instruction. + SDNode *Load = 0; + if (HasLoad) { + MVT::ValueType VT = *RC->vt_begin(); + Load = DAG.getTargetNode(getLoadRegOpcode(RC), VT, MVT::Other, + &AddrOps[0], AddrOps.size()); + NewNodes.push_back(Load); + } + + // Emit the data processing instruction. + std::vector VTs; + const TargetRegisterClass *DstRC = 0; + if (TID.numDefs > 0) { + const TargetOperandInfo &DstTOI = TID.OpInfo[0]; + DstRC = (DstTOI.Flags & M_LOOK_UP_PTR_REG_CLASS) + ? TII.getPointerRegClass() : getRegClass(DstTOI.RegClass); + VTs.push_back(*DstRC->vt_begin()); + } + for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) { + MVT::ValueType VT = N->getValueType(i); + if (VT != MVT::Other && i >= TID.numDefs) + VTs.push_back(VT); + } + if (Load) + BeforeOps.push_back(SDOperand(Load, 0)); + std::copy(AfterOps.begin(), AfterOps.end(), std::back_inserter(BeforeOps)); + SDNode *NewNode= DAG.getTargetNode(Opc, VTs, &BeforeOps[0], BeforeOps.size()); + NewNodes.push_back(NewNode); + + // Emit the store instruction. + if (HasStore) { + AddrOps.pop_back(); + AddrOps.push_back(SDOperand(NewNode, 0)); + AddrOps.push_back(Chain); + SDNode *Store = DAG.getTargetNode(getStoreRegOpcode(DstRC), + MVT::Other, &AddrOps[0], AddrOps.size()); + NewNodes.push_back(Store); + } + + return true; +} + + const unsigned * X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { static const unsigned CalleeSavedRegs32Bit[] = { diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h index 0d9ef2ab5fe..fc739bb0956 100644 --- a/lib/Target/X86/X86RegisterInfo.h +++ b/lib/Target/X86/X86RegisterInfo.h @@ -64,7 +64,7 @@ private: /// MemOp2RegOpTable - Load / store unfolding opcode map. /// - DenseMap MemOp2RegOpTable; + DenseMap > MemOp2RegOpTable; public: X86RegisterInfo(X86TargetMachine &tm, const TargetInstrInfo &tii); @@ -88,11 +88,21 @@ public: unsigned SrcReg, int FrameIndex, const TargetRegisterClass *RC) const; + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const; + void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const; + void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const; + void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, @@ -122,6 +132,16 @@ public: unsigned OpNum, MachineInstr* LoadMI) const; + /// unfoldMemoryOperand - Separate a single instruction which folded a load or a + /// a store or a load and a store into two or more instruction. If this is + /// possible, returns true as well as the new instructions by reference. + bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, + SSARegMap *RegMap, + SmallVector &NewMIs) const; + + bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, + SmallVector &NewNodes) const; + /// getCalleeSavedRegs - Return a null-terminated list of all of the /// callee-save registers on this target. const unsigned *getCalleeSavedRegs(const MachineFunction* MF = 0) const;