diff options
Diffstat (limited to 'llvm/lib/Target')
| -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.    ///  | 

