diff options
author | Evan Cheng <evan.cheng@apple.com> | 2007-08-30 05:54:07 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2007-08-30 05:54:07 +0000 |
commit | dabe160c9e044db002b48b18c3b029ca04e24698 (patch) | |
tree | c53adf4dc7736250e5c1bba9605f57a7715769e2 | |
parent | 03225435be9dcdfb38223e3bce8eaa0489f7fbad (diff) | |
download | external_llvm-dabe160c9e044db002b48b18c3b029ca04e24698.zip external_llvm-dabe160c9e044db002b48b18c3b029ca04e24698.tar.gz external_llvm-dabe160c9e044db002b48b18c3b029ca04e24698.tar.bz2 |
Added support to fold X86 load / store instructions. This allow rematerialized loads to be folded into their uses.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41599 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/X86/X86RegisterInfo.cpp | 135 | ||||
-rw-r--r-- | lib/Target/X86/X86RegisterInfo.h | 13 | ||||
-rw-r--r-- | test/CodeGen/X86/constant-pool-remat-0.ll | 3 |
3 files changed, 101 insertions, 50 deletions
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 11c7547..b4006f3 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -270,63 +270,81 @@ void X86RegisterInfo::reMaterialize(MachineBasicBlock &MBB, MBB.insert(I, MI); } -static MachineInstr *FuseTwoAddrInst(unsigned Opcode, unsigned FrameIndex, - MachineInstr *MI, - const TargetInstrInfo &TII) { +static const MachineInstrBuilder &FuseInstrAddOperand(MachineInstrBuilder &MIB, + MachineOperand &MO) { + if (MO.isReg()) + MIB = MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit()); + else if (MO.isImm()) + 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<MachineOperand,4> &MOs, + MachineInstr *MI, const TargetInstrInfo &TII) { unsigned NumOps = TII.getNumOperands(MI->getOpcode())-2; + // Create the base instruction with the memory operand as the first part. - MachineInstrBuilder MIB = addFrameReference(BuildMI(TII.get(Opcode)), - FrameIndex); + MachineInstrBuilder MIB = BuildMI(TII.get(Opcode)); + unsigned NumAddrOps = MOs.size(); + for (unsigned i = 0; i != NumAddrOps; ++i) + MIB = FuseInstrAddOperand(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); - if (MO.isReg()) - MIB = MIB.addReg(MO.getReg(), false, MO.isImplicit()); - else if (MO.isImm()) - MIB = MIB.addImm(MO.getImm()); - else if (MO.isGlobalAddress()) - MIB = MIB.addGlobalAddress(MO.getGlobal(), 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 type!"); + MIB = FuseInstrAddOperand(MIB, MO); } return MIB; } static MachineInstr *FuseInst(unsigned Opcode, unsigned OpNo, - unsigned FrameIndex, MachineInstr *MI, - const TargetInstrInfo &TII) { + SmallVector<MachineOperand,4> &MOs, + MachineInstr *MI, const TargetInstrInfo &TII) { MachineInstrBuilder MIB = BuildMI(TII.get(Opcode)); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand &MO = MI->getOperand(i); if (i == OpNo) { assert(MO.isReg() && "Expected to fold into reg operand!"); - MIB = addFrameReference(MIB, FrameIndex); - } else if (MO.isReg()) - MIB = MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit()); - else if (MO.isImm()) - MIB = MIB.addImm(MO.getImm()); - else if (MO.isGlobalAddress()) - MIB = MIB.addGlobalAddress(MO.getGlobal(), 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!"); + unsigned NumAddrOps = MOs.size(); + for (unsigned i = 0; i != NumAddrOps; ++i) + MIB = FuseInstrAddOperand(MIB, MOs[i]); + if (NumAddrOps < 4) // FrameIndex only + MIB.addImm(1).addReg(0).addImm(0); + } else { + MIB = FuseInstrAddOperand(MIB, MO); + } } return MIB; } -static MachineInstr *MakeM0Inst(const TargetInstrInfo &TII, - unsigned Opcode, unsigned FrameIndex, +static MachineInstr *MakeM0Inst(const TargetInstrInfo &TII, unsigned Opcode, + SmallVector<MachineOperand,4> &MOs, MachineInstr *MI) { - return addFrameReference(BuildMI(TII.get(Opcode)), FrameIndex).addImm(0); + MachineInstrBuilder MIB = BuildMI(TII.get(Opcode)); + + unsigned NumAddrOps = MOs.size(); + for (unsigned i = 0; i != NumAddrOps; ++i) + MIB = FuseInstrAddOperand(MIB, MOs[i]); + if (NumAddrOps < 4) // FrameIndex only + MIB.addImm(1).addReg(0).addImm(0); + return MIB.addImm(0); } @@ -390,13 +408,9 @@ static const TableEntry *TableLookup(const TableEntry *Table, unsigned N, } #endif - -MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, - unsigned i, - int FrameIndex) const { - // Check switch flag - if (NoFusing) return NULL; - +MachineInstr* +X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned i, + SmallVector<MachineOperand,4> &MOs) const { // Table (and size) to search const TableEntry *OpcodeTablePtr = NULL; unsigned OpcodeTableSize = 0; @@ -412,7 +426,7 @@ MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, if (isTwoAddr && NumOps >= 2 && i < 2 && MI->getOperand(0).isReg() && MI->getOperand(1).isReg() && - MI->getOperand(0).getReg() == MI->getOperand(1).getReg()) { + MI->getOperand(0).getReg() == MI->getOperand(1).getReg()) { static const TableEntry OpcodeTable[] = { { X86::ADC32ri, X86::ADC32mi }, { X86::ADC32ri8, X86::ADC32mi8 }, @@ -580,13 +594,13 @@ MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, isTwoAddrFold = true; } else if (i == 0) { // If operand 0 if (MI->getOpcode() == X86::MOV16r0) - NewMI = MakeM0Inst(TII, X86::MOV16mi, FrameIndex, MI); + NewMI = MakeM0Inst(TII, X86::MOV16mi, MOs, MI); else if (MI->getOpcode() == X86::MOV32r0) - NewMI = MakeM0Inst(TII, X86::MOV32mi, FrameIndex, MI); + NewMI = MakeM0Inst(TII, X86::MOV32mi, MOs, MI); else if (MI->getOpcode() == X86::MOV64r0) - NewMI = MakeM0Inst(TII, X86::MOV64mi32, FrameIndex, MI); + NewMI = MakeM0Inst(TII, X86::MOV64mi32, MOs, MI); else if (MI->getOpcode() == X86::MOV8r0) - NewMI = MakeM0Inst(TII, X86::MOV8mi, FrameIndex, MI); + NewMI = MakeM0Inst(TII, X86::MOV8mi, MOs, MI); if (NewMI) { NewMI->copyKillDeadInfo(MI); return NewMI; @@ -658,6 +672,7 @@ MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, { X86::XCHG64rr, X86::XCHG64mr }, { X86::XCHG8rr, X86::XCHG8mr } }; + ASSERT_SORTED(OpcodeTable); OpcodeTablePtr = OpcodeTable; OpcodeTableSize = ARRAY_SIZE(OpcodeTable); @@ -766,6 +781,7 @@ MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, { X86::XCHG64rr, X86::XCHG64rm }, { X86::XCHG8rr, X86::XCHG8rm } }; + ASSERT_SORTED(OpcodeTable); OpcodeTablePtr = OpcodeTable; OpcodeTableSize = ARRAY_SIZE(OpcodeTable); @@ -960,6 +976,7 @@ MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, { X86::XORPDrr, X86::XORPDrm }, { X86::XORPSrr, X86::XORPSrm } }; + ASSERT_SORTED(OpcodeTable); OpcodeTablePtr = OpcodeTable; OpcodeTableSize = ARRAY_SIZE(OpcodeTable); @@ -973,9 +990,9 @@ MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, if (const TableEntry *Entry = TableLookup(OpcodeTablePtr, OpcodeTableSize, fromOpcode)) { if (isTwoAddrFold) - NewMI = FuseTwoAddrInst(Entry->to, FrameIndex, MI, TII); + NewMI = FuseTwoAddrInst(Entry->to, MOs, MI, TII); else - NewMI = FuseInst(Entry->to, i, FrameIndex, MI, TII); + NewMI = FuseInst(Entry->to, i, MOs, MI, TII); NewMI->copyKillDeadInfo(MI); return NewMI; } @@ -989,6 +1006,26 @@ MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, } +MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNum, + int FrameIndex) const { + // Check switch flag + if (NoFusing) return NULL; + SmallVector<MachineOperand,4> MOs; + MOs.push_back(MachineOperand::CreateFrameIndex(FrameIndex)); + return foldMemoryOperand(MI, OpNum, MOs); +} + +MachineInstr* X86RegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNum, + MachineInstr *LoadMI) const { + // Check switch flag + if (NoFusing) return NULL; + SmallVector<MachineOperand,4> MOs; + unsigned NumOps = TII.getNumOperands(LoadMI->getOpcode()); + for (unsigned i = NumOps - 4; i != NumOps; ++i) + MOs.push_back(LoadMI->getOperand(i)); + return foldMemoryOperand(MI, OpNum, MOs); +} + 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 bcfba24..462bcc3 100644 --- a/lib/Target/X86/X86RegisterInfo.h +++ b/lib/Target/X86/X86RegisterInfo.h @@ -14,6 +14,7 @@ #ifndef X86REGISTERINFO_H #define X86REGISTERINFO_H +#include "llvm/ADT/SmallVector.h" #include "llvm/Target/MRegisterInfo.h" #include "X86GenRegisterInfo.h.inc" @@ -92,6 +93,13 @@ public: unsigned OpNum, int FrameIndex) const; + /// foldMemoryOperand - Same as the previous version except it allows folding + /// of any load and store from / to any address, not just from a specific + /// stack slot. + MachineInstr* foldMemoryOperand(MachineInstr* MI, + unsigned OpNum, + MachineInstr* LoadMI) 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; @@ -132,6 +140,11 @@ public: // Exception handling queries. unsigned getEHExceptionRegister() const; unsigned getEHHandlerRegister() const; + +private: + MachineInstr* foldMemoryOperand(MachineInstr* MI, + unsigned OpNum, + SmallVector<MachineOperand,4> &MOs) const; }; // getX86SubSuperRegister - X86 utility function. It returns the sub or super diff --git a/test/CodeGen/X86/constant-pool-remat-0.ll b/test/CodeGen/X86/constant-pool-remat-0.ll index fbc660f..8007720 100644 --- a/test/CodeGen/X86/constant-pool-remat-0.ll +++ b/test/CodeGen/X86/constant-pool-remat-0.ll @@ -1,6 +1,7 @@ ; RUN: llvm-as < %s | llc -march=x86-64 | grep LCPI | count 3 +; RUN: llvm-as < %s | llc -march=x86-64 -stats -info-output-file - | grep asm-printer | grep 6 ; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep LCPI | count 3 -; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -stats -info-output-file - | grep asm-printer | grep 9 +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -stats -info-output-file - | grep asm-printer | grep 8 declare fastcc float @qux(float %y) |