diff options
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/R600/SIInstrInfo.cpp | 83 | ||||
| -rw-r--r-- | llvm/lib/Target/R600/SIInstrInfo.h | 8 | 
2 files changed, 91 insertions, 0 deletions
diff --git a/llvm/lib/Target/R600/SIInstrInfo.cpp b/llvm/lib/Target/R600/SIInstrInfo.cpp index 94f7d6920ab..c32c6855a5c 100644 --- a/llvm/lib/Target/R600/SIInstrInfo.cpp +++ b/llvm/lib/Target/R600/SIInstrInfo.cpp @@ -23,6 +23,7 @@  #include "llvm/IR/Function.h"  #include "llvm/CodeGen/RegisterScavenging.h"  #include "llvm/MC/MCInstrDesc.h" +#include "llvm/Support/Debug.h"  using namespace llvm; @@ -832,6 +833,88 @@ SIInstrInfo::isTriviallyReMaterializable(const MachineInstr *MI,    }  } +static bool offsetsDoNotOverlap(int WidthA, int OffsetA, +                                int WidthB, int OffsetB) { +  int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB; +  int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA; +  int LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB; +  return LowOffset + LowWidth <= HighOffset; +} + +bool SIInstrInfo::checkInstOffsetsDoNotOverlap(MachineInstr *MIa, +                                               MachineInstr *MIb) const { +  unsigned BaseReg0, Offset0; +  unsigned BaseReg1, Offset1; + +  if (getLdStBaseRegImmOfs(MIa, BaseReg0, Offset0, &RI) && +      getLdStBaseRegImmOfs(MIb, BaseReg1, Offset1, &RI)) { +    assert(MIa->hasOneMemOperand() && MIb->hasOneMemOperand() && +           "read2 / write2 not expected here yet"); +    unsigned Width0 = (*MIa->memoperands_begin())->getSize(); +    unsigned Width1 = (*MIb->memoperands_begin())->getSize(); +    if (BaseReg0 == BaseReg1 && +        offsetsDoNotOverlap(Width0, Offset0, Width1, Offset1)) { +      return true; +    } +  } + +  return false; +} + +bool SIInstrInfo::areMemAccessesTriviallyDisjoint(MachineInstr *MIa, +                                                  MachineInstr *MIb, +                                                  AliasAnalysis *AA) const { +  unsigned Opc0 = MIa->getOpcode(); +  unsigned Opc1 = MIb->getOpcode(); + +  assert(MIa && (MIa->mayLoad() || MIa->mayStore()) && +         "MIa must load from or modify a memory location"); +  assert(MIb && (MIb->mayLoad() || MIb->mayStore()) && +         "MIb must load from or modify a memory location"); + +  if (MIa->hasUnmodeledSideEffects() || MIb->hasUnmodeledSideEffects()) +    return false; + +  // XXX - Can we relax this between address spaces? +  if (MIa->hasOrderedMemoryRef() || MIb->hasOrderedMemoryRef()) +    return false; + +  // TODO: Should we check the address space from the MachineMemOperand? That +  // would allow us to distinguish objects we know don't alias based on the +  // underlying addres space, even if it was lowered to a different one, +  // e.g. private accesses lowered to use MUBUF instructions on a scratch +  // buffer. +  if (isDS(Opc0)) { +    if (isDS(Opc1)) +      return checkInstOffsetsDoNotOverlap(MIa, MIb); + +    return !isFLAT(Opc1); +  } + +  if (isMUBUF(Opc0) || isMTBUF(Opc0)) { +    if (isMUBUF(Opc1) || isMTBUF(Opc1)) +      return checkInstOffsetsDoNotOverlap(MIa, MIb); + +    return !isFLAT(Opc1) && !isSMRD(Opc1); +  } + +  if (isSMRD(Opc0)) { +    if (isSMRD(Opc1)) +      return checkInstOffsetsDoNotOverlap(MIa, MIb); + +    return !isFLAT(Opc1) && !isMUBUF(Opc0) && !isMTBUF(Opc0); +  } + +  if (isFLAT(Opc0)) { +    if (isFLAT(Opc1)) +      return checkInstOffsetsDoNotOverlap(MIa, MIb); + +    return false; +  } + +  return false; +} +  namespace llvm {  namespace AMDGPU {  // Helper function generated by tablegen.  We are wrapping this with diff --git a/llvm/lib/Target/R600/SIInstrInfo.h b/llvm/lib/Target/R600/SIInstrInfo.h index ce32fd7fa65..3bdbc9b5498 100644 --- a/llvm/lib/Target/R600/SIInstrInfo.h +++ b/llvm/lib/Target/R600/SIInstrInfo.h @@ -57,6 +57,9 @@ private:    void addDescImplicitUseDef(const MCInstrDesc &Desc, MachineInstr *MI) const; +  bool checkInstOffsetsDoNotOverlap(MachineInstr *MIa, +                                    MachineInstr *MIb) const; +    unsigned findUsedSGPR(const MachineInstr *MI, int OpIndices[3]) const;  public: @@ -115,6 +118,10 @@ public:    bool isTriviallyReMaterializable(const MachineInstr *MI,                                     AliasAnalysis *AA = nullptr) const; +  bool areMemAccessesTriviallyDisjoint( +    MachineInstr *MIa, MachineInstr *MIb, +    AliasAnalysis *AA = nullptr) const override; +    MachineInstr *buildMovInstr(MachineBasicBlock *MBB,                                MachineBasicBlock::iterator I,                                unsigned DstReg, unsigned SrcReg) const override; @@ -131,6 +138,7 @@ public:    bool isVOP2(uint16_t Opcode) const;    bool isVOP3(uint16_t Opcode) const;    bool isVOPC(uint16_t Opcode) const; +    bool isInlineConstant(const APInt &Imm) const;    bool isInlineConstant(const MachineOperand &MO) const;    bool isLiteralConstant(const MachineOperand &MO) const;  | 

