[PATCH] R600/SI: Implement getLdStBaseRegImmOfs for LDS

Tom Stellard tom at stellard.net
Mon Jul 28 07:13:20 PDT 2014


On Sat, Jul 26, 2014 at 10:30:01PM +0000, Matt Arsenault wrote:
> Theoretically this should help with load / store clustering, but so far I haven't managed to get it to do anything. This will also be used to help with using read2 / write2 instructions
> 
> http://reviews.llvm.org/D4686
> 
> Files:
>   lib/Target/R600/SIInstrInfo.cpp
>   lib/Target/R600/SIInstrInfo.h
> 
> Index: lib/Target/R600/SIInstrInfo.cpp
> ===================================================================
> --- lib/Target/R600/SIInstrInfo.cpp
> +++ lib/Target/R600/SIInstrInfo.cpp
> @@ -32,6 +32,38 @@
>  // TargetInstrInfo callbacks
>  //===----------------------------------------------------------------------===//
>  
> +bool SIInstrInfo::getLdStBaseRegImmOfs(MachineInstr *LdSt,
> +                                       unsigned &BaseReg, unsigned &Offset,
> +                                       const TargetRegisterInfo *TRI) const {
> +  // TODO: Other address spaces.
> +  unsigned Opc = LdSt->getOpcode();
> +  if (isDS(Opc)) {
> +    switch (Opc) {
> +    case AMDGPU::DS_READ_B32:
> +    case AMDGPU::DS_READ_B64:
> +    case AMDGPU::DS_READ_I16:
> +    case AMDGPU::DS_READ_U16:
> +    case AMDGPU::DS_READ_I8:
> +    case AMDGPU::DS_READ_U8:
> +      BaseReg = LdSt->getOperand(2).getReg(); // addr
> +      Offset = LdSt->getOperand(3).getImm(); // offset
> +      return true;
> +    case AMDGPU::DS_WRITE_B32:
> +    case AMDGPU::DS_WRITE_B64:
> +    case AMDGPU::DS_WRITE_B16:
> +    case AMDGPU::DS_WRITE_B8:
> +      BaseReg = LdSt->getOperand(1).getReg(); // addr
> +      Offset = LdSt->getOperand(3).getImm(); // offset
> +      return true;
> +    default:
> +      // Skip read2 / write2 and atomics.
> +      return false;
> +    }

You could set the UseNamedOperandTable  bit for DS instructions and
use SIInstrInfo::getNamedOperand here and avoid the switch statement.
This way it will work for atomics too.

You'll still need special handling for read2 / write2, which
has fields named offset0 and offset1 instead of offset.

-Tom

> +  }
> +
> +  return false;
> +}
> +
>  void
>  SIInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
>                           MachineBasicBlock::iterator MI, DebugLoc DL,
> Index: lib/Target/R600/SIInstrInfo.h
> ===================================================================
> --- lib/Target/R600/SIInstrInfo.h
> +++ lib/Target/R600/SIInstrInfo.h
> @@ -62,6 +62,11 @@
>      return RI;
>    }
>  
> +  bool getLdStBaseRegImmOfs(MachineInstr *LdSt,
> +                            unsigned &BaseReg, unsigned &Offset,
> +                            const TargetRegisterInfo *TRI) const override;
> +
> +
>    void copyPhysReg(MachineBasicBlock &MBB,
>                     MachineBasicBlock::iterator MI, DebugLoc DL,
>                     unsigned DestReg, unsigned SrcReg,

> Index: lib/Target/R600/SIInstrInfo.cpp
> ===================================================================
> --- lib/Target/R600/SIInstrInfo.cpp
> +++ lib/Target/R600/SIInstrInfo.cpp
> @@ -32,6 +32,38 @@
>  // TargetInstrInfo callbacks
>  //===----------------------------------------------------------------------===//
>  
> +bool SIInstrInfo::getLdStBaseRegImmOfs(MachineInstr *LdSt,
> +                                       unsigned &BaseReg, unsigned &Offset,
> +                                       const TargetRegisterInfo *TRI) const {
> +  // TODO: Other address spaces.
> +  unsigned Opc = LdSt->getOpcode();
> +  if (isDS(Opc)) {
> +    switch (Opc) {
> +    case AMDGPU::DS_READ_B32:
> +    case AMDGPU::DS_READ_B64:
> +    case AMDGPU::DS_READ_I16:
> +    case AMDGPU::DS_READ_U16:
> +    case AMDGPU::DS_READ_I8:
> +    case AMDGPU::DS_READ_U8:
> +      BaseReg = LdSt->getOperand(2).getReg(); // addr
> +      Offset = LdSt->getOperand(3).getImm(); // offset
> +      return true;
> +    case AMDGPU::DS_WRITE_B32:
> +    case AMDGPU::DS_WRITE_B64:
> +    case AMDGPU::DS_WRITE_B16:
> +    case AMDGPU::DS_WRITE_B8:
> +      BaseReg = LdSt->getOperand(1).getReg(); // addr
> +      Offset = LdSt->getOperand(3).getImm(); // offset
> +      return true;
> +    default:
> +      // Skip read2 / write2 and atomics.
> +      return false;
> +    }
> +  }
> +
> +  return false;
> +}
> +
>  void
>  SIInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
>                           MachineBasicBlock::iterator MI, DebugLoc DL,
> Index: lib/Target/R600/SIInstrInfo.h
> ===================================================================
> --- lib/Target/R600/SIInstrInfo.h
> +++ lib/Target/R600/SIInstrInfo.h
> @@ -62,6 +62,11 @@
>      return RI;
>    }
>  
> +  bool getLdStBaseRegImmOfs(MachineInstr *LdSt,
> +                            unsigned &BaseReg, unsigned &Offset,
> +                            const TargetRegisterInfo *TRI) const override;
> +
> +
>    void copyPhysReg(MachineBasicBlock &MBB,
>                     MachineBasicBlock::iterator MI, DebugLoc DL,
>                     unsigned DestReg, unsigned SrcReg,

> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list