From: Evan Cheng Date: Wed, 5 Dec 2007 03:14:33 +0000 (+0000) Subject: Add a argument to storeRegToStackSlot and storeRegToAddr to specify whether X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d64b5c82b97ad1b74eb9fd2f23257a7899b0c307;p=oota-llvm.git Add a argument to storeRegToStackSlot and storeRegToAddr to specify whether the stored register is killed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44600 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index 1be8ea5ea04..a40d0abcb1c 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -278,6 +278,9 @@ namespace llvm { SmallVector &Ops, bool isSS, int Slot, unsigned Reg); + bool canFoldMemoryOperand(MachineInstr *MI, + SmallVector &Ops) const; + /// anyKillInMBBAfterIdx - Returns true if there is a kill of the specified /// VNInfo that's after the specified index but is within the basic block. bool anyKillInMBBAfterIdx(const LiveInterval &li, const VNInfo *VNI, @@ -304,7 +307,7 @@ namespace llvm { /// rewriteInstructionForSpills, rewriteInstructionsForSpills - Helper functions /// for addIntervalsForSpills to rewrite uses / defs for the given live range. - void rewriteInstructionForSpills(const LiveInterval &li, bool TrySplit, + bool rewriteInstructionForSpills(const LiveInterval &li, bool TrySplit, unsigned id, unsigned index, unsigned end, MachineInstr *MI, MachineInstr *OrigDefMI, MachineInstr *DefMI, unsigned Slot, int LdSlot, bool isLoad, bool isLoadSS, bool DefIsReMat, bool CanDelete, diff --git a/include/llvm/Target/MRegisterInfo.h b/include/llvm/Target/MRegisterInfo.h index c4d16227574..08f76c4d353 100644 --- a/include/llvm/Target/MRegisterInfo.h +++ b/include/llvm/Target/MRegisterInfo.h @@ -493,10 +493,10 @@ public: virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const = 0; - virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const = 0; @@ -553,12 +553,12 @@ public: return 0; } - /// getOpcodeAfterMemoryFold - Returns the opcode of the would be new - /// instruction after load / store is folded into an instruction of the - /// specified opcode. It returns zero if the specified unfolding is not - /// possible. - virtual unsigned getOpcodeAfterMemoryFold(unsigned Opc, unsigned OpNum) const{ - return 0; + /// canFoldMemoryOperand - Returns true if the specified load / store is + /// folding is possible. + virtual + bool canFoldMemoryOperand(MachineInstr *MI, + SmallVectorImpl &Ops) const{ + return false; } /// unfoldMemoryOperand - Separate a single instruction which folded a load or diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index 882c6a74404..9f765d43d40 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -253,7 +253,7 @@ void PEI::saveCalleeSavedRegisters(MachineFunction &Fn) { MBB->addLiveIn(CSI[i].getReg()); // Insert the spill to the stack frame. - RegInfo->storeRegToStackSlot(*MBB, I, CSI[i].getReg(), + RegInfo->storeRegToStackSlot(*MBB, I, CSI[i].getReg(), true, CSI[i].getFrameIdx(), CSI[i].getRegClass()); } } diff --git a/lib/CodeGen/RegAllocBigBlock.cpp b/lib/CodeGen/RegAllocBigBlock.cpp index 227a238a86d..83c9ceb37b0 100644 --- a/lib/CodeGen/RegAllocBigBlock.cpp +++ b/lib/CodeGen/RegAllocBigBlock.cpp @@ -329,7 +329,7 @@ void RABigBlock::spillVirtReg(MachineBasicBlock &MBB, const TargetRegisterClass *RC = MF->getSSARegMap()->getRegClass(VirtReg); int FrameIndex = getStackSpaceFor(VirtReg, RC); DOUT << " to stack slot #" << FrameIndex; - RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIndex, RC); + RegInfo->storeRegToStackSlot(MBB, I, PhysReg, true, FrameIndex, RC); ++NumStores; // Update statistics } diff --git a/lib/CodeGen/RegAllocLocal.cpp b/lib/CodeGen/RegAllocLocal.cpp index a666184b96e..4b4150a492a 100644 --- a/lib/CodeGen/RegAllocLocal.cpp +++ b/lib/CodeGen/RegAllocLocal.cpp @@ -286,7 +286,7 @@ void RALocal::spillVirtReg(MachineBasicBlock &MBB, const TargetRegisterClass *RC = MF->getSSARegMap()->getRegClass(VirtReg); int FrameIndex = getStackSpaceFor(VirtReg, RC); DOUT << " to stack slot #" << FrameIndex; - RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIndex, RC); + RegInfo->storeRegToStackSlot(MBB, I, PhysReg, true, FrameIndex, RC); ++NumStores; // Update statistics } diff --git a/lib/CodeGen/RegAllocSimple.cpp b/lib/CodeGen/RegAllocSimple.cpp index f49dd4c5cfb..574559a7ac3 100644 --- a/lib/CodeGen/RegAllocSimple.cpp +++ b/lib/CodeGen/RegAllocSimple.cpp @@ -156,7 +156,7 @@ void RegAllocSimple::spillVirtReg(MachineBasicBlock &MBB, // Add move instruction(s) ++NumStores; - RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIdx, RC); + RegInfo->storeRegToStackSlot(MBB, I, PhysReg, true, FrameIdx, RC); } diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp index 15592128480..9cb7453d3d3 100644 --- a/lib/CodeGen/RegisterScavenging.cpp +++ b/lib/CodeGen/RegisterScavenging.cpp @@ -282,7 +282,7 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC, RegInfo->eliminateFrameIndex(II, SPAdj, this); } - RegInfo->storeRegToStackSlot(*MBB, I, SReg, ScavengingFrameIndex, RC); + RegInfo->storeRegToStackSlot(*MBB, I, SReg, true, ScavengingFrameIndex, RC); MachineBasicBlock::iterator II = prior(I); RegInfo->eliminateFrameIndex(II, SPAdj, this); ScavengedReg = SReg; diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 58fc40b2174..6c04439bcb9 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -208,7 +208,8 @@ bool SimpleSpiller::runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM) { } if (MO.isDef()) { - MRI.storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC); + MRI.storeRegToStackSlot(MBB, next(MII), PhysReg, true, + StackSlot, RC); ++NumStores; } } @@ -861,7 +862,7 @@ void LocalSpiller::SpillRegToStackSlot(MachineBasicBlock &MBB, BitVector &RegKills, std::vector &KillOps, VirtRegMap &VRM) { - MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC); + MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, true, StackSlot, RC); DOUT << "Store:\t" << *next(MII); // If there is a dead store to this stack slot, nuke it now. @@ -984,9 +985,10 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) { const TargetRegisterClass *RC = RegMap->getRegClass(VirtReg); unsigned Phys = VRM.getPhys(VirtReg); int StackSlot = VRM.getStackSlot(VirtReg); - MRI->storeRegToStackSlot(MBB, next(MII), Phys, StackSlot, RC); - DOUT << "Store:\t" << *next(MII); - VRM.virtFolded(VirtReg, next(MII), VirtRegMap::isMod); + MRI->storeRegToStackSlot(MBB, next(MII), Phys, false, StackSlot, RC); + MachineInstr *StoreMI = next(MII); + DOUT << "Store:\t" << StoreMI; + VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod); } NextMII = next(MII); } @@ -1011,12 +1013,6 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) { assert(MRegisterInfo::isVirtualRegister(VirtReg) && "Not a virtual or a physical register?"); - // Assumes this is the last use of a split interval. IsKill will be unset - // if reg is use later unless it's a two-address operand. - if (MO.isUse() && VRM.getPreSplitReg(VirtReg) && - TID->getOperandConstraint(i, TOI::TIED_TO) == -1) - MI.getOperand(i).setIsKill(); - unsigned SubIdx = MO.getSubReg(); if (VRM.isAssignedReg(VirtReg)) { // This virtual register was assigned a physreg! diff --git a/lib/Target/ARM/ARMRegisterInfo.cpp b/lib/Target/ARM/ARMRegisterInfo.cpp index f1665dc0b49..70360705a69 100644 --- a/lib/Target/ARM/ARMRegisterInfo.cpp +++ b/lib/Target/ARM/ARMRegisterInfo.cpp @@ -158,31 +158,32 @@ static const MachineInstrBuilder &ARMInstrAddOperand(MachineInstrBuilder &MIB, void ARMRegisterInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned SrcReg, int FI, + unsigned SrcReg, bool isKill, int FI, const TargetRegisterClass *RC) const { if (RC == ARM::GPRRegisterClass) { MachineFunction &MF = *MBB.getParent(); ARMFunctionInfo *AFI = MF.getInfo(); if (AFI->isThumbFunction()) - BuildMI(MBB, I, TII.get(ARM::tSpill)).addReg(SrcReg, false, false, true) + BuildMI(MBB, I, TII.get(ARM::tSpill)).addReg(SrcReg, false, false, isKill) .addFrameIndex(FI).addImm(0); else AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::STR)) - .addReg(SrcReg, false, false, true) + .addReg(SrcReg, false, false, isKill) .addFrameIndex(FI).addReg(0).addImm(0)); } else if (RC == ARM::DPRRegisterClass) { AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::FSTD)) - .addReg(SrcReg, false, false, true) + .addReg(SrcReg, false, false, isKill) .addFrameIndex(FI).addImm(0)); } else { assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::FSTS)) - .addReg(SrcReg, false, false, true) + .addReg(SrcReg, false, false, isKill) .addFrameIndex(FI).addImm(0)); } } void ARMRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { @@ -192,7 +193,7 @@ void ARMRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, if (AFI->isThumbFunction()) { Opc = Addr[0].isFrameIndex() ? ARM::tSpill : ARM::tSTR; MachineInstrBuilder MIB = - BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, true); + BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, isKill); for (unsigned i = 0, e = Addr.size(); i != e; ++i) MIB = ARMInstrAddOperand(MIB, Addr[i]); NewMIs.push_back(MIB); @@ -207,7 +208,7 @@ void ARMRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, } MachineInstrBuilder MIB = - BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, true); + BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, isKill); for (unsigned i = 0, e = Addr.size(); i != e; ++i) MIB = ARMInstrAddOperand(MIB, Addr[i]); AddDefaultPred(MIB); @@ -426,6 +427,39 @@ MachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr *MI, return NewMI; } +bool ARMRegisterInfo::canFoldMemoryOperand(MachineInstr *MI, + SmallVectorImpl &Ops) const { + if (Ops.size() != 1) return NULL; + + unsigned OpNum = Ops[0]; + unsigned Opc = MI->getOpcode(); + switch (Opc) { + default: break; + case ARM::MOVr: + // If it is updating CPSR, then it cannot be foled. + return MI->getOperand(4).getReg() != ARM::CPSR; + case ARM::tMOVr: { + if (OpNum == 0) { // move -> store + unsigned SrcReg = MI->getOperand(1).getReg(); + if (isPhysicalRegister(SrcReg) && !isLowRegister(SrcReg)) + // tSpill cannot take a high register operand. + return false; + } else { // move -> load + unsigned DstReg = MI->getOperand(0).getReg(); + if (isPhysicalRegister(DstReg) && !isLowRegister(DstReg)) + // tRestore cannot target a high register operand. + return false; + } + return true; + } + case ARM::FCPYS: + case ARM::FCPYD: + return true; + } + + return false; +} + const unsigned* ARMRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { static const unsigned CalleeSavedRegs[] = { diff --git a/lib/Target/ARM/ARMRegisterInfo.h b/lib/Target/ARM/ARMRegisterInfo.h index ed53e4e2da5..85ef153f94a 100644 --- a/lib/Target/ARM/ARMRegisterInfo.h +++ b/lib/Target/ARM/ARMRegisterInfo.h @@ -48,10 +48,10 @@ public: void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; @@ -84,6 +84,9 @@ public: return 0; } + bool canFoldMemoryOperand(MachineInstr *MI, + SmallVectorImpl &Ops) const; + const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) const; const TargetRegisterClass* const* diff --git a/lib/Target/Alpha/AlphaRegisterInfo.cpp b/lib/Target/Alpha/AlphaRegisterInfo.cpp index b8e2c268271..8185a796f76 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.cpp +++ b/lib/Target/Alpha/AlphaRegisterInfo.cpp @@ -61,28 +61,29 @@ AlphaRegisterInfo::AlphaRegisterInfo(const TargetInstrInfo &tii) void AlphaRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx, - const TargetRegisterClass *RC) const { + unsigned SrcReg, bool isKill, int FrameIdx, + const TargetRegisterClass *RC) const { //cerr << "Trying to store " << getPrettyName(SrcReg) << " to " // << FrameIdx << "\n"; //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg); if (RC == Alpha::F4RCRegisterClass) BuildMI(MBB, MI, TII.get(Alpha::STS)) - .addReg(SrcReg, false, false, true) + .addReg(SrcReg, false, false, isKill) .addFrameIndex(FrameIdx).addReg(Alpha::F31); else if (RC == Alpha::F8RCRegisterClass) BuildMI(MBB, MI, TII.get(Alpha::STT)) - .addReg(SrcReg, false, false, true) + .addReg(SrcReg, false, false, isKill) .addFrameIndex(FrameIdx).addReg(Alpha::F31); else if (RC == Alpha::GPRCRegisterClass) BuildMI(MBB, MI, TII.get(Alpha::STQ)) - .addReg(SrcReg, false, false, true) + .addReg(SrcReg, false, false, isKill) .addFrameIndex(FrameIdx).addReg(Alpha::F31); else abort(); } void AlphaRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { @@ -96,7 +97,7 @@ void AlphaRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, else abort(); MachineInstrBuilder MIB = - BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, true); + BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, isKill); for (unsigned i = 0, e = Addr.size(); i != e; ++i) { MachineOperand &MO = Addr[i]; if (MO.isRegister()) diff --git a/lib/Target/Alpha/AlphaRegisterInfo.h b/lib/Target/Alpha/AlphaRegisterInfo.h index 04565f7bb22..7a846dcc4d7 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.h +++ b/lib/Target/Alpha/AlphaRegisterInfo.h @@ -30,10 +30,10 @@ struct AlphaRegisterInfo : public AlphaGenRegisterInfo { /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; diff --git a/lib/Target/CellSPU/SPURegisterInfo.cpp b/lib/Target/CellSPU/SPURegisterInfo.cpp index a9c7333dc75..683d97652cf 100644 --- a/lib/Target/CellSPU/SPURegisterInfo.cpp +++ b/lib/Target/CellSPU/SPURegisterInfo.cpp @@ -194,7 +194,7 @@ SPURegisterInfo::SPURegisterInfo(const SPUSubtarget &subtarget, void SPURegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx, + unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC) const { MachineOpCode opc; @@ -227,10 +227,12 @@ SPURegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, abort(); } - addFrameReference(BuildMI(MBB, MI, TII.get(opc)).addReg(SrcReg), FrameIdx); + addFrameReference(BuildMI(MBB, MI, TII.get(opc)) + .addReg(SrcReg, false, false, isKill), FrameIdx); } void SPURegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { @@ -258,7 +260,7 @@ void SPURegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, abort(); } MachineInstrBuilder MIB = BuildMI(TII.get(Opc)) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); for (unsigned i = 0, e = Addr.size(); i != e; ++i) { MachineOperand &MO = Addr[i]; if (MO.isRegister()) diff --git a/lib/Target/CellSPU/SPURegisterInfo.h b/lib/Target/CellSPU/SPURegisterInfo.h index 07e16d809a0..1eca442cae8 100644 --- a/lib/Target/CellSPU/SPURegisterInfo.h +++ b/lib/Target/CellSPU/SPURegisterInfo.h @@ -44,11 +44,11 @@ namespace llvm { //! Store a register to a stack slot, based on its register class. void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; //! Store a register to an address, based on its register class - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; diff --git a/lib/Target/IA64/IA64RegisterInfo.cpp b/lib/Target/IA64/IA64RegisterInfo.cpp index af1af3110dd..2490f88420a 100644 --- a/lib/Target/IA64/IA64RegisterInfo.cpp +++ b/lib/Target/IA64/IA64RegisterInfo.cpp @@ -38,22 +38,23 @@ IA64RegisterInfo::IA64RegisterInfo(const TargetInstrInfo &tii) void IA64RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx, + unsigned SrcReg, bool isKill, + int FrameIdx, const TargetRegisterClass *RC) const{ if (RC == IA64::FPRegisterClass) { BuildMI(MBB, MI, TII.get(IA64::STF_SPILL)).addFrameIndex(FrameIdx) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); } else if (RC == IA64::GRRegisterClass) { BuildMI(MBB, MI, TII.get(IA64::ST8)).addFrameIndex(FrameIdx) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); } else if (RC == IA64::PRRegisterClass) { /* we use IA64::r2 as a temporary register for doing this hackery. */ // first we load 0: BuildMI(MBB, MI, TII.get(IA64::MOV), IA64::r2).addReg(IA64::r0); // then conditionally add 1: BuildMI(MBB, MI, TII.get(IA64::CADDIMM22), IA64::r2).addReg(IA64::r2) - .addImm(1).addReg(SrcReg, false, false, true); + .addImm(1).addReg(SrcReg, false, false, isKill); // and then store it to the stack BuildMI(MBB, MI, TII.get(IA64::ST8)).addFrameIndex(FrameIdx).addReg(IA64::r2); } else assert(0 && @@ -61,6 +62,7 @@ void IA64RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, } void IA64RegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { @@ -86,7 +88,7 @@ void IA64RegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, else MIB.addFrameIndex(MO.getFrameIndex()); } - MIB.addReg(SrcReg, false, false, true); + MIB.addReg(SrcReg, false, false, isKill); NewMIs.push_back(MIB); return; diff --git a/lib/Target/IA64/IA64RegisterInfo.h b/lib/Target/IA64/IA64RegisterInfo.h index 3f86a4c1743..0ac5b7cae71 100644 --- a/lib/Target/IA64/IA64RegisterInfo.h +++ b/lib/Target/IA64/IA64RegisterInfo.h @@ -31,10 +31,10 @@ struct IA64RegisterInfo : public IA64GenRegisterInfo { /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp index 37c09331d5d..81591897d5d 100644 --- a/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/lib/Target/Mips/MipsRegisterInfo.cpp @@ -85,24 +85,25 @@ getRegisterNumbering(unsigned RegEnum) void MipsRegisterInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned SrcReg, int FI, + unsigned SrcReg, bool isKill, int FI, const TargetRegisterClass *RC) const { if (RC == Mips::CPURegsRegisterClass) - BuildMI(MBB, I, TII.get(Mips::SW)).addReg(SrcReg, false, false, true) + BuildMI(MBB, I, TII.get(Mips::SW)).addReg(SrcReg, false, false, isKill) .addImm(0).addFrameIndex(FI); else assert(0 && "Can't store this register to stack slot"); } void MipsRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { if (RC != Mips::CPURegsRegisterClass) assert(0 && "Can't store this register"); MachineInstrBuilder MIB = BuildMI(TII.get(Mips::SW)) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); for (unsigned i = 0, e = Addr.size(); i != e; ++i) { MachineOperand &MO = Addr[i]; if (MO.isRegister()) diff --git a/lib/Target/Mips/MipsRegisterInfo.h b/lib/Target/Mips/MipsRegisterInfo.h index 4ebb7369756..a3fad4a13b6 100644 --- a/lib/Target/Mips/MipsRegisterInfo.h +++ b/lib/Target/Mips/MipsRegisterInfo.h @@ -34,10 +34,10 @@ struct MipsRegisterInfo : public MipsGenRegisterInfo { /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 09b0e515790..dec49bd16a7 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -104,39 +104,39 @@ PPCRegisterInfo::PPCRegisterInfo(const PPCSubtarget &ST, } static void StoreRegToStackSlot(const TargetInstrInfo &TII, - unsigned SrcReg, int FrameIdx, + unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) { if (RC == PPC::GPRCRegisterClass) { if (SrcReg != PPC::LR) { NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STW)) - .addReg(SrcReg, false, false, true), FrameIdx)); + .addReg(SrcReg, false, false, isKill), FrameIdx)); } else { // FIXME: this spills LR immediately to memory in one step. To do this, // we use R11, which we know cannot be used in the prolog/epilog. This is // a hack. NewMIs.push_back(BuildMI(TII.get(PPC::MFLR), PPC::R11)); NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STW)) - .addReg(PPC::R11, false, false, true), FrameIdx)); + .addReg(PPC::R11, false, false, isKill), FrameIdx)); } } else if (RC == PPC::G8RCRegisterClass) { if (SrcReg != PPC::LR8) { NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STD)) - .addReg(SrcReg, false, false, true), FrameIdx)); + .addReg(SrcReg, false, false, isKill), FrameIdx)); } else { // FIXME: this spills LR immediately to memory in one step. To do this, // we use R11, which we know cannot be used in the prolog/epilog. This is // a hack. NewMIs.push_back(BuildMI(TII.get(PPC::MFLR8), PPC::X11)); NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STD)) - .addReg(PPC::X11, false, false, true), FrameIdx)); + .addReg(PPC::X11, false, false, isKill), FrameIdx)); } } else if (RC == PPC::F8RCRegisterClass) { NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STFD)) - .addReg(SrcReg, false, false, true), FrameIdx)); + .addReg(SrcReg, false, false, isKill), FrameIdx)); } else if (RC == PPC::F4RCRegisterClass) { NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STFS)) - .addReg(SrcReg, false, false, true), FrameIdx)); + .addReg(SrcReg, false, false, isKill), FrameIdx)); } else if (RC == PPC::CRRCRegisterClass) { // FIXME: We use R0 here, because it isn't available for RA. // We need to store the CR in the low 4-bits of the saved value. First, @@ -153,7 +153,7 @@ static void StoreRegToStackSlot(const TargetInstrInfo &TII, } NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STW)) - .addReg(PPC::R0, false, false, true), FrameIdx)); + .addReg(PPC::R0, false, false, isKill), FrameIdx)); } else if (RC == PPC::VRRCRegisterClass) { // We don't have indexed addressing for vector loads. Emit: // R0 = ADDI FI# @@ -163,7 +163,7 @@ static void StoreRegToStackSlot(const TargetInstrInfo &TII, NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::ADDI), PPC::R0), FrameIdx, 0, 0)); NewMIs.push_back(BuildMI(TII.get(PPC::STVX)) - .addReg(SrcReg, false, false, true).addReg(PPC::R0).addReg(PPC::R0)); + .addReg(SrcReg, false, false, isKill).addReg(PPC::R0).addReg(PPC::R0)); } else { assert(0 && "Unknown regclass!"); abort(); @@ -173,20 +173,22 @@ static void StoreRegToStackSlot(const TargetInstrInfo &TII, void PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx, + unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC) const { SmallVector NewMIs; - StoreRegToStackSlot(TII, SrcReg, FrameIdx, RC, NewMIs); + StoreRegToStackSlot(TII, SrcReg, isKill, FrameIdx, RC, NewMIs); for (unsigned i = 0, e = NewMIs.size(); i != e; ++i) MBB.insert(MI, NewMIs[i]); } void PPCRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { if (Addr[0].isFrameIndex()) { - StoreRegToStackSlot(TII, SrcReg, Addr[0].getFrameIndex(), RC, NewMIs); + StoreRegToStackSlot(TII, SrcReg, isKill, Addr[0].getFrameIndex(), RC, + NewMIs); return; } @@ -206,7 +208,7 @@ void PPCRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, abort(); } MachineInstrBuilder MIB = BuildMI(TII.get(Opc)) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); for (unsigned i = 0, e = Addr.size(); i != e; ++i) { MachineOperand &MO = Addr[i]; if (MO.isRegister()) diff --git a/lib/Target/PowerPC/PPCRegisterInfo.h b/lib/Target/PowerPC/PPCRegisterInfo.h index 8647a339195..687af569717 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.h +++ b/lib/Target/PowerPC/PPCRegisterInfo.h @@ -37,10 +37,10 @@ public: /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; diff --git a/lib/Target/Sparc/SparcRegisterInfo.cpp b/lib/Target/Sparc/SparcRegisterInfo.cpp index fcd0dfcca25..dc2f9e89ff2 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.cpp +++ b/lib/Target/Sparc/SparcRegisterInfo.cpp @@ -32,23 +32,24 @@ SparcRegisterInfo::SparcRegisterInfo(SparcSubtarget &st, void SparcRegisterInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned SrcReg, int FI, + unsigned SrcReg, bool isKill, int FI, const TargetRegisterClass *RC) const { // On the order of operands here: think "[FrameIdx + 0] = SrcReg". if (RC == SP::IntRegsRegisterClass) BuildMI(MBB, I, TII.get(SP::STri)).addFrameIndex(FI).addImm(0) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); else if (RC == SP::FPRegsRegisterClass) BuildMI(MBB, I, TII.get(SP::STFri)).addFrameIndex(FI).addImm(0) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); else if (RC == SP::DFPRegsRegisterClass) BuildMI(MBB, I, TII.get(SP::STDFri)).addFrameIndex(FI).addImm(0) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); else assert(0 && "Can't store this register to stack slot"); } void SparcRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { @@ -71,7 +72,7 @@ void SparcRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, else MIB.addFrameIndex(MO.getFrameIndex()); } - MIB.addReg(SrcReg, false, false, true); + MIB.addReg(SrcReg, false, false, isKill); NewMIs.push_back(MIB); return; } diff --git a/lib/Target/Sparc/SparcRegisterInfo.h b/lib/Target/Sparc/SparcRegisterInfo.h index 347b631ecf4..8049fadda1b 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.h +++ b/lib/Target/Sparc/SparcRegisterInfo.h @@ -32,10 +32,10 @@ struct SparcRegisterInfo : public SparcGenRegisterInfo { /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 122dd9ed758..a1c118291f8 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -834,14 +834,15 @@ static unsigned getStoreRegOpcode(const TargetRegisterClass *RC, void X86RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx, + unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC) const { unsigned Opc = getStoreRegOpcode(RC, StackAlign); addFrameReference(BuildMI(MBB, MI, TII.get(Opc)), FrameIdx) - .addReg(SrcReg, false, false, true); + .addReg(SrcReg, false, false, isKill); } void X86RegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { @@ -849,7 +850,7 @@ void X86RegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, 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); + MIB.addReg(SrcReg, false, false, isKill); NewMIs.push_back(MIB); } @@ -1195,11 +1196,27 @@ MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, } -unsigned X86RegisterInfo::getOpcodeAfterMemoryFold(unsigned Opc, - unsigned OpNum) const { +bool X86RegisterInfo::canFoldMemoryOperand(MachineInstr *MI, + SmallVectorImpl &Ops) const { // Check switch flag if (NoFusing) return 0; - const DenseMap *OpcodeTablePtr = NULL; + + if (Ops.size() == 2 && Ops[0] == 0 && Ops[1] == 1) { + switch (MI->getOpcode()) { + default: return false; + case X86::TEST8rr: + case X86::TEST16rr: + case X86::TEST32rr: + case X86::TEST64rr: + return true; + } + } + + if (Ops.size() != 1) + return false; + + unsigned OpNum = Ops[0]; + unsigned Opc = MI->getOpcode(); unsigned NumOps = TII.getNumOperands(Opc); bool isTwoAddr = NumOps > 1 && TII.getOperandConstraint(Opc, 1, TOI::TIED_TO) != -1; @@ -1207,18 +1224,16 @@ unsigned X86RegisterInfo::getOpcodeAfterMemoryFold(unsigned Opc, // Folding a memory location into the two-address part of a two-address // instruction is different than folding it other places. It requires // replacing the *two* registers with the memory location. + const DenseMap *OpcodeTablePtr = NULL; if (isTwoAddr && NumOps >= 2 && OpNum < 2) { OpcodeTablePtr = &RegOp2MemOpTable2Addr; } else if (OpNum == 0) { // If operand 0 switch (Opc) { case X86::MOV16r0: - return X86::MOV16mi; case X86::MOV32r0: - return X86::MOV32mi; case X86::MOV64r0: - return X86::MOV64mi32; case X86::MOV8r0: - return X86::MOV8mi; + return true; default: break; } OpcodeTablePtr = &RegOp2MemOpTable0; @@ -1233,9 +1248,9 @@ unsigned X86RegisterInfo::getOpcodeAfterMemoryFold(unsigned Opc, DenseMap::iterator I = OpcodeTablePtr->find((unsigned*)Opc); if (I != OpcodeTablePtr->end()) - return I->second; + return true; } - return 0; + return false; } bool X86RegisterInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, @@ -1335,7 +1350,7 @@ bool X86RegisterInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, const TargetOperandInfo &DstTOI = TID.OpInfo[0]; const TargetRegisterClass *DstRC = (DstTOI.Flags & M_LOOK_UP_PTR_REG_CLASS) ? TII.getPointerRegClass() : getRegClass(DstTOI.RegClass); - storeRegToAddr(MF, Reg, AddrOps, DstRC, NewMIs); + storeRegToAddr(MF, Reg, true, AddrOps, DstRC, NewMIs); } return true; diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h index c74d2e769df..eda48c20e24 100644 --- a/lib/Target/X86/X86RegisterInfo.h +++ b/lib/Target/X86/X86RegisterInfo.h @@ -101,10 +101,10 @@ public: void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIndex, + unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; @@ -148,11 +148,9 @@ public: SmallVectorImpl &Ops, MachineInstr* LoadMI) const; - /// getOpcodeAfterMemoryFold - Returns the opcode of the would be new - /// instruction after load / store is folded into an instruction of the - /// specified opcode. It returns zero if the specified unfolding is not - /// possible. - unsigned getOpcodeAfterMemoryFold(unsigned Opc, unsigned OpNum) const; + /// canFoldMemoryOperand - Returns true if the specified load / store is + /// folding is possible. + bool canFoldMemoryOperand(MachineInstr*, SmallVectorImpl &) const; /// unfoldMemoryOperand - Separate a single instruction which folded a load or /// a store or a load and a store into two or more instruction. If this is