diff options
| author | QingShan Zhang <qshanz@cn.ibm.com> | 2019-07-02 03:28:52 +0000 |
|---|---|---|
| committer | QingShan Zhang <qshanz@cn.ibm.com> | 2019-07-02 03:28:52 +0000 |
| commit | 7fdb3a293b27d551d1657392243496b4a7164802 (patch) | |
| tree | 52345365866f7cd4a603a5bd218fff5cbd26fa73 /llvm/lib | |
| parent | 2a622b30e3b419a0699b78f039f234bf35fe283b (diff) | |
| download | bcm5719-llvm-7fdb3a293b27d551d1657392243496b4a7164802.tar.gz bcm5719-llvm-7fdb3a293b27d551d1657392243496b4a7164802.zip | |
[PowerPC] Implement the areMemAccessesTriviallyDisjoint hook
After implemented this hook, we will model the memory dependency in the scheduling dependency graph more precise,
and will have more opportunity to reorder the load/stores, as they didn't have the dependency at some condition
Differential Revision: https://reviews.llvm.org/D63804
llvm-svn: 364886
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | 56 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrInfo.h | 16 |
2 files changed, 72 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp index 22921ace75f..2658a85303f 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -3996,3 +3996,59 @@ unsigned PPCInstrInfo::reduceLoopCount( return LoopCountReg; } +// Return true if get the base operand, byte offset of an instruction and the +// memory width. Width is the size of memory that is being loaded/stored. +bool PPCInstrInfo::getMemOperandWithOffsetWidth( + const MachineInstr &LdSt, + const MachineOperand *&BaseReg, + int64_t &Offset, + unsigned &Width, + const TargetRegisterInfo *TRI) const { + assert(LdSt.mayLoadOrStore() && "Expected a memory operation."); + + // Handle only loads/stores with base register followed by immediate offset. + if (LdSt.getNumExplicitOperands() != 3) + return false; + if (!LdSt.getOperand(1).isImm() || !LdSt.getOperand(2).isReg()) + return false; + + if (!LdSt.hasOneMemOperand()) + return false; + + Width = (*LdSt.memoperands_begin())->getSize(); + Offset = LdSt.getOperand(1).getImm(); + BaseReg = &LdSt.getOperand(2); + return true; +} + +bool PPCInstrInfo::areMemAccessesTriviallyDisjoint( + const MachineInstr &MIa, const MachineInstr &MIb, + AliasAnalysis * /*AA*/) const { + assert(MIa.mayLoadOrStore() && "MIa must be a load or store."); + assert(MIb.mayLoadOrStore() && "MIb must be a load or store."); + + if (MIa.hasUnmodeledSideEffects() || MIb.hasUnmodeledSideEffects() || + MIa.hasOrderedMemoryRef() || MIb.hasOrderedMemoryRef()) + return false; + + // Retrieve the base register, offset from the base register and width. Width + // is the size of memory that is being loaded/stored (e.g. 1, 2, 4). If + // base registers are identical, and the offset of a lower memory access + + // the width doesn't overlap the offset of a higher memory access, + // then the memory accesses are different. + const TargetRegisterInfo *TRI = &getRegisterInfo(); + const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr; + int64_t OffsetA = 0, OffsetB = 0; + unsigned int WidthA = 0, WidthB = 0; + if (getMemOperandWithOffsetWidth(MIa, BaseOpA, OffsetA, WidthA, TRI) && + getMemOperandWithOffsetWidth(MIb, BaseOpB, OffsetB, WidthB, TRI)) { + if (BaseOpA->isIdenticalTo(*BaseOpB)) { + int LowOffset = std::min(OffsetA, OffsetB); + int HighOffset = std::max(OffsetA, OffsetB); + int LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB; + if (LowOffset + LowWidth <= HighOffset) + return true; + } + } + return false; +} diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.h b/llvm/lib/Target/PowerPC/PPCInstrInfo.h index 78b04c2c1ca..70fb757e8f1 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.h +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.h @@ -357,6 +357,22 @@ public: unsigned SrcReg2, int Mask, int Value, const MachineRegisterInfo *MRI) const override; + + /// Return true if get the base operand, byte offset of an instruction and + /// the memory width. Width is the size of memory that is being + /// loaded/stored (e.g. 1, 2, 4, 8). + bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, + const MachineOperand *&BaseOp, + int64_t &Offset, unsigned &Width, + const TargetRegisterInfo *TRI) const; + + /// Return true if two MIs access different memory addresses and false + /// otherwise + bool + areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, + const MachineInstr &MIb, + AliasAnalysis *AA = nullptr) const override; + /// GetInstSize - Return the number of bytes of code the specified /// instruction may be. This returns the maximum number of bytes. /// |

