Index: include/llvm/Target/TargetInstrInfo.h =================================================================== --- include/llvm/Target/TargetInstrInfo.h +++ include/llvm/Target/TargetInstrInfo.h @@ -1092,16 +1092,12 @@ } /// Used by MachineScheduler to determine if it should attempt to cluster - /// these memory operations. Implementation of this callback is needed - /// when an instruction requires a fully calculated address and does not - /// have separate base register and offset operands. If it does have - /// separate offset field the getMemOpBaseRegImmOfs should suffice. + /// these memory operations. Arguments are two candidate instructions + /// and base registers as returned by the getMemOpBaseRegImmOfs. virtual bool doMemOpsHaveSameBasePtr(const MachineInstr &MI1, unsigned BaseReg1, const MachineInstr &MI2, - unsigned BaseReg2) const { - return BaseReg1 == BaseReg2; - } + unsigned BaseReg2) const; /// Returns true if the two given memory operations should be scheduled /// adjacent. Note that you have to add: Index: lib/CodeGen/TargetInstrInfo.cpp =================================================================== --- lib/CodeGen/TargetInstrInfo.cpp +++ lib/CodeGen/TargetInstrInfo.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineMemOperand.h" @@ -644,6 +645,39 @@ hasReassociableSibling(Inst, Commuted); } +/// Used by MachineScheduler to determine if it should attempt to cluster +/// these memory operations. Arguments are two candidate instructions +/// and base registers as returned by the getMemOpBaseRegImmOfs. +bool TargetInstrInfo::doMemOpsHaveSameBasePtr(const MachineInstr &MI1, + unsigned BaseReg1, + const MachineInstr &MI2, + unsigned BaseReg2) const { + if (BaseReg1 == BaseReg2) + return true; + + if (!MI1.hasOneMemOperand() || !MI2.hasOneMemOperand()) + return false; + + auto MO1 = *MI1.memoperands_begin(); + auto MO2 = *MI2.memoperands_begin(); + if (MO1->getAddrSpace() != MO2->getAddrSpace()) + return false; + + auto Base1 = MO1->getValue(); + auto Base2 = MO2->getValue(); + if (!Base1 || !Base2) + return false; + const MachineFunction &MF = *MI1.getParent()->getParent(); + const DataLayout &DL = MF.getFunction()->getParent()->getDataLayout(); + Base1 = GetUnderlyingObject(Base1, DL); + Base2 = GetUnderlyingObject(Base1, DL); + + if (isa(Base1) || isa(Base2)) + return false; + + return Base1 == Base2; +} + // The concept of the reassociation pass is that these operations can benefit // from this kind of transformation: // Index: lib/Target/AArch64/AArch64InstrInfo.h =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.h +++ lib/Target/AArch64/AArch64InstrInfo.h @@ -242,6 +242,12 @@ bool getMemOpInfo(unsigned Opcode, unsigned &Scale, unsigned &Width, int64_t &MinOffset, int64_t &MaxOffset) const; + bool doMemOpsHaveSameBasePtr(const MachineInstr &SU1, unsigned BaseReg1, + const MachineInstr &SU2, unsigned BaseReg2) + const final { + return BaseReg1 == BaseReg2; + } + bool shouldClusterMemOps(MachineInstr &FirstLdSt, MachineInstr &SecondLdSt, unsigned NumLoads) const override; Index: lib/Target/AMDGPU/SIInstrInfo.h =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.h +++ lib/Target/AMDGPU/SIInstrInfo.h @@ -151,10 +151,6 @@ int64_t &Offset, const TargetRegisterInfo *TRI) const final; - bool doMemOpsHaveSameBasePtr(const MachineInstr &SU1, unsigned BaseReg1, - const MachineInstr &SU2, unsigned BaseReg2) - const final; - bool shouldClusterMemOps(MachineInstr &FirstLdSt, MachineInstr &SecondLdSt, unsigned NumLoads) const final; Index: lib/Target/AMDGPU/SIInstrInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.cpp +++ lib/Target/AMDGPU/SIInstrInfo.cpp @@ -27,7 +27,6 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/MemoryLocation.h" -#include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" @@ -357,36 +356,6 @@ return false; } -bool SIInstrInfo::doMemOpsHaveSameBasePtr(const MachineInstr &MI1, - unsigned BaseReg1, - const MachineInstr &MI2, - unsigned BaseReg2) const { - if (BaseReg1 == BaseReg2) - return true; - - if (!MI1.hasOneMemOperand() || !MI2.hasOneMemOperand()) - return false; - - auto MO1 = *MI1.memoperands_begin(); - auto MO2 = *MI2.memoperands_begin(); - if (MO1->getAddrSpace() != MO2->getAddrSpace()) - return false; - - auto Base1 = MO1->getValue(); - auto Base2 = MO2->getValue(); - if (!Base1 || !Base2) - return false; - const MachineFunction &MF = *MI1.getParent()->getParent(); - const DataLayout &DL = MF.getFunction()->getParent()->getDataLayout(); - Base1 = GetUnderlyingObject(Base1, DL); - Base2 = GetUnderlyingObject(Base1, DL); - - if (isa(Base1) || isa(Base2)) - return false; - - return Base1 == Base2; -} - bool SIInstrInfo::shouldClusterMemOps(MachineInstr &FirstLdSt, MachineInstr &SecondLdSt, unsigned NumLoads) const {