[llvm] r252722 - [X86] Replace LEAs with INC/DEC when profitable

Kuperstein, Michael M via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 16 06:57:19 PST 2015


Adding Anton, who wrote the patch.

-----Original Message-----
From: Rafael EspĂ­ndola [mailto:rafael.espindola at gmail.com] 
Sent: Wednesday, November 11, 2015 22:52
To: Kuperstein, Michael M
Cc: llvm-commits
Subject: Re: [llvm] r252722 - [X86] Replace LEAs with INC/DEC when profitable

BTW it can also be profitable for speed is some cases:

https://llvm.org/bugs/show_bug.cgi?id=13320

Cheers,
Rafael


On 11 November 2015 at 06:44, Michael Kuperstein via llvm-commits <llvm-commits at lists.llvm.org> wrote:
> Author: mkuper
> Date: Wed Nov 11 05:44:31 2015
> New Revision: 252722
>
> URL: http://llvm.org/viewvc/llvm-project?rev=252722&view=rev
> Log:
> [X86] Replace LEAs with INC/DEC when profitable
>
> If possible and profitable, replace lea %reg, 1(%reg) and lea %reg, -1(%reg) with inc %reg and dec %reg respectively.
>
> Patch by: anton.nadolsky at intel.com
> Differential Revision: http://reviews.llvm.org/D14059
>
> Added:
>     llvm/trunk/test/CodeGen/X86/fixup-lea.ll
> Modified:
>     llvm/trunk/lib/Target/X86/X86FixupLEAs.cpp
>     llvm/trunk/test/CodeGen/X86/lsr-static-addr.ll
>
> Modified: llvm/trunk/lib/Target/X86/X86FixupLEAs.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Fixup
> LEAs.cpp?rev=252722&r1=252721&r2=252722&view=diff
> ======================================================================
> ========
> --- llvm/trunk/lib/Target/X86/X86FixupLEAs.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86FixupLEAs.cpp Wed Nov 11 05:44:31 
> +++ 2015
> @@ -9,6 +9,7 @@
>  //
>  // This file defines the pass that finds instructions that can be  // 
> re-written as LEA instructions in order to reduce pipeline delays.
> +// When optimizing for size it replaces suitable LEAs with INC or DEC.
>  //
>  
> //===-----------------------------------------------------------------
> -----===//
>
> @@ -61,6 +62,11 @@ class FixupLEAPass : public MachineFunct
>    void processInstructionForSLM(MachineBasicBlock::iterator &I,
>                                  MachineFunction::iterator MFI);
>
> +  /// \brief Look for LEAs that add 1 to reg or subtract 1 from reg  
> + /// and convert them to INC or DEC respectively.
> +  bool fixupIncDec(MachineBasicBlock::iterator &I,
> +                   MachineFunction::iterator MFI) const;
> +
>    /// \brief Determine if an instruction references a machine register
>    /// and, if so, whether it reads or writes the register.
>    RegUsageState usesRegister(MachineOperand &p, 
> MachineBasicBlock::iterator I); @@ -89,6 +95,8 @@ public:
>  private:
>    MachineFunction *MF;
>    const X86InstrInfo *TII; // Machine instruction info.
> +  bool OptIncDec;
> +  bool OptLEA;
>  };
>  char FixupLEAPass::ID = 0;
>  }
> @@ -150,7 +158,10 @@ FunctionPass *llvm::createX86FixupLEAs()  bool 
> FixupLEAPass::runOnMachineFunction(MachineFunction &Func) {
>    MF = &Func;
>    const X86Subtarget &ST = Func.getSubtarget<X86Subtarget>();
> -  if (!ST.LEAusesAG() && !ST.slowLEA())
> +  OptIncDec = !ST.slowIncDec() || 
> + Func.getFunction()->optForMinSize();
> +  OptLEA = ST.LEAusesAG() || ST.slowLEA();
> +
> +  if (!OptLEA && !OptIncDec)
>      return false;
>
>    TII = ST.getInstrInfo();
> @@ -222,6 +233,60 @@ FixupLEAPass::searchBackwards(MachineOpe
>    return nullptr;
>  }
>
> +static inline bool isLEA(const int opcode) {
> +  return opcode == X86::LEA16r || opcode == X86::LEA32r ||
> +         opcode == X86::LEA64r || opcode == X86::LEA64_32r; }
> +
> +/// isLEASimpleIncOrDec - Does this LEA have one these forms:
> +/// lea  %reg, 1(%reg)
> +/// lea  %reg, -1(%reg)
> +static inline bool isLEASimpleIncOrDec(MachineInstr *LEA) {
> +  unsigned SrcReg = LEA->getOperand(1 + X86::AddrBaseReg).getReg();
> +  unsigned DstReg = LEA->getOperand(0).getReg();
> +  unsigned AddrDispOp = 1 + X86::AddrDisp;
> +  return SrcReg == DstReg &&
> +         LEA->getOperand(1 + X86::AddrIndexReg).getReg() == 0 &&
> +         LEA->getOperand(1 + X86::AddrSegmentReg).getReg() == 0 &&
> +         LEA->getOperand(AddrDispOp).isImm() &&
> +         (LEA->getOperand(AddrDispOp).getImm() == 1 ||
> +          LEA->getOperand(AddrDispOp).getImm() == -1); }
> +
> +bool FixupLEAPass::fixupIncDec(MachineBasicBlock::iterator &I,
> +                               MachineFunction::iterator MFI) const {
> +  MachineInstr *MI = I;
> +  int Opcode = MI->getOpcode();
> +  if (!isLEA(Opcode))
> +    return false;
> +
> +  if (isLEASimpleIncOrDec(MI) && TII->isSafeToClobberEFLAGS(*MFI, I)) {
> +    int NewOpcode;
> +    bool isINC = MI->getOperand(4).getImm() == 1;
> +    switch (Opcode) {
> +    case X86::LEA16r:
> +      NewOpcode = isINC ? X86::INC16r : X86::DEC16r;
> +      break;
> +    case X86::LEA32r:
> +    case X86::LEA64_32r:
> +      NewOpcode = isINC ? X86::INC32r : X86::DEC32r;
> +      break;
> +    case X86::LEA64r:
> +      NewOpcode = isINC ? X86::INC64r : X86::DEC64r;
> +      break;
> +    }
> +
> +    MachineInstr *NewMI =
> +        BuildMI(*MFI, I, MI->getDebugLoc(), TII->get(NewOpcode))
> +            .addOperand(MI->getOperand(0))
> +            .addOperand(MI->getOperand(1));
> +    MFI->erase(I);
> +    I = static_cast<MachineBasicBlock::iterator>(NewMI);
> +    return true;
> +  }
> +  return false;
> +}
> +
>  void FixupLEAPass::processInstruction(MachineBasicBlock::iterator &I,
>                                        MachineFunction::iterator MFI) {
>    // Process a load, store, or LEA instruction.
> @@ -265,8 +330,7 @@ void FixupLEAPass::processInstructionFor
>                                              MachineFunction::iterator MFI) {
>    MachineInstr *MI = I;
>    const int opcode = MI->getOpcode();
> -  if (opcode != X86::LEA16r && opcode != X86::LEA32r && opcode != X86::LEA64r &&
> -      opcode != X86::LEA64_32r)
> +  if (!isLEA(opcode))
>      return;
>    if (MI->getOperand(5).getReg() != 0 || !MI->getOperand(4).isImm() ||
>        !TII->isSafeToClobberEFLAGS(*MFI, I)) @@ -280,7 +344,8 @@ void 
> FixupLEAPass::processInstructionFor
>      return;
>    int addrr_opcode, addri_opcode;
>    switch (opcode) {
> -  default: llvm_unreachable("Unexpected LEA instruction");
> +  default:
> +    llvm_unreachable("Unexpected LEA instruction");
>    case X86::LEA16r:
>      addrr_opcode = X86::ADD16rr;
>      addri_opcode = X86::ADD16ri;
> @@ -330,10 +395,16 @@ bool FixupLEAPass::processBasicBlock(Mac
>                                       MachineFunction::iterator MFI) {
>
>    for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end(); ++I) {
> -    if (MF.getSubtarget<X86Subtarget>().isSLM())
> -      processInstructionForSLM(I, MFI);
> -    else
> -      processInstruction(I, MFI);
> +    if (OptIncDec)
> +      if (fixupIncDec(I, MFI))
> +        continue;
> +
> +    if (OptLEA) {
> +      if (MF.getSubtarget<X86Subtarget>().isSLM())
> +        processInstructionForSLM(I, MFI);
> +      else
> +        processInstruction(I, MFI);
> +    }
>    }
>    return false;
>  }
>
> Added: llvm/trunk/test/CodeGen/X86/fixup-lea.ll
> URL: 
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fixup-
> lea.ll?rev=252722&view=auto 
> ======================================================================
> ========
> --- llvm/trunk/test/CodeGen/X86/fixup-lea.ll (added)
> +++ llvm/trunk/test/CodeGen/X86/fixup-lea.ll Wed Nov 11 05:44:31 2015
> @@ -0,0 +1,34 @@
> +;RUN: llc < %s -march=x86 | FileCheck %s
> +
> +define void @foo(i32 inreg %dns) minsize {
> +entry:
> +; CHECK-LABEL: foo
> +; CHECK: dec
> +  br label %for.body
> +
> +for.body:
> +  %i.05 = phi i16 [ %dec, %for.body ], [ 0, %entry ]
> +  %dec = add i16 %i.05, -1
> +  %conv = zext i16 %dec to i32
> +  %cmp = icmp slt i32 %conv, %dns
> +  br i1 %cmp, label %for.body, label %for.end
> +
> +for.end:
> +  ret void
> +}
> +
> +define void @bar(i32 inreg %dns) minsize {
> +entry:
> +; CHECK-LABEL: bar
> +; CHECK: inc
> +  br label %for.body
> +
> +for.body:
> +  %i.05 = phi i16 [ %inc, %for.body ], [ 0, %entry ]
> +  %inc = add i16 %i.05, 1
> +  %conv = zext i16 %inc to i32
> +  %cmp = icmp slt i32 %conv, %dns
> +  br i1 %cmp, label %for.body, label %for.end
> +for.end:
> +  ret void
> +}
>
> Modified: llvm/trunk/test/CodeGen/X86/lsr-static-addr.ll
> URL: 
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/lsr-st
> atic-addr.ll?rev=252722&r1=252721&r2=252722&view=diff
> ======================================================================
> ========
> --- llvm/trunk/test/CodeGen/X86/lsr-static-addr.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/lsr-static-addr.ll Wed Nov 11 05:44:31 
> +++ 2015
> @@ -18,7 +18,7 @@
>  ; ATOM-NEXT: movsd A(,%rax,8)
>  ; ATOM-NEXT: mulsd
>  ; ATOM-NEXT: movsd
> -; ATOM-NEXT: leaq 1(%rax), %rax
> +; ATOM-NEXT: incq %rax
>
>  @A = external global [0 x double]
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
---------------------------------------------------------------------
Intel Israel (74) Limited

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


More information about the llvm-commits mailing list