Index: include/llvm/Target/TargetInstrInfo.h =================================================================== --- include/llvm/Target/TargetInstrInfo.h +++ include/llvm/Target/TargetInstrInfo.h @@ -832,6 +832,16 @@ return false; } + /// Get the base register and byte offset of an instruction that reads/writes + /// memory. This is similar to getLdStBaseRegImmOfs, but also works on memory + /// instructions that have been folded into other non-memory operations, like + /// arithmetic. + virtual bool getMemOpBaseRegImmOfs(MachineInstr *MemOp, bool &IsLoadingOp, + unsigned &BaseReg, unsigned &Offset, + const TargetRegisterInfo *TRI) const { + return false; + } + virtual bool enableClusterLoads() const { return false; } virtual bool shouldClusterLoads(MachineInstr *FirstLdSt, Index: lib/Target/X86/X86InstrInfo.h =================================================================== --- lib/Target/X86/X86InstrInfo.h +++ lib/Target/X86/X86InstrInfo.h @@ -254,6 +254,10 @@ MachineBasicBlock *&FBB, SmallVectorImpl &Cond, bool AllowModify) const override; + + bool getMemOpBaseRegImmOfs(MachineInstr *LdSt, bool &IsLoadOp, + unsigned &BaseReg, unsigned &Offset, + const TargetRegisterInfo *TRI) const override; unsigned RemoveBranch(MachineBasicBlock &MBB) const override; unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, Index: lib/Target/X86/X86InstrInfo.cpp =================================================================== --- lib/Target/X86/X86InstrInfo.cpp +++ lib/Target/X86/X86InstrInfo.cpp @@ -3961,6 +3961,51 @@ } } +bool X86InstrInfo::getMemOpBaseRegImmOfs(MachineInstr *MemOp, bool &IsLoadingOp, + unsigned &BaseReg, unsigned &Offset, + const TargetRegisterInfo *TRI) const { + unsigned MemRefBegin = -1; + + switch (MemOp->getOpcode()) { + default: + return false; // cannot parse this instruction + + case X86::MOV64rm: + case X86::MOV32rm: + case X86::MOV16rm: + IsLoadingOp = true; + MemRefBegin = 1; + break; + + case X86::ADD64rm: + case X86::ADD32rm: + case X86::ADD16rm: + IsLoadingOp = true; + MemRefBegin = 2; + break; + } + + BaseReg = MemOp->getOperand(MemRefBegin + X86::AddrBaseReg).getReg(); + + if (MemOp->getOperand(MemRefBegin + X86::AddrScaleAmt).getImm() != 1) + return false; + + if (MemOp->getOperand(MemRefBegin + X86::AddrIndexReg).getReg() != + X86::NoRegister) + return false; + + const MachineOperand &DispMO = MemOp->getOperand(MemRefBegin + X86::AddrDisp); + + // Displacement can be symbolic + if (!DispMO.isImm()) + return false; + + Offset = DispMO.getImm(); + + return (MemOp->getOperand(MemRefBegin + X86::AddrIndexReg).getReg() == + X86::NoRegister); +} + static unsigned getStoreRegOpcode(unsigned SrcReg, const TargetRegisterClass *RC, bool isStackAligned,