PATCH: R600/SI: Do abs/neg folding with ComplexPatterns

Matt Arsenault Matthew.Arsenault at amd.com
Wed Jul 30 12:36:45 PDT 2014


On 07/29/2014 08:40 PM, Tom Stellard wrote:
>
> In my updated patch I've removed a few layers of inheritance.  The VOP*Inst
> classes still exist, but if you need to make define a custom instruction, you
> can use the VOP*_Helper classes which let you specify the ins, outs, asm,
> and patterns directly.
>
> I've also added a VOPProfile class that can be used for specifying the
> operands for an instruction.
>
LGTM except for 3 typos I found. The new patterns are still impressively 
complicated, but I don't have any better ideas


> diff --git a/lib/Target/R600/SIInstrInfo.cpp b/lib/Target/R600/SIInstrInfo.cpp
> index 06529a2..b9ebc0f 100644
> --- a/lib/Target/R600/SIInstrInfo.cpp
> +++ b/lib/Target/R600/SIInstrInfo.cpp
> @@ -388,14 +388,14 @@ bool SIInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
>   MachineInstr *SIInstrInfo::commuteInstruction(MachineInstr *MI,
>                                                 bool NewMI) const {
>   
> -  MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
>     if (MI->getNumOperands() < 3 || !MI->getOperand(1).isReg())
>       return nullptr;
>   
> -  // Cannot commute VOP2 if src0 is SGPR.
> -  if (isVOP2(MI->getOpcode()) && MI->getOperand(1).isReg() &&
> -      RI.isSGPRClass(MRI.getRegClass(MI->getOperand(1).getReg())))
> -   return nullptr;
> +  // Make sure it s legal to commute operands for VOP2.
> +  if (isVOP2(MI->getOpcode()) &&
> +      (!isOperandLegal(MI, 1, &MI->getOperand(2)) ||
> +       !isOperandLegal(MI, 2, &MI->getOperand(1))))
> +    return nullptr;
>   
>     if (!MI->getOperand(2).isReg()) {
>       // XXX: Commute instructions with FPImm operands
> @@ -896,8 +896,36 @@ unsigned SIInstrInfo::split64BitImm(SmallVectorImpl<MachineInstr *> &Worklist,
>     return Dst;
>   }
>   
> +bool SIInstrInfo::isOperandLegal(const MachineInstr *MI, unsigned OpIdx,
> +                                 const MachineOperand *MO) const {
> +  const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
> +  const MCInstrDesc &InstDesc = get(MI->getOpcode());
> +  const MCOperandInfo &OpInfo = InstDesc.OpInfo[OpIdx];
> +  const TargetRegisterClass *DefinedRC =
> +      OpInfo.RegClass != -1 ? RI.getRegClass(OpInfo.RegClass) : nullptr;
> +  if (!MO)
> +    MO = &MI->getOperand(OpIdx);
> +
> +  if (MO->isReg()) {
> +    assert(DefinedRC);
> +    const TargetRegisterClass *RC = MRI.getRegClass(MO->getReg());
> +    return RI.getCommonSubClass(RC, RI.getRegClass(OpInfo.RegClass));
> +  }
> +
> +
> +  // Handle non-register types that are treated like immediates.
> +  assert(MO->isImm() || MO->isFPImm() || MO->isTargetIndex() || MO->isFI());
> +
> +  if (!DefinedRC)
> +    // This opperand expects an immediate
> +    return true;
Typo: opperand. Also move the comment before the if so the body of it 
doesn't look like it's on 2 lines

>   class Constants {
>   int TWO_PI = 0x40c90fdb;
> diff --git a/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp b/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp
> index 78776c1..8cdf878 100644
> --- a/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp
> +++ b/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp
> @@ -14,6 +14,7 @@
>   //===----------------------------------------------------------------------===//
>   
>   #include "AMDGPU.h"
> +#include "SIDefines.h"
>   #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
>   #include "MCTargetDesc/AMDGPUMCCodeEmitter.h"
>   #include "MCTargetDesc/AMDGPUFixupKinds.h"
> @@ -84,6 +85,15 @@ MCCodeEmitter *llvm::createSIMCCodeEmitter(const MCInstrInfo &MCII,
>   
>   bool SIMCCodeEmitter::isSrcOperand(const MCInstrDesc &Desc,
>                                      unsigned OpNo) const {
> +  // FIXME: We need a better way to figure out which operands can be immediate
> +  // values
> +  //
> +  // Some VOP* instructions like ADDC use VReg32 as the register class
> +  // for source 0, becuase they read VCC and can't take an SGPR as an
  Typo: becuase
> +// Returns the input arguments for VOP3 instructions for the given SrcVT.
> +class getIns64 <RegisterClass Src0RC, RegisterClass Src1RC,
> +                RegisterClass Src2RC, int NumSrcArgs,
> +                bit HasModifiers> {
> +
> +  dag ret =
> +    !if (!eq(NumSrcArgs, 1),
> +      !if (!eq(HasModifiers, 1),
> +        // VOP1 with modifiers
> +        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
> +             i32imm:$clamp, i32imm:$omod)
> +      /* else */,
> +        // VOP1 without modifiers
> +        (ins Src0RC:$src0)
> +      /* endif */ ),
> +    !if (!eq(NumSrcArgs, 2),
> +      !if (!eq(HasModifiers, 1),
> +        // VOP 2 with modifiers
> +        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
> +             InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
> +             i32imm:$clamp, i32imm:$omod)
> +      /* else */,
> +        // VOP2 without modifiers
> +        (ins Src0RC:$src0, Src1RC:$src1)
> +      /* endif */ )
> +    /* NumSrcArgs == 3 */,
> +      !if (!eq(HasModifiers, 1),
> +        // VOP3 with modifiers
> +        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
> +             InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
> +             InputModsNoDefault:$src2_modifiers, Src2RC:$src2,
> +             i32imm:$clamp, i32imm:$omod)
> +      /* else */,
> +        // VOP3 without modifiers
> +        (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2)
> +      /* endif */ )));
> +}
> +
> +// Returns the assembly string for the inputs and outputs of a VOP[12C]
> +// instruction.  This does not add the _e32 suffix, so it can be re-sued
Typo: re-sued

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140730/8d3615e2/attachment.html>


More information about the llvm-commits mailing list